Skip to content

Commit eaa2bcb

Browse files
Merge pull request #66 from oracle/undeploy-fixes
changing the behavior of undeploy to be consistent with other operations
2 parents cb6d5ae + dc4a12d commit eaa2bcb

File tree

6 files changed

+141
-20
lines changed

6 files changed

+141
-20
lines changed

electron/app/js/kubectlUtils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ async function getOperatorLogs(kubectlExe, operatorNamespace, options) {
199199
}
200200

201201
async function getOperatorVersionFromDomainConfigMap(kubectlExe, domainNamespace, options) {
202-
const args = [ 'get', 'configmap', 'weblogic-scripts-cm', '-n', domainNamespace, '-o', 'jsonpath={.metadata.labels.weblogic\\.operatorVersion}'];
202+
const args = [ 'get', 'configmap', 'weblogic-scripts-cm', '-n', domainNamespace, '-o',
203+
'jsonpath={.metadata.labels.weblogic\\.operatorVersion}'];
203204

204205
const httpsProxyUrl = getHttpsProxyUrl();
205206
const bypassProxyHosts = getBypassProxyHosts();

electron/app/locales/en/webui.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,8 +1037,8 @@
10371037
"k8s-domain-deployer-operator-installed-check-failed-error-message": "Unable to deploy WebLogic domain to Kubernetes because an error occurred while detecting if the WebLogic Kubernetes Operator {{operatorName}} is installed in Kubernetes namespace {{operatorNamespace}}: {{error}}.",
10381038
"k8s-domain-deployer-operator-not-installed-error-message": "Unable to deploy WebLogic domain to Kubernetes because the WebLogic Kubernetes Operator {{operatorName}} is not installed in Kubernetes namespace {{operatorNamespace}}.",
10391039
"k8s-domain-deployer-create-ns-in-progress": "Creating the Kubernetes namespace {{domainNamespace}}",
1040-
"k8s-domain-deployer-create-ns-error-message": "Unable to deploy WebLogic domain to Kubernetes due to an error creating the Kubernetes namespace {{namespace}}: {{error}}",
1041-
"k8s-domain-deployer-label-ns-error-message": "Unable to deploy WebLogic domain to Kubernetes due to an error adding the label {{label}} to the Kubernetes namespace {{domainNamespace}}: {{error}}",
1040+
"k8s-domain-deployer-create-ns-error-message": "Unable to deploy WebLogic domain to Kubernetes due to an error creating the Kubernetes namespace {{namespace}}: {{error}}.",
1041+
"k8s-domain-deployer-label-ns-error-message": "Unable to deploy WebLogic domain to Kubernetes due to an error adding the label {{label}} to the Kubernetes namespace {{domainNamespace}}: {{error}}.",
10421042
"k8s-domain-deployer-update-operator-config-in-progress": "Updating WebLogic Kubernetes Operator {{operatorName}} in Kubernetes namespace {{operatorNamespace}} to manage WebLogic Domain {{domainName}}",
10431043
"k8s-domain-deployer-add-domain-error-message": "Unable to deploy WebLogic domain to Kubernetes due to an error while upgrading the WebLogic Kubernetes Operator {{operatorName}} in namespace {{operatorNamespace}} to pick up monitoring domain namespace {{domainNamespace}}: {{error}}.",
10441044
"k8s-domain-deployer-create-image-pull-secret-in-progress": "Creating image pull secret {{secretName}} in Kubernetes namespace {{domainNamespace}}",
@@ -1062,12 +1062,20 @@
10621062
"k8s-domain-undeployer-aborted-error-title": "Undeploying WebLogic Domain from Kubernetes Aborted",
10631063
"k8s-domain-undeployer-remove-namespace-prompt-title": "Undeploy WebLogic Domain from Kubernetes Scope",
10641064
"k8s-domain-undeployer-remove-namespace-prompt-question": "After undeploying the WebLogic domain {{name}}, would you like to also delete the Kubernetes namespace {{namespace}} (and all of its data)?",
1065-
"k8s-domain-undeployer-remove-namespace-prompt-details": "UUndeploying the WebLogic domain will remove the WebLogic Kubernetes Operator's domain custom resource {{domainUid}} and will cause any running pods associated with the domain to be shut down and removed. Removing the WebLogic domain's namespace {{domainNamespace}} will remove all secrets, config maps, ingress routes, and other Kubernetes objects that exist in the Kubernetes namespace.",
1065+
"k8s-domain-undeployer-remove-namespace-prompt-details": "Undeploying the WebLogic domain will remove the WebLogic Kubernetes Operator's domain custom resource {{domainUid}} and will cause any running pods associated with the domain to be shut down and removed. Removing the WebLogic domain's namespace {{domainNamespace}} will remove all secrets, config maps, ingress routes, and other Kubernetes objects that exist in the Kubernetes namespace.",
10661066
"k8s-domain-undeployer-kubectl-exe-invalid-error-message": "Unable to undeploy the domain because the Kubernetes client executable is invalid: {{error}}.",
1067+
"k8s-domain-undeployer-helm-exe-invalid-error-message": "Unable to undeploy the domain because the Helm executable is invalid: {{error}}.",
10671068
"k8s-domain-undeployer-project-not-saved-error-prefix": "Unable to undeploy the domain because project save failed",
10681069
"k8s-domain-undeployer-set-context-error-message": "Unable to undeploy the domain because setting the Kubernetes client content failed: {{error}}.",
1070+
"k8s-domain-undeployer-validate-ns-failed-error-message": "Unable to undeploy the domain and its Kubernetes namespace {{namespace}} because an error occurred while trying to determine if the namespace exists: {{error}}.",
1071+
"k8s-domain-undeployer-ns-not-exist-error-message": "Unable to undeploy the domain because the domain's Kubernetes namespace {{namespace}} does not exist.",
1072+
"k8s-domain-undeployer-validate-domain-failed-error-message": "Unable to undeploy the domain {{domain}} because an error occurred while trying to determine if the domain exists: {{error}}.",
1073+
"k8s-domain-undeployer-domain-not-exist-error-message": "Unable to undeploy the domain because the domain {{domain}} does not exist.",
1074+
"k8s-domain-undeployer-operator-installed-check-failed-error-message": "Unable to undeploy WebLogic domain because an error occurred while detecting if the WebLogic Kubernetes Operator {{operatorName}} is installed in Kubernetes namespace {{operatorNamespace}}: {{error}}.",
1075+
"k8s-domain-undeployer-update-operator-config-in-progress": "Updating WebLogic Kubernetes Operator {{operatorName}} in Kubernetes namespace {{operatorNamespace}} to stop managing WebLogic Domains in Kubernetes namespace {{domainNamespace}}",
10691076
"k8s-domain-undeployer-k8s-namespace-delete-failed-error-message": "Unable to undeploy the domain because an error occurred while trying to delete the Kubernetes namespace {{namespace}}: {{error}}.",
10701077
"k8s-domain-undeployer-k8s-object-delete-failed-error-message": "Unable to undeploy the domain because an error occurred while trying to delete the Kubernetes {{type}} object {{name}} from the Kubernetes namespace {{namespace}}: {{error}}.",
1078+
"k8s-domain-undeployer-remove-domain-error-message": "Unable to update WebLogic Kubernetes Operator to remove Kubernetes namespace {{domainNamespace}} from its list of managed namespaces due to an error while upgrading the WebLogic Kubernetes Operator {{operatorName}} in namespace {{operatorNamespace}}: {{error}}.",
10711079
"k8s-domain-undeployer-undeploy-complete-title": "WebLogic Domain Undeployment from Kubernetes Complete",
10721080
"k8s-domain-undeployer-undeploy-domain-complete-message": "WebLogic domain {{domainName}} successfully undeployed from Kubernetes namespace {{domainNamespace}}.",
10731081
"k8s-domain-undeployer-undeploy-namespace-complete-message": "WebLogic domain {{domainName}} and Kubernetes namespace {{domainNamespace}} successfully undeployed.",
@@ -1107,6 +1115,8 @@
11071115
"flow-update-operator-name": "Update Operator",
11081116
"flow-uninstall-operator-name": "Uninstall Operator",
11091117
"flow-deploy-domain-name": "Deploy Domain",
1118+
"flow-domain-exists-check-in-progress": "Verifying Domain {{domainUid}} exists",
1119+
"flow-namespace-exists-check-in-progress": "Verifying Kubernetes namespace {{namespace}} exists",
11101120
"flow-undeploy-domain-name": "Undeploy Domain",
11111121
"flow-undeploy-domain-in-progress": "Undeploying Domain {{domainUid}}",
11121122
"flow-undeploy-namespace-in-progress": "Undeploying Domain Namespace {{domainNamespace}}",

webui/src/js/utils/k8s-domain-actions-base.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ function (WktActionsBase, project, wktConsole, i18n, projectIo, dialogHelper) {
2727
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
2828
return Promise.resolve(false);
2929
} else if (!validationResults.isValid) {
30-
const errMessage = i18n.t(`${errPrefix}-domain-not-exist-error-message`, {
31-
domain: this.project.k8sDomain.uid.value,
32-
error: validationResults.reason
33-
});
30+
const errMessage = i18n.t(`${errPrefix}-domain-not-exist-error-message`,
31+
{ domain: this.project.k8sDomain.uid.value });
3432
dialogHelper.closeBusyDialog();
3533
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
3634
return Promise.resolve(false);

webui/src/js/utils/k8s-domain-deployer.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,7 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
120120
break;
121121

122122
case 'List':
123-
const list = this.project.wko.operatorDomainNamespacesList.value;
124-
this.addDomainNamespaceToList(list, this.project.k8sDomain.kubernetesNamespace.value);
123+
const list = this.addDomainNamespaceToList(this.project.k8sDomain.kubernetesNamespace.value);
125124
helmChartValues.domainNamespaces = `{${list.join(',')}}`;
126125
break;
127126

@@ -293,10 +292,13 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
293292
}
294293
}
295294

