Răsfoiți Sursa

Add support for non-active secret when updating

When updating or adding a new endpoint, its Barbican secret may not be
active immediately.

A polling is made to make sure the secret is active. If after 10 retries
(2 second waiting period after each request) the secret is still
inactive, the secret payload call gets rejected.
Sergiu Miclea 7 ani în urmă
părinte
comite
430046bae6

+ 13 - 4
src/components/organisms/Endpoint/Endpoint.jsx

@@ -155,7 +155,9 @@ class Endpoint extends React.Component<Props, State> {
 
 
   componentDidMount() {
   componentDidMount() {
     providerStore.getConnectionInfoSchema(this.getEndpointType())
     providerStore.getConnectionInfoSchema(this.getEndpointType())
-    KeyboardManager.onEnter('endpoint', () => { if (this.isValidateButtonEnabled) this.handleValidateClick() }, 2)
+    KeyboardManager.onEnter('endpoint', () => {
+      if (this.isValidateButtonEnabled) this.handleValidateClick()
+    }, 2)
   }
   }
 
 
   componentWillReceiveProps(props: Props) {
   componentWillReceiveProps(props: Props) {
@@ -281,9 +283,14 @@ class Endpoint extends React.Component<Props, State> {
     }
     }
 
 
     endpointStore.update(this.state.endpoint).then(() => {
     endpointStore.update(this.state.endpoint).then(() => {
+      let endpoint = endpointStore.endpoints.find(e => this.state.endpoint && e.id === this.state.endpoint.id)
+      if (!endpoint) {
+        throw new Error('endpoint not found')
+      }
+
+      this.setState({ endpoint: ObjectUtils.flatten(endpoint) })
       notificationStore.alert('Validating endpoint ...')
       notificationStore.alert('Validating endpoint ...')
-      // $FlowIssue
-      endpointStore.validate(this.state.endpoint)
+      endpointStore.validate(endpoint)
     })
     })
   }
   }
 
 
@@ -386,7 +393,9 @@ class Endpoint extends React.Component<Props, State> {
           passwordFields,
           passwordFields,
           getFieldValue: field => this.getFieldValue(field),
           getFieldValue: field => this.getFieldValue(field),
           highlightRequired: () => this.highlightRequired(),
           highlightRequired: () => this.highlightRequired(),
-          handleFieldChange: (field, value) => { if (field) this.handleFieldsChange([{ field, value }]) },
+          handleFieldChange: (field, value) => {
+            if (field) this.handleFieldsChange([{ field, value }])
+          },
           handleFieldsChange: fields => { this.handleFieldsChange(fields) },
           handleFieldsChange: fields => { this.handleFieldsChange(fields) },
           handleValidateClick: () => { this.handleValidateClick() },
           handleValidateClick: () => { this.handleValidateClick() },
           handleCancelClick: () => { this.handleCancelClick() },
           handleCancelClick: () => { this.handleCancelClick() },

+ 34 - 11
src/sources/EndpointSource.js

@@ -17,6 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 import moment from 'moment'
 import moment from 'moment'
 
 
 import Api from '../utils/ApiCaller'
 import Api from '../utils/ApiCaller'
+import notificationStore from '../stores/NotificationStore'
 import { SchemaParser } from './Schemas'
 import { SchemaParser } from './Schemas'
 import ObjectUtils from '../utils/ObjectUtils'
 import ObjectUtils from '../utils/ObjectUtils'
 import type { Endpoint, Validation, Storage } from '../types/Endpoint'
 import type { Endpoint, Validation, Storage } from '../types/Endpoint'
@@ -87,6 +88,27 @@ class EdnpointSource {
     })
     })
   }
   }
 
 
+  static getSecretPayload(uuid: string, count: number = 0) {
+    let delay = () => new Promise(r => { setTimeout(() => { r() }, 2000) })
+
+    if (count >= 10) {
+      return Promise.reject({ secretCustomError: `The secret '${uuid}' is not active after ${count} retries.` })
+    }
+
+    return Api.send({
+      url: `${servicesUrl.barbican}/v1/secrets/${uuid}`,
+      headers: { Accept: 'application/json' },
+    }).then(response => {
+      if (response.data.status === 'ACTIVE') {
+        return Api.send({
+          url: `${servicesUrl.barbican}/v1/secrets/${uuid}/payload`,
+          headers: { Accept: 'text/plain' },
+        })
+      }
+      return delay().then(() => this.getSecretPayload(uuid, count + 1))
+    })
+  }
+
   static getConnectionsInfo(endpoints: Endpoint[]): Promise<Endpoint[]> {
   static getConnectionsInfo(endpoints: Endpoint[]): Promise<Endpoint[]> {
     return Promise.all(endpoints.map(endpoint => {
     return Promise.all(endpoints.map(endpoint => {
       let index = endpoint.connection_info.secret_ref ? endpoint.connection_info.secret_ref.lastIndexOf('/') : ''
       let index = endpoint.connection_info.secret_ref ? endpoint.connection_info.secret_ref.lastIndexOf('/') : ''
@@ -151,18 +173,18 @@ class EdnpointSource {
         uuidIndex = connectionInfo.secret_ref.lastIndexOf('/')
         uuidIndex = connectionInfo.secret_ref.lastIndexOf('/')
         uuid = connectionInfo.secret_ref.substr(uuidIndex + 1)
         uuid = connectionInfo.secret_ref.substr(uuidIndex + 1)
         newEndpoint = putResponse.data.endpoint
         newEndpoint = putResponse.data.endpoint
-        return Api.send({
-          url: `${servicesUrl.barbican}/v1/secrets/${uuid}/payload`,
-          method: 'GET',
-          responseType: 'text',
-          headers: { Accept: 'text/plain' },
-        })
+        return this.getSecretPayload(uuid)
       }).then(conInfoResponse => {
       }).then(conInfoResponse => {
         newEndpoint.connection_info = {
         newEndpoint.connection_info = {
           ...newEndpoint.connection_info,
           ...newEndpoint.connection_info,
           ...conInfoResponse.data,
           ...conInfoResponse.data,
         }
         }
         return newEndpoint
         return newEndpoint
+      }).catch(e => {
+        if (e.secretCustomError) {
+          notificationStore.alert(e.secretCustomError, 'error')
+        }
+        throw e
       })
       })
     }
     }
 
 
@@ -205,17 +227,18 @@ class EdnpointSource {
         let uuid = connectionInfo.secret_ref.substr(uuidIndex + 1)
         let uuid = connectionInfo.secret_ref.substr(uuidIndex + 1)
         newEndpoint = postResponse.data.endpoint
         newEndpoint = postResponse.data.endpoint
 
 
-        return Api.send({
-          url: `${servicesUrl.barbican}/v1/secrets/${uuid}/payload`,
-          responseType: 'text',
-          headers: { Accept: 'text/plain' },
-        })
+        return this.getSecretPayload(uuid)
       }).then(conInfoResponse => {
       }).then(conInfoResponse => {
         newEndpoint.connection_info = {
         newEndpoint.connection_info = {
           ...newEndpoint.connection_info,
           ...newEndpoint.connection_info,
           ...conInfoResponse.data,
           ...conInfoResponse.data,
         }
         }
         return newEndpoint
         return newEndpoint
+      }).catch(e => {
+        if (e.secretCustomError) {
+          notificationStore.alert(e.secretCustomError, 'error')
+        }
+        throw e
       })
       })
     }
     }
 
 

+ 5 - 1
src/stores/EndpointStore.js

@@ -153,6 +153,9 @@ class EndpointStore {
       this.endpoints = updateEndpoint(updatedEndpoint, this.endpoints)
       this.endpoints = updateEndpoint(updatedEndpoint, this.endpoints)
       this.connectionInfo = { ...updatedEndpoint.connection_info }
       this.connectionInfo = { ...updatedEndpoint.connection_info }
       this.updating = false
       this.updating = false
+    }).catch(e => {
+      this.updating = false
+      throw e
     })
     })
   }
   }
 
 
@@ -171,8 +174,9 @@ class EndpointStore {
 
 
       this.connectionInfo = addedEndpoint.connection_info
       this.connectionInfo = addedEndpoint.connection_info
       this.adding = false
       this.adding = false
-    }).catch(() => {
+    }).catch(e => {
       this.adding = false
       this.adding = false
+      throw e
     })
     })
   }
   }