Skip to content

Commit a60e8c6

Browse files
Merge pull request #63 from oracle/prepare-model-secret-handling
fixing model updates related to secret handling after prepare model action
2 parents 8578ee8 + 9aa1b37 commit a60e8c6

File tree

5 files changed

+52
-13
lines changed

5 files changed

+52
-13
lines changed

electron/app/locales/en/webui.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,8 @@
671671
"ingress-design-add-route-label": "Add Route",
672672
"ingress-design-edit-route-label": "Edit Route",
673673
"ingress-design-delete-route-label": "Delete Route",
674+
"ingress-design-delete-route-warning-title": "Deleting Ingress Route",
675+
"ingress-design-delete-route-warning-message": "Ingress route is only deleted from the table. If it already exists in the Kubernetes cluster, you must manually delete it from the cluster",
674676

675677
"ingress-installer-aborted-error-title": "Ingress Controller Installation Aborted",
676678
"ingress-installer-not-install-message": "The Install Ingress Controller option is off so there is nothing to do.",

webui/src/js/models/k8s-domain-definition.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ define(['knockout', 'utils/observable-properties', 'utils/common-utilities', 'ut
103103

104104
// update the secrets list when any model content changes.
105105
wdtModel.modelContentChanged.subscribe(() => {
106+
wktLogger.debug('modelContentChanged event calling updateSecrets()');
106107
this.updateSecrets();
107108
});
108109

@@ -132,15 +133,20 @@ define(['knockout', 'utils/observable-properties', 'utils/common-utilities', 'ut
132133
};
133134

134135
this.setCredentialPathsForSecretsTable = (json) => {
136+
wktLogger.debug('entering setCredentialPathsForSecretsTable() with secrets table length = %s', this.secrets.value.length);
135137
if (this.secrets.value.length > 0) {
136138
if (!json.credentialPaths) {
139+
wktLogger.debug('creating credentialPaths array');
137140
json.credentialPaths = [];
138141
}
139142
for (const secret of this.secrets.value) {
143+
wktLogger.debug('working on secret path %s', `${name}.secrets.${secret.uid}`);
140144
if (secret.username) {
145+
wktLogger.debug('setting secret %s', `${name}.secrets.${secret.uid}.username`);
141146
json.credentialPaths.push(`${name}.secrets.${secret.uid}.username`);
142147
}
143148
if (secret.password) {
149+
wktLogger.debug('setting secret %s', `${name}.secrets.${secret.uid}.password`);
144150
json.credentialPaths.push(`${name}.secrets.${secret.uid}.password`);
145151
}
146152
}
@@ -207,10 +213,18 @@ define(['knockout', 'utils/observable-properties', 'utils/common-utilities', 'ut
207213

208214
this.handlePrepareModelSecrets = (secrets) => {
209215
if (secrets && secrets.secrets && secrets.secrets.length) {
216+
wktLogger.debug('handlePrepareModelSecrets() working on %d secrets', secrets.secrets.length);
210217
for (const secret of secrets.secrets) {
211-
const existingSecretObject = findSecretByName(secret.name, this.secrets.observable());
218+
wktLogger.debug('working on secret %s', secret.name);
219+
220+
// The secret should always exist already because prepare model updated the model first,
221+
// which triggers updating the secrets ListProperty. If not, something is broken...
222+
//
223+
const existingSecretObject = findSecretByName(this.uid.value, secret.name, this.secrets.observable());
212224
updateSecretFromPrepareModelResults(existingSecretObject, secret.keys);
213225
}
226+
} else {
227+
wktLogger.debug('handlePrepareModelSecrets() has nothing to do');
214228
}
215229
};
216230

@@ -222,7 +236,7 @@ define(['knockout', 'utils/observable-properties', 'utils/common-utilities', 'ut
222236

223237
this.getFieldValueFromExistingSecrets = (uid, fieldName, defaultValue) => {
224238
let result = defaultValue;
225-
for (const domainSecret of this.secrets.value) {
239+
for (const domainSecret of this.secrets.observable()) {
226240
if (domainSecret.uid === uid) {
227241
if (domainSecret[fieldName]) {
228242
result = domainSecret[fieldName];
@@ -269,10 +283,11 @@ define(['knockout', 'utils/observable-properties', 'utils/common-utilities', 'ut
269283
}
270284
}
271285

272-
function findSecretByName(secretName, secretsList) {
286+
function findSecretByName(domainUid, secretName, secretsList) {
273287
let result;
288+
const domainQualifiedSecretName = `${domainUid}-${secretName}`;
274289
for (const secret of secretsList) {
275-
if (secret.name === secretName) {
290+
if (secret.name === domainQualifiedSecretName || secret.name === secretName) {
276291
result = secret;
277292
break;
278293
}

webui/src/js/models/wdt-model-definition.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,24 @@ define(['knockout', 'utils/observable-properties', 'js-yaml', 'utils/validation-
111111
const secretName = matches.groups.name;
112112
const secretEnvVar = matches.groups.envvar;
113113
const secretField = matches.groups.field;
114-
115-
const secretKey = secretEnvVar ? `${secretEnvVar}-${secretName}` : secretName;
114+
wktLogger.debug('found matching secret %s with envVar = %s and field = %s', secretName, secretEnvVar, secretField);
115+
116+
// While this key is never used outside this function, we need the key to
117+
// match the resolved secret name. For example, if the DOMAIN_UID is mydomain,
118+
// the following two secret fields should be part of the same secret:
119+
//
120+
// JDBCDriverParams:
121+
// URL: '@@PROP:JDBC.myds.URL@@'
122+
// PasswordEncrypted: '@@SECRET:@@ENV:DOMAIN_UID@@-jdbc-myds:password@@'
123+
// DriverName: com.mysql.cj.jdbc.Driver
124+
// Properties:
125+
// user:
126+
// Value: '@@SECRET:mydomain-jdbc-myds:username@@'
127+
//
128+
let secretKey = secretName;
129+
if (secretEnvVar) {
130+
secretKey = secretName.startsWith('-') ? `${secretEnvVar}${secretName}` : `${secretEnvVar}-${secretName}`;
131+
}
116132

117133
let secretData;
118134
if (secretsMap.has(secretKey)) {
@@ -125,6 +141,8 @@ define(['knockout', 'utils/observable-properties', 'js-yaml', 'utils/validation-
125141
}
126142
secretData[secretField] = '';
127143
secretsMap.set(secretKey, secretData);
144+
} else {
145+
wktLogger.debug('skipping matching secret %s', matches.groups.name);
128146
}
129147
});
130148
return [...secretsMap.values()];
@@ -287,14 +305,19 @@ define(['knockout', 'utils/observable-properties', 'js-yaml', 'utils/validation-
287305
*/
288306
this.setModelFileContents = modelContent => {
289307
this.modelFileContents = {};
290-
this.modelContent('');
291308

292309
const models = modelContent['models'];
293-
if(models) {
310+
if (models) {
294311
for (const [file, contents] of Object.entries(models)) {
295312
this.recordModelFile(file, contents);
296313
}
297314
this.modelContent(this.getCurrentModelFileContents() || '');
315+
} else {
316+
// Only empty the model content where explicitly told to do so
317+
// since setting this field generates an event that triggers
318+
// other code to run (e.g., k8s-domain-definition.updateSecrets()).
319+
//
320+
this.modelContent('');
298321
}
299322
};
300323

webui/src/js/utils/observable-properties.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,8 @@ define(['knockout', 'utils/common-utilities', 'utils/validation-helper', 'utils/
438438
}
439439
}
440440

441-
addNewItem() {
442-
this.observable.push(this.createArrayItem(this, arguments.length === 0 ? {} : arguments[0]));
441+
addNewItem(item) {
442+
this.observable.push(this.createArrayItem(this, !!item ? item : {}));
443443
}
444444

445445
get observable() {

webui/src/js/viewModels/ingress-design-view-impl.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ function(i18n, accUtils, ko, ArrayDataProvider, BufferingDataProvider, project,
195195
this.handleDeleteRoute = (event, context) => {
196196
const index = context.item.index;
197197
this.routes.observable.splice(index, 1);
198-
const title = i18n.t('ingress-installer-delete-route-warning-title');
199-
const message = i18n.t('ingress-installer-delete-route-warning-message');
198+
const title = i18n.t('ingress-design-delete-route-warning-title');
199+
const message = i18n.t('ingress-design-delete-route-warning-message');
200200
window.api.ipc.invoke('show-error-message', title, message);
201201
};
202202

@@ -235,7 +235,6 @@ function(i18n, accUtils, ko, ArrayDataProvider, BufferingDataProvider, project,
235235
this.getEnabledText = (value) => {
236236
return this.anyLabelMapper(value ? 'dialog-button-yes' : 'dialog-button-no');
237237
};
238-
239238
}
240239

241240
/*

0 commit comments

Comments
 (0)