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

Merge pull request #590 from porter-dev/0.2.0-env-var-secret-update

[0.2.0] Hotfix -- env var secret update edge cases
abelanger5 5 лет назад
Родитель
Сommit
e5982d5114

+ 2 - 0
dashboard/src/components/values-form/KeyValueArray.tsx

@@ -117,6 +117,7 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
                   this.props.setValues(obj);
                 }}
                 disabled={this.props.disabled || value.includes("PORTERSECRET")}
+                spellCheck={false}
               />
               <Spacer />
               <Input
@@ -132,6 +133,7 @@ export default class KeyValueArray extends Component<PropsType, StateType> {
                 }}
                 disabled={this.props.disabled || value.includes("PORTERSECRET")}
                 type={value.includes("PORTERSECRET") ? "password" : "text"}
+                spellCheck={false}
               />
               {this.renderDeleteButton(i)}
               {this.renderHiddenOption(value.includes("PORTERSECRET"), i)}

+ 21 - 4
dashboard/src/main/home/cluster-dashboard/env-groups/CreateEnvGroup.tsx

@@ -56,11 +56,28 @@ export default class CreateEnvGroup extends Component<PropsType, StateType> {
     let apiEnvVariables: Record<string, string> = {};
     let secretEnvVariables: Record<string, string> = {};
 
-    this.state.envVariables.forEach((envVar: KeyValueType) => {
-      if (envVar.hidden) {
-        secretEnvVariables[envVar.key] = envVar.value;
+    let envVariables = this.state.envVariables
+
+    envVariables.filter((envVar: KeyValueType, index : number, self : KeyValueType[]) => {
+      // remove any collisions that are marked as deleted and are duplicates
+      let numCollisions = self.reduce((n, _envVar : KeyValueType) => {
+        return n + (_envVar.key === envVar.key ? 1 : 0);
+      }, 0)
+
+      if (numCollisions == 1) {
+        return true
       } else {
-        apiEnvVariables[envVar.key] = envVar.value;
+        return index === self.findIndex((_envVar : KeyValueType) => (
+          _envVar.key === envVar.key && !_envVar.deleted
+        ))
+      }
+    }).forEach((envVar: KeyValueType) => {
+      if (!envVar.deleted) {
+        if (envVar.hidden) {
+          secretEnvVariables[envVar.key] = envVar.value
+        } else {
+          apiEnvVariables[envVar.key] = envVar.value
+        }
       }
     });
 

+ 34 - 32
dashboard/src/main/home/cluster-dashboard/env-groups/EnvGroupArray.tsx

@@ -91,38 +91,40 @@ export default class EnvGroupArray extends Component<PropsType, StateType> {
     return (
       <>
         {this.props.values.map((entry: KeyValueType, i: number) => {
-          if (!entry.deleted) {
-            return (
-              <InputWrapper key={i}>
-                <Input
-                  placeholder="ex: key"
-                  width="270px"
-                  value={entry.key}
-                  onChange={(e: any) => {
-                    let _values = this.props.values;
-                    _values[i].key = e.target.value;
-                    this.props.setValues(_values);
-                  }}
-                  disabled={this.props.disabled || entry.locked}
-                />
-                <Spacer />
-                <Input
-                  placeholder="ex: value"
-                  width="270px"
-                  value={entry.value}
-                  onChange={(e: any) => {
-                    let _values = this.props.values;
-                    _values[i].value = e.target.value;
-                    this.props.setValues(_values);
-                  }}
-                  disabled={this.props.disabled || entry.locked}
-                  type={entry.hidden ? "password" : "text"}
-                />
-                {this.renderHiddenOption(entry.hidden, entry.locked, i)}
-                {this.renderDeleteButton(i)}
-              </InputWrapper>
-            );
-          }
+            if (!entry.deleted) {
+                return (
+                    <InputWrapper key={i}>
+                      <Input
+                        placeholder="ex: key"
+                        width="270px"
+                        value={entry.key}
+                        onChange={(e: any) => {
+                          let _values = this.props.values
+                          _values[i].key = e.target.value;
+                          this.props.setValues(_values);
+                        }}
+                        disabled={this.props.disabled || entry.locked}
+                        spellCheck={false}
+                      />
+                      <Spacer />
+                      <Input
+                        placeholder="ex: value"
+                        width="270px"
+                        value={entry.value}
+                        onChange={(e: any) => {
+                          let _values = this.props.values
+                          _values[i].value = e.target.value;
+                          this.props.setValues(_values);
+                        }}
+                        disabled={this.props.disabled || entry.locked}
+                        type={entry.hidden ? "password" : "text"}
+                        spellCheck={false}
+                      />
+                      {this.renderHiddenOption(entry.hidden, entry.locked, i)}
+                      {this.renderDeleteButton(i)}
+                    </InputWrapper>
+                  );
+            }
         })}
       </>
     );

+ 29 - 1
dashboard/src/main/home/cluster-dashboard/env-groups/ExpandedEnvGroup.tsx

@@ -74,7 +74,35 @@ export default class ExpandedEnvGroup extends Component<PropsType, StateType> {
     let apiEnvVariables: Record<string, string> = {};
     let secretEnvVariables: Record<string, string> = {};
 
-    this.state.envVariables.forEach((envVar: KeyValueType) => {
+    let envVariables = this.state.envVariables
+
+    envVariables.filter((envVar: KeyValueType, index : number, self : KeyValueType[]) => {
+      // remove any collisions that are marked as deleted and are duplicates, unless they are 
+      // all delete collisions
+      let numDeleteCollisions = self.reduce((n, _envVar : KeyValueType) => {
+        return n + (_envVar.key === envVar.key && envVar.deleted ? 1 : 0);
+      }, 0)
+
+      let numCollisions = self.reduce((n, _envVar : KeyValueType) => {
+        return n + (_envVar.key === envVar.key ? 1 : 0);
+      }, 0)
+
+      if (numCollisions == numDeleteCollisions) {
+        // if all collisions are delete collisions, just remove duplicates
+        return index === self.findIndex((_envVar : KeyValueType) => (
+          _envVar.key === envVar.key
+        ))
+      } else if (numCollisions == 1) {
+        // if there's just one collision (self), keep the object
+        return true
+      } else {
+        // if there are more collisions than delete collisions, remove all duplicates that
+        // are deletions
+        return index === self.findIndex((_envVar : KeyValueType) => (
+          _envVar.key === envVar.key && !_envVar.deleted
+        ))
+      }
+    }).forEach((envVar: KeyValueType) => {
       if (envVar.hidden) {
         if (envVar.deleted) {
           secretEnvVariables[envVar.key] = null

+ 4 - 4
server/api/k8s_handler.go

@@ -372,11 +372,11 @@ func (app *App) HandleUpdateConfigMap(w http.ResponseWriter, r *http.Request) {
 
 	// add all secret env variables to configmap with value PORTERSECRET_${configmap_name}
 	for key, val := range configMap.SecretEnvVariables {
-		configMap.EnvVariables[key] = fmt.Sprintf("PORTERSECRET_%s", configMap.Name)
-
-		// if val is empty, set to empty
-		if val == "" {
+		// if val is empty and key does not exist in configmap already, set to empty
+		if _, found := configMap.EnvVariables[key]; val == "" && !found {
 			configMap.EnvVariables[key] = ""
+		} else if val != "" {
+			configMap.EnvVariables[key] = fmt.Sprintf("PORTERSECRET_%s", configMap.Name)
 		}
 	}