296-
addDomainNamespaceToList(domainNamespaceList, domainNamespace) {
295+
addDomainNamespaceToList(domainNamespace) {
296+
const domainNamespaceList = this.project.wko.operatorDomainNamespacesList.value;
297297
if (!domainNamespaceList.includes(domainNamespace)) {
298298
domainNamespaceList.push(domainNamespace);
299+
this.project.wko.operatorDomainNamespacesList.value = domainNamespaceList;
299300
}
301+
return this.project.wko.operatorDomainNamespacesList.value;
300302
}
301303

302304
getValidatableObject(flowNameKey) {

webui/src/js/utils/k8s-domain-undeployer.js

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
4848
return Promise.resolve(false);
4949
}
5050
const removeNamespace = removeNamespacePromptResult === 'yes';
51+
const updateOperatorList = removeNamespace &&
52+
this.project.wko.operatorDomainNamespaceSelectionStrategy.value === 'List' &&
53+
this.project.wko.operatorDomainNamespacesList.observable().includes(domainNamespace);
5154

52-
const totalSteps = 4.0;
55+
const totalSteps = updateOperatorList ? 8.0 : 5.0;
5356
try {
5457
let busyDialogMessage = i18n.t('flow-validate-kubectl-exe-in-progress');
5558
dialogHelper.openBusyDialog(busyDialogMessage, 'bar');
@@ -62,36 +65,112 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
6265
}
6366
}
6467

68+
let step = 1;
69+
const helmExe = this.getHelmExe();
70+
if (updateOperatorList && !options.skipHelmExeValidation) {
71+
busyDialogMessage = i18n.t('flow-validate-helm-exe-in-progress');
72+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
73+
if (! await this.validateHelmExe(helmExe, errTitle, errPrefix)) {
74+
return Promise.resolve(false);
75+
}
76+
step++;
77+
}
78+
6579
// While technically not required, we force saving the project for Go Menu item behavior consistency.
6680
//
6781
busyDialogMessage = i18n.t('flow-save-project-in-progress');
68-
dialogHelper.updateBusyDialog(busyDialogMessage, 1 / totalSteps);
82+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
6983
if (!options.skipProjectSave) {
7084
if (! await this.saveProject(errTitle, errPrefix)) {
7185
return Promise.resolve(false);
7286
}
7387
}
88+
step++;
7489

7590
// Set the Kubernetes context, if needed
7691
busyDialogMessage = i18n.t('flow-kubectl-use-context-in-progress');
77-
dialogHelper.updateBusyDialog(busyDialogMessage, 2 / totalSteps);
92+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
7893
const kubectlContext = this.getKubectlContext();
7994
const kubectlOptions = this.getKubectlOptions();
8095
if (!options.skipKubectlSetContext) {
8196
if (! await this.useKubectlContext(kubectlExe, kubectlOptions, kubectlContext, errTitle, errPrefix)) {
8297
return Promise.resolve(false);
8398
}
8499
}
100+
step++;
101+
102+
// Make sure that the domain or namespace exists
103+
if (removeNamespace) {
104+
busyDialogMessage = i18n.t('flow-namespace-exists-check-in-progress', { namespace: domainNamespace });
105+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
106+
if (!await this.validateKubernetesNamespaceExists(kubectlExe, kubectlOptions, domainNamespace, errTitle, errPrefix)) {
107+
return Promise.resolve(false);
108+
}
109+
} else {
110+
busyDialogMessage = i18n.t('flow-domain-exists-check-in-progress', {domainUid: domainUid});
111+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
112+
if (!await this.validateDomainExists(kubectlExe, kubectlOptions, errTitle, errPrefix)) {
113+
return Promise.resolve(false);
114+
}
115+
}
116+
step++;
85117

86118
let deleteResult;
87119
if (removeNamespace) {
120+
const operatorName = this.project.wko.wkoDeployName.value;
121+
const operatorNamespace = this.project.wko.k8sNamespace.value;
122+
123+
let operatorInstalled;
124+
if (updateOperatorList) {
125+
busyDialogMessage = i18n.t('flow-checking-operator-installed-in-progress',
126+
{operatorName: operatorName, Namespace: operatorNamespace});
127+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
128+
if (!options.skipCheckOperatorAlreadyInstalled) {
129+
const isInstalledResult = await this.checkOperatorIsInstalled(kubectlExe, kubectlOptions,
130+
operatorName, operatorNamespace, errTitle);
131+
if (!isInstalledResult) {
132+
return Promise.resolve(false);
133+
}
134+
operatorInstalled = isInstalledResult.isInstalled;
135+
}
136+
step++;
137+
}
138+
88139
busyDialogMessage = i18n.t('flow-undeploy-namespace-in-progress', { domainNamespace: domainNamespace });
89-
dialogHelper.updateBusyDialog(busyDialogMessage, 2 / totalSteps);
140+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
90141
deleteResult = await this.deleteKubernetesObjectIfExists(kubectlExe, kubectlOptions,
91142
null, 'namespace', domainNamespace, errTitle, errPrefix);
143+
144+
if (deleteResult && updateOperatorList) {
145+
step++;
146+
busyDialogMessage = i18n.t('k8s-domain-undeployer-update-operator-config-in-progress',
147+
{operatorName: operatorName, operatorNamespace: operatorNamespace, domainNamespace: domainNamespace});
148+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
149+
if (operatorInstalled) {
150+
const list = this.removeDomainNamespaceFromList(domainNamespace);
151+
const helmChartValues = {
152+
domainNamespaces: `{${list.join(',')}}`
153+
};
154+
155+
const upgradeResults = await window.api.ipc.invoke('helm-update-wko', helmExe, operatorName,
156+
operatorNamespace, helmChartValues, helmHelper.getHelmOptions());
157+
if (!upgradeResults.isSuccess) {
158+
const errMessage = i18n.t('k8s-domain-undeployer-remove-domain-error-message',
159+
{
160+
domainNamespace: domainNamespace,
161+
operatorName: operatorName,
162+
operatorNamespace: operatorNamespace,
163+
error: upgradeResults.reason
164+
});
165+
dialogHelper.closeBusyDialog();
166+
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
167+
return Promise.resolve(false);
168+
}
169+
}
170+
}
92171
} else {
93172
busyDialogMessage = i18n.t('flow-undeploy-domain-in-progress', { domainUid: domainUid });
94-
dialogHelper.updateBusyDialog(busyDialogMessage, 2 / totalSteps);
173+
dialogHelper.updateBusyDialog(busyDialogMessage, step / totalSteps);
95174
deleteResult = await this.deleteKubernetesObjectIfExists(kubectlExe, kubectlOptions,
96175
domainNamespace, 'domain', domainUid, errTitle, errPrefix);
97176
}
@@ -135,6 +214,40 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
135214

136215
return validationObject;
137216
}
217+
218+
async checkOperatorIsInstalled(kubectlExe, kubectlOptions, operatorName, operatorNamespace, errTitle) {
219+
const results = { isInstalled: true };
220+
try {
221+
const isInstalledResults =
222+
await window.api.ipc.invoke('is-wko-installed', kubectlExe, operatorName, operatorNamespace, kubectlOptions);
223+
if (!isInstalledResults.isInstalled) {
224+
if (isInstalledResults.reason) {
225+
// error from backend
226+
const errMessage = i18n.t('k8s-domain-undeployer-operator-installed-check-failed-error-message',
227+
{operatorName: operatorName, operatorNamespace: operatorNamespace, error: isInstalledResults.reason});
228+
wktLogger.error(errMessage);
229+
dialogHelper.closeBusyDialog();
230+
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
231+
return Promise.resolve(false);
232+
} else {
233+
results.isInstalled = false;
234+
}
235+
}
236+
} catch (err) {
237+
return Promise.reject(err);
238+
}
239+
return Promise.resolve(results);
240+
}
241+
242+
removeDomainNamespaceFromList(domainNamespace) {
243+
const domainNamespaceList = this.project.wko.operatorDomainNamespacesList.value;
244+
const position = domainNamespaceList.indexOf(domainNamespace);
245+
if (position >= 0) {
246+
domainNamespaceList.splice(position, 1);
247+
this.project.wko.operatorDomainNamespacesList.value = domainNamespaceList;
248+
}
249+
return this.project.wko.operatorDomainNamespacesList.value;
250+
}
138251
}
139252

140253
return new K8sDomainUndeployer();

webui/src/js/utils/wkt-actions-base.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,7 @@ function(project, wktConsole, i18n, projectIo, dialogHelper) {
296296
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
297297
return Promise.resolve(false);
298298
} else if (!validationResults.isValid) {
299-
const errMessage = i18n.t(`${errPrefix}-ns-not-exist-error-message`, {
300-
namespace: namespace,
301-
error: validationResults.reason
302-
});
299+
const errMessage = i18n.t(`${errPrefix}-ns-not-exist-error-message`, { namespace: namespace });
303300
this._closeBusyDialog(shouldCloseBusyDialog);
304301
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
305302
return Promise.resolve(false);

0 commit comments

Comments
 (0)