Pārlūkot izejas kodu

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 gadi atpakaļ
vecāks
revīzija
430046bae6

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

@@ -155,7 +155,9 @@ class Endpoint extends React.Component<Props, State> {
 
   componentDidMount() {
     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) {
@@ -281,9 +283,14 @@ class Endpoint extends React.Component<Props, State> {
     }
 
     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 ...')
-      // $FlowIssue
-      endpointStore.validate(this.state.endpoint)
+      endpointStore.validate(endpoint)
     })
   }
 
@@ -386,7 +393,9 @@ class Endpoint extends React.Component<Props, State> {
           passwordFields,
           getFieldValue: field => this.getFieldValue(field),
           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) },
           handleValidateClick: () => { this.handleValidateClick() },
           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 Api from '../utils/ApiCaller'
+import notificationStore from '../stores/NotificationStore'
 import { SchemaParser } from './Schemas'
 import ObjectUtils from '../utils/ObjectUtils'
 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[]> {
     return Promise.all(endpoints.map(endpoint => {
       let index = endpoint.connection_info.secret_ref ? endpoint.connection_info.secret_ref.lastIndexOf('/') : ''
@@ -151,18 +173,18 @@ class EdnpointSource {
         uuidIndex = connectionInfo.secret_ref.lastIndexOf('/')
         uuid = connectionInfo.secret_ref.substr(uuidIndex + 1)
         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 => {
         newEndpoint.connection_info = {
           ...newEndpoint.connection_info,
           ...conInfoResponse.data,
         }
         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)
         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 => {
         newEndpoint.connection_info = {
           ...newEndpoint.connection_info,
           ...conInfoResponse.data,
         }
         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.connectionInfo = { ...updatedEndpoint.connection_info }
       this.updating = false
+    }).catch(e => {
+      this.updating = false
+      throw e
     })
   }
 
@@ -171,8 +174,9 @@ class EndpointStore {
 
       this.connectionInfo = addedEndpoint.connection_info
       this.adding = false
-    }).catch(() => {
+    }).catch(e => {
       this.adding = false
+      throw e
     })
   }