Просмотр исходного кода

Merge pull request #31 from smiclea/CORWEB-25

Refactored required fields and credentials handling so it doesn't need specific Azure code CORWEB-25
Alessandro Pilotti 8 лет назад
Родитель
Сommit
bd5b7a095a

+ 53 - 34
src/components/AddCloudConnection/AddCloudConnection.js

@@ -105,18 +105,6 @@ class AddCloudConnection extends Reflux.Component {
   handleSave() {
     let valid = true
     let requiredFields = this.state.requiredFields
-    // If Azure, validate fields manually
-    if (this.state.currentCloud.name == "azure") {
-      if (this.state.currentCloudData.login_type == "user_credentials") {
-        requiredFields = ["subscription_id", "username", "password"]
-      } else if (this.state.currentCloudData.login_type == "service_principal_credentials") {
-        requiredFields = ["subscription_id", "tenant_id", "client_id", "client_secret"]
-      } else {
-        valid = false
-        NotificationActions.notify("Please choose the login type", "error")
-      }
-      this.setState({ requiredFields: requiredFields })
-    }
 
     for (let i in this.state.currentCloudData) {
       if (requiredFields.indexOf(i) > -1 && !this.state.currentCloudData[i]) {
@@ -144,6 +132,11 @@ class AddCloudConnection extends Reflux.Component {
         }
 
         let field = this.state.currentCloud.endpoint.fields.find(function findByName(f) { return f.name == this }, key);
+
+        if (!field || !field.dataType) {
+          continue;
+        }
+
         // Convert datatype
         switch (field.dataType) {
           case 'boolean':
@@ -169,28 +162,20 @@ class AddCloudConnection extends Reflux.Component {
         return;
       }
 
-      // If Azure, explicitly setting the fields right
-      if (this.state.currentCloud.name == "azure") {
-        credentials = {}
-        credentials["subscription_id"] = this.state.currentCloudData["subscription_id"]
-        if (this.state.currentCloudData["login_type"] == "user_credentials") {
-          credentials["user_credentials"] = {
-            username: this.state.currentCloudData["username"],
-            password: this.state.currentCloudData["password"]
-          }
-        } else {
-          credentials["service_principal_credentials"] = {
-            tenant_id: this.state.currentCloudData["tenant_id"],
-            client_id: this.state.currentCloudData["client_id"],
-            client_secret: this.state.currentCloudData["client_secret"]
-          }
-        }
-      }
+      // If there's a switch radio, create a hierarchical structure with the selected radio as the root.
+      this.state.currentCloud.endpoint.fields.forEach(field => {
+        if (field.type === 'switch-radio') {
+          credentials[credentials[field.name]] = {}
 
-      // Remove the login_type since it is not needed
-      if (this.state.currentCloud.name == "azure") {
-        delete credentials.login_type
-      }
+          field.options.forEach(fieldOptions => {
+            if (fieldOptions.value === credentials[field.name]) {
+              fieldOptions.fields.forEach(fieldOptionField => {
+                credentials[credentials[field.name]][fieldOptionField.name] = credentials[fieldOptionField.name]
+              })
+            }
+          })
+        }
+      })
 
       // If endpoint is new
       if (this.state.type == "new") {
@@ -311,8 +296,9 @@ class AddCloudConnection extends Reflux.Component {
           break
         case 'switch-radio':
           field.options.forEach(option => {
-            if (option.default && typeof currentCloudData[field.name] == "undefined") {
+            if (option.default && !currentCloudData[field.name]) {
               currentCloudData[field.name] = option.value
+              this.setRadioRequiredFields(field, option.value)
               this.setState({ currentCloudData: currentCloudData })
             }
           }, this)
@@ -346,6 +332,34 @@ class AddCloudConnection extends Reflux.Component {
     }
   }
 
+  /**
+   * Dinamically change the required fields affected by the current radio selection
+   * @param field
+   * @param currentValue
+   */
+  setRadioRequiredFields(field, currentValue) {
+    let requiredFields = this.state.requiredFields || [];
+
+    // Remove fields set by previous radio change
+    field.options.forEach(option => {
+      option.fields.forEach(f => {
+        requiredFields = requiredFields.filter(rf => rf !== f.name)
+      })
+    })
+
+    field.options.forEach(option => {
+      if (option.value === currentValue) {
+        option.fields.forEach(optionField => {
+          if (optionField.required) {
+            requiredFields.push(optionField.name);
+          }
+        })
+      }
+    })
+
+    this.setState({ requiredFields: requiredFields });
+  }
+
   /**
    * Handles cancel edit/add endpoint
    */
@@ -365,6 +379,11 @@ class AddCloudConnection extends Reflux.Component {
     } else {
       currentCloudData[field.name] = e.target.value
     }
+
+    if (field.type === 'switch-radio') {
+      this.setRadioRequiredFields(field, e.target.value)
+    }
+
     this.setState({ currentCloudData: currentCloudData })
   }
 

+ 45 - 39
src/components/CloudConnectionDetail/CloudConnectionDetail.js

@@ -50,6 +50,17 @@ class CloudConnectionDetail extends Component {
 
   processProps(props) {
     let fields = []
+
+    let addField = (name, value) => {
+      name = Helper.convertCloudFieldLabel(name)
+      if (!fields.find(f => f.fieldName === name)) {
+        fields.push({
+          fieldName: name,
+          fieldValue: value
+        })
+      }
+    }
+
     if (props.connection.credentials) {
       for (let fieldName in props.connection.credentials) {
         let value = props.connection.credentials[fieldName]
@@ -59,56 +70,51 @@ class CloudConnectionDetail extends Component {
         if (value === true) value = "Yes"
         if (value === false) value = "No"
 
-        fields.push({
-          fieldName: Helper.convertCloudFieldLabel(fieldName),
-          fieldValue: value
-        })
+        if (typeof value === 'object') {
+          for (let extraField in value) {
+            addField(extraField, value[extraField])
+          }
+        } else {
+          addField(fieldName, value)
+        }
       }
     }
+
+    // Sort username and password to the front
+    let sortExceptions = { Username: 1, Password: 2 };
+    fields.sort((a, b) => {
+      if (sortExceptions[a.fieldName] && sortExceptions[b.fieldName]) {
+        return sortExceptions[a.fieldName] - sortExceptions[b.fieldName];
+      } else if (sortExceptions[a.fieldName]) {
+        return -1;
+      } else if (sortExceptions[b.fieldName]) {
+        return 1;
+      } else {
+        return 0;
+      }
+    })
+
     return fields
   }
 
   renderAuthFields() {
     if (this.state.fields.length) {
       return this.state.fields.map((field, index) => {
-        if (typeof field.fieldValue === "object") {
-          let extraFields = []
-          for (let i in field.fieldValue) {
-            let fieldValue = field.fieldValue[i] ? field.fieldValue[i] : "-"
-            if (i == "password") {
-              continue
-            }
-            extraFields.push((
-              <div className={s.formGroup} key={"formGroup_" + i}>
-                <div className={s.title}>
-                  {i}
-                </div>
-                <div className={s.value}>
-                  {fieldValue}
-                </div>
+        if (field.fieldName !== 'login_type') {
+          return (
+            <div className={s.formGroup} key={"formGroup_" + index}>
+              <div className={s.title}>
+                {field.fieldName}
               </div>
-            ))
-          }
-          return extraFields
-        } else {
-          let fieldValue = field.fieldValue ? field.fieldValue : "-"
-          if (field.fieldName != "password") {
-            return (
-              <div className={s.formGroup} key={"formGroup_" + index}>
-                <div className={s.title}>
-                  {field.fieldName}
-                </div>
-                <div className={s.value}>
-                  {fieldValue}
-                </div>
+              <div className={s.value}>
+                {field.fieldValue || '-'}
               </div>
-            )
-          } else {
-            return null
-          }
+            </div>
+          )
+        } else {
+          return null
         }
-      }
-      )
+      })
     } else {
       return <LoadingIcon />
     }

+ 0 - 1
src/components/ReplicaList/ReplicaList.js

@@ -111,7 +111,6 @@ class ReplicaList extends Reflux.Component {
     if (count == 0) {
       tasksRemaining = "-"
     }
-
     return (
       <div className={"item " + (item.selected ? "selected" : "")} key={"replica_" + item.id}>
         <span className="cell cell-icon" onClick={(e) => this.replicaDetail(e, item)}>

+ 3 - 0
src/constants/CloudLabels.js

@@ -38,6 +38,9 @@ export const defaultLabels = {
   migr_image: "Migration Image Name or Id",
   migr_image_map: "Migration Image Map",
   migr_network_name: "Migration Network Name",
+  migr_image_name: "Migration Image Name",
+  migr_image_name_map: "Migration Image Name Map",
+  migr_image_id: "Migration Image ID",
   migr_worker_use_config_drive: "Migration Worker use ConfigDrive",
   migr_worker_use_fip: "Migration Worker use FIP",
   delete_disks_on_vm_termination: "Delete Disks on VM termination",

+ 2 - 1
src/stores/ConnectionsStore/ConnectionsStore.js

@@ -297,7 +297,8 @@ class ConnectionsStore extends Reflux.Store
           {
             label: "User Credentials",
             value: "user_credentials",
-            fields: this.processCloud(userCredentialFields)
+            fields: this.processCloud(userCredentialFields),
+            default: true
           },
           {
             label: "Service Principal Credentials",