Skip to content

Commit b860456

Browse files
Merge pull request #58 from oracle/uninstall-namespaces
added option to delete namespace when uninstalling operator and ingress controller
2 parents f1ac345 + 47966e4 commit b860456

File tree

9 files changed

+147
-90
lines changed

9 files changed

+147
-90
lines changed

electron/app/js/ipcRendererPreload.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ contextBridge.exposeInMainWorld(
145145
'verify-file-exists',
146146
'ok-or-cancel-prompt',
147147
'yes-or-no-prompt',
148+
'yes-no-or-cancel-prompt',
148149
'install-app-update',
149150
'get-latest-wdt-installer',
150151
'wit-cache-installers',
@@ -191,8 +192,7 @@ contextBridge.exposeInMainWorld(
191192
'k8s-delete-object',
192193
'openssl-generate-certs',
193194
'validate-k8s-namespaces-exist',
194-
'validate-wko-domain-exist',
195-
'domain-undeploy-scope-prompt'
195+
'validate-wko-domain-exist'
196196
];
197197
return new Promise((resolve, reject) => {
198198
if (validChannels.includes(channel)) {

electron/app/js/wktWindow.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,25 +1002,25 @@ async function promptUserForYesOrNoAnswer(targetWindow, title, message) {
10021002
});
10031003
}
10041004

1005-
async function promptUserForK8sDomainRemovalScope(targetWindow, title, question, details) {
1005+
async function promptUserForYesNoOrCancelAnswer(targetWindow, title, question, details) {
10061006
return new Promise(resolve => {
10071007
dialog.showMessageBox(targetWindow, {
10081008
title: title,
10091009
message: question,
10101010
detail: details,
10111011
type: 'question',
1012-
buttons: [ i18n.t('button-cancel'), i18n.t('button-domain-only'), i18n.t('button-domain-namespace') ],
1012+
buttons: [ i18n.t('button-cancel'), i18n.t('button-no'), i18n.t('button-yes') ],
10131013
defaultId: 1,
10141014
cancelId: 0
10151015
}).then(dialogResponse => {
10161016
let response;
10171017
switch (dialogResponse.response) {
10181018
case 2:
1019-
response = 'namespace';
1019+
response = 'yes';
10201020
break;
10211021

10221022
case 1:
1023-
response = 'domain';
1023+
response = 'no';
10241024
break;
10251025

10261026
case 0:
@@ -1088,7 +1088,7 @@ module.exports = {
10881088
setHasOpenDialog,
10891089
setTargetType,
10901090
showErrorMessage,
1091-
promptUserForK8sDomainRemovalScope,
10921091
promptUserForOkOrCancelAnswer,
1093-
promptUserForYesOrNoAnswer
1092+
promptUserForYesOrNoAnswer,
1093+
promptUserForYesNoOrCancelAnswer
10941094
};

electron/app/locales/en/electron.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,6 @@
187187
"button-useExistingLocation": "Use Existing Location",
188188
"button-update-now": "Update and Restart Now",
189189
"button-update-on-exit": "Update when Application Exits",
190-
"button-domain-only": "Remove Domain Only",
191-
"button-domain-namespace": "Remove Entire Namespace",
192190

193191
"tools-docker-hub": "Docker Hub",
194192

electron/app/locales/en/webui.json

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,6 @@
637637
"ingress-design-ingress-annotations": "Optional Annotations",
638638
"ingress-design-ingress-route-name-help": "The name to be used for creating this ingress route.",
639639
"ingress-design-ingress-route-virtualhost-help": "The virtual host name is used as the host routing rule for this ingress route.",
640-
"ingress-design-ingress-route-virtualhost-help": "The virtual host name is used as the host routing rule for this ingress route.",
641640
"ingress-design-ingress-route-targetservice-help": "The target service is the where this ingress route will send the request to the backend Kubernetes service address.",
642641
"ingress-design-ingress-route-targetport-help": "The target port is the where this ingress route will send the request to the backend Kubernetes service port.",
643642
"ingress-design-ingress-route-path-help": "The URL path routing rule for this ingress route.",
@@ -696,18 +695,23 @@
696695

697696
"ingress-uninstaller-aborted-error-title": "Ingress Controller Uninstall Aborted",
698697
"ingress-uninstaller-not-install-message": "The Install Ingress Controller option is off so there is nothing to do.",
698+
"ingress-uninstaller-remove-namespace-prompt-title": "Uninstall {{provider}} Ingress Controller Scope",
699+
"ingress-uninstaller-remove-namespace-prompt-question": "After uninstalling the {{provider}} Ingress Controller {{name}}, would you like to also delete the Kubernetes namespace {{namespace}} (and all of its data)?",
700+
"ingress-uninstaller-remove-namespace-prompt-details": "Uninstalling the {{provider}} Ingress Controller {{name}} will make any running WebLogic domains unreachable from outside the Kubernetes cluster. If you also choose to remove the Kubernetes namespace {{namespace}} will remove all secrets and other Kubernetes objects that exist in the Kubernetes namespace.",
699701
"ingress-uninstaller-kubectl-exe-invalid-error-message": "Unable to uninstall ingress controller because the Kubernetes client executable is invalid: {{error}}.",
700702
"ingress-uninstaller-helm-exe-invalid-error-message": "Unable to uninstall ingress controller because the Helm executable is invalid: {{error}}.",
701703
"ingress-uninstaller-project-not-saved-error-prefix": "Unable to uninstall ingress controller because project save failed",
702704
"ingress-uninstaller-set-context-error-message": "Unable to uninstall ingress controller because setting the Kubernetes client cluster context failed: {{error}}.",
703705
"ingress-uninstaller-checking-installed-in-progress": "Checking to see if the Ingress Controller {{name}} is installed in Kubernetes namespace {{namespace}}.",
704706
"ingress-uninstaller-checking-already-installed-error-message": "Unable to uninstall ingress controller {{name}} from Kubernetes namespace {{namespace}} because an error was encountered while trying to determine if the ingress controller is installed: {{error}}.",
705707
"ingress-uninstaller-ingress-not-installed-error-message": "Unable to uninstall the ingress controller {{name}} from Kubernetes namespace {{namespace}} because it does not appear to be installed.",
706-
"ingress-uninstaller-uninstall-in-progress": "Uninstalling ingress controller {{name}} from Kubernetes namespace {{namespace}}",
707-
"ingress-uninstaller-uninstall-complete-title": "Ingress Controller Uninstall Complete",
708-
"ingress-uninstaller-uninstall-complete-message": "Ingress Controller {{name}} successfully uninstalled from Kubernetes namespace {{namespace}}.",
709-
"ingress-uninstaller-uninstall-failed-title": "Ingress Controller Uninstall Failed",
710-
"ingress-uninstaller-uninstall-failed-error-message": "Uninstalling ingress controller {{name}} from Kubernetes namespace {{namespace}} failed: {{error}}.",
708+
"ingress-uninstaller-uninstall-in-progress": "Uninstalling {{provider}} ingress controller {{name}} from Kubernetes namespace {{namespace}}",
709+
"ingress-uninstaller-remove-namespace-in-progress": "Removing Kubernetes namespace {{namespace}}",
710+
"ingress-uninstaller-uninstall-complete-title": "{{provider}} Ingress Controller Uninstall Complete",
711+
"ingress-uninstaller-uninstall-complete-message": "{{provider}} ingress controller {{name}} successfully uninstalled from Kubernetes namespace {{namespace}}.",
712+
"ingress-uninstaller-uninstall-complete-with-namespace-message": "{{provider}} ingress controller {{name}} successfully uninstalled and Kubernetes namespace {{namespace}} was deleted.",
713+
"ingress-uninstaller-uninstall-failed-title": "{{provider}} Ingress Controller Uninstall Failed",
714+
"ingress-uninstaller-uninstall-failed-error-message": "Uninstalling {{provider}} ingress controller {{name}} from Kubernetes namespace {{namespace}} failed: {{error}}.",
711715
"ingress-uninstaller-uninstall-catch-all-error-message": "Ingress Controller uninstall failed with an unexpected error: {{error}}.",
712716

713717
"ingress-routes-updater-update-aborted-error-title": "Ingress Routes Update Aborted",
@@ -989,6 +993,9 @@
989993
"wko-updater-update-catch-all-error-message": "WebLogic Kubernetes Operator update failed with an unexpected error: {{error}}",
990994

991995
"wko-uninstaller-aborted-error-title": "WebLogic Kubernetes Operator Uninstall Aborted",
996+
"wko-uninstaller-remove-namespace-prompt-title": "Uninstall WebLogic Kubernetes Operator Scope",
997+
"wko-uninstaller-remove-namespace-prompt-question": "After uninstalling the WebLogic Kubernetes Operator {{name}}, would you like to also delete the Kubernetes namespace {{namespace}} (and all of its data)?",
998+
"wko-uninstaller-remove-namespace-prompt-details": "Uninstalling the WebLogic Kubernetes Operator {{name}} will not stop any already running WebLogic domains but these domains will no longer be managed. If you also choose to remove the Kubernetes namespace {{namespace}} will remove all secrets, service accounts, and other Kubernetes objects that exist in the Kubernetes namespace.",
992999
"wko-uninstaller-kubectl-exe-invalid-error-message": "Unable to uninstall WebLogic Kubernetes Operator because the Kubernetes client executable is invalid: {{error}}.",
9931000
"wko-uninstaller-helm-exe-invalid-error-message": "Unable to uninstall WebLogic Kubernetes Operator because the Helm executable is invalid: {{error}}.",
9941001
"wko-uninstaller-project-not-saved-error-prefix": "Unable to uninstall WebLogic Kubernetes Operator because project save failed",
@@ -999,10 +1006,12 @@
9991006
"wko-uninstaller-add-chart-in-progress": "Adding WebLogic Kubernetes Operator Helm chart",
10001007
"wko-uninstaller-add-chart-error-message": "Unable to uninstall WebLogic Kubernetes Operator because an error occurred while adding the Helm chart: {{error}}",
10011008
"wko-uninstaller-uninstall-in-progress": "Uninstalling WebLogic Kubernetes Operator using Helm release name {{helmReleaseName}}",
1009+
"wko-uninstaller-remove-namespace-in-progress": "Removing Kubernetes namespace {{namespace}}",
10021010
"wko-uninstaller-uninstall-complete-title": "WebLogic Kubernetes Operator Uninstall Complete",
1003-
"wko-uninstaller-uninstall-complete-message": "WebLogic Kubernetes Operator {{operatorName}} successfully uninstalled to Kubernetes namespace {{operatorNamespace}}.",
1011+
"wko-uninstaller-uninstall-complete-message": "WebLogic Kubernetes Operator {{operatorName}} successfully uninstalled from Kubernetes namespace {{operatorNamespace}}.",
1012+
"wko-uninstaller-uninstall-complete-with-namespace-message": "WebLogic Kubernetes Operator {{operatorName}} successfully uninstalled and Kubernetes namespace {{operatorNamespace}} was deleted.",
10041013
"wko-uninstaller-uninstall-failed-title": "WebLogic Kubernetes Operator Uninstall Failed",
1005-
"wko-uninstaller-uninstall-failed-error-message":"Unable to uninstall WebLogic Kubernetes Operator {{operatorName}} to Kubernetes namespace {{operatorNamespace}}: {{error}}.",
1014+
"wko-uninstaller-uninstall-failed-error-message":"Unable to uninstall WebLogic Kubernetes Operator {{operatorName}} from Kubernetes namespace {{operatorNamespace}}: {{error}}.",
10061015
"wko-uninstaller-uninstall-catch-all-error-message": "WebLogic Kubernetes Operator uninstall failed with an unexpected error: {{error}}",
10071016

10081017
"k8s-domain-deployer-aborted-error-title": "Deploying WebLogic Domain to Kubernetes Aborted",
@@ -1036,10 +1045,9 @@
10361045
"k8s-domain-script-generator-invalid-target-domain-location": "Unknown value for target domain location {{targetDomainLocation}}",
10371046

10381047
"k8s-domain-undeployer-aborted-error-title": "Undeploying WebLogic Domain from Kubernetes Aborted",
1039-
"k8s-domain-undeployer-scope-prompt-title": "Undeploy WebLogic Domain from Kubernetes Scope",
1040-
"k8s-domain-undeployer-scope-prompt-question": "Would you like to undeploy the just WebLogic domain {{domainUid}} or the entire WebLogic domain's namespace {{domainNamespace}} (and all of its data) from Kubernetes?",
1041-
"k8s-domain-undeployer-scope-prompt-details": "Removing 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, in addition to removing the WebLogic domain {{domainUid}}, remove all secrets, config maps, ingress routes, and other Kubernetes objects that exist in Kubernetes namespace.",
1042-
"k8s-domain-undeployer-prompt-result-assertion-error-message": "Unexpected prompt action 'cancel' while undeploying the Kubernetes WebLogic domain. Please report an issue on GitHub.",
1048+
"k8s-domain-undeployer-remove-namespace-prompt-title": "Undeploy WebLogic Domain from Kubernetes Scope",
1049+
"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)?",
1050+
"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.",
10431051
"k8s-domain-undeployer-kubectl-exe-invalid-error-message": "Unable to undeploy the domain because the Kubernetes client executable is invalid: {{error}}.",
10441052
"k8s-domain-undeployer-project-not-saved-error-prefix": "Unable to undeploy the domain because project save failed",
10451053
"k8s-domain-undeployer-set-context-error-message": "Unable to undeploy the domain because setting the Kubernetes client content failed: {{error}}.",

electron/app/main.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const i18n = require('./js/i18next.config');
1414
const { initializeLoggingSystem, logRendererMessage } = require('./js/wktLogging');
1515
const userSettings = require('./js/userSettings');
1616
const { chooseFromFileSystem, createNetworkWindow, createWindow, initialize, setHasOpenDialog, setTargetType,
17-
showErrorMessage, promptUserForOkOrCancelAnswer, promptUserForYesOrNoAnswer, promptUserForK8sDomainRemovalScope } = require('./js/wktWindow');
17+
showErrorMessage, promptUserForOkOrCancelAnswer, promptUserForYesOrNoAnswer, promptUserForYesNoOrCancelAnswer } =
18+
require('./js/wktWindow');
1819
const project = require('./js/project');
1920
const wktTools = require('./js/wktTools');
2021
const wdtArchive = require('./js/wdtArchive');
@@ -641,6 +642,10 @@ class Main {
641642
return promptUserForYesOrNoAnswer(event.sender.getOwnerBrowserWindow(), title, question);
642643
});
643644

645+
ipcMain.handle('yes-no-or-cancel-prompt', async (event, title, question, details) => {
646+
return promptUserForYesNoOrCancelAnswer(event.sender.getOwnerBrowserWindow(), title, question, details);
647+
});
648+
644649
ipcMain.handle('ok-or-cancel-prompt', async (event, title, question) => {
645650
return promptUserForOkOrCancelAnswer(event.sender.getOwnerBrowserWindow(), title, question);
646651
});
@@ -749,10 +754,6 @@ class Main {
749754
return kubectlUtils.deleteObjectIfExists(kubectlExe, namespace, object, kind, kubectlOptions);
750755
});
751756

752-
ipcMain.handle('domain-undeploy-scope-prompt', async (event, title, question, details) => {
753-
return promptUserForK8sDomainRemovalScope(event.sender.getOwnerBrowserWindow(), title, question, details);
754-
});
755-
756757
ipcMain.handle('helm-add-wko-chart', async (event, helmExe, helmOptions) => {
757758
return helmUtils.addOrUpdateWkoHelmChart(helmExe, helmOptions);
758759
});

webui/src/js/utils/ingress-controller-uninstaller.js

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,24 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, dialogHelper,
3737
return Promise.resolve(false);
3838
}
3939

40-
const totalSteps = 6.0;
40+
const ingressControllerProvider = this.project.ingress.ingressControllerProvider.value;
41+
const ingressControllerNamespace = this.project.ingress.ingressControllerNamespace.value;
42+
const ingressControllerName = this.project.ingress.ingressControllerName.value;
43+
44+
const providerName = i18n.t(`ingress-design-type-${ingressControllerProvider}-label`);
45+
const promptTitle = i18n.t('ingress-uninstaller-remove-namespace-prompt-title',
46+
{ provider: providerName });
47+
const promptQuestion = i18n.t('ingress-uninstaller-remove-namespace-prompt-question',
48+
{ provider: providerName, name: ingressControllerName, namespace: ingressControllerNamespace });
49+
const promptDetails = i18n.t('ingress-uninstaller-remove-namespace-prompt-details',
50+
{ provider: providerName, name: ingressControllerName, namespace: ingressControllerNamespace });
51+
const removeNamespacePromptResult = await this.removeNamespacePrompt(promptTitle, promptQuestion, promptDetails);
52+
if (removeNamespacePromptResult === 'cancel') {
53+
return Promise.resolve(false);
54+
}
55+
const removeNamespace = removeNamespacePromptResult === 'yes';
56+
57+
const totalSteps = removeNamespace ? 7.0 : 6.0;
4158
try {
4259
let busyDialogMessage = i18n.t('flow-validate-kubectl-exe-in-progress');
4360
dialogHelper.openBusyDialog(busyDialogMessage, 'bar');
@@ -80,9 +97,6 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, dialogHelper,
8097
}
8198

8299
const helmOptions = helmHelper.getHelmOptions();
83-
const ingressControllerProvider = this.project.ingress.ingressControllerProvider.value;
84-
const ingressControllerNamespace = this.project.ingress.ingressControllerNamespace.value;
85-
const ingressControllerName = this.project.ingress.ingressControllerName.value;
86100

87101
busyDialogMessage = i18n.t('ingress-uninstaller-checking-installed-in-progress',
88102
{ name: ingressControllerName, namespace: ingressControllerNamespace });
@@ -103,21 +117,17 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, dialogHelper,
103117
}
104118

105119
busyDialogMessage = i18n.t('ingress-uninstaller-uninstall-in-progress',
106-
{ name: ingressControllerName, namespace: ingressControllerNamespace });
120+
{ provider: providerName, name: ingressControllerName, namespace: ingressControllerNamespace });
107121
dialogHelper.updateBusyDialog(busyDialogMessage, 5/totalSteps);
108122
const uninstallResults = await window.api.ipc.invoke('helm-uninstall-ingress-controller',
109123
helmExe, ingressControllerName, ingressControllerNamespace, helmOptions);
110-
if (uninstallResults.isSuccess) {
111-
const title = i18n.t('ingress-uninstaller-uninstall-complete-title');
112-
const message = i18n.t('ingress-uninstaller-uninstall-complete-message',
113-
{ name: ingressControllerName, namespace: ingressControllerNamespace });
114-
dialogHelper.closeBusyDialog();
115-
await window.api.ipc.invoke('show-info-message', title, message);
116-
return Promise.resolve(true);
117-
} else {
118-
errTitle = i18n.t('ingress-uninstaller-uninstall-failed-title');
124+
125+
126+
if (!uninstallResults.isSuccess) {
127+
errTitle = i18n.t('ingress-uninstaller-uninstall-failed-title', { provider: providerName });
119128
const errMessage = i18n.t('ingress-uninstaller-uninstall-failed-error-message',
120129
{
130+
provider: providerName,
121131
name: ingressControllerName,
122132
namespace: ingressControllerNamespace,
123133
error: uninstallResults.reason
@@ -126,6 +136,30 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, dialogHelper,
126136
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
127137
return Promise.resolve(false);
128138
}
139+
140+
if (removeNamespace) {
141+
busyDialogMessage = i18n.t('ingress-uninstaller-remove-namespace-in-progress',
142+
{ namespace: ingressControllerNamespace });
143+
dialogHelper.updateBusyDialog(busyDialogMessage, 7 / totalSteps);
144+
const deleteResults = await this.deleteKubernetesObjectIfExists(kubectlExe, kubectlOptions,
145+
null, 'namespace', ingressControllerNamespace, errTitle, errPrefix);
146+
if (!deleteResults) {
147+
return Promise.resolve(false);
148+
}
149+
}
150+
151+
const title = i18n.t('ingress-uninstaller-uninstall-complete-title', { provider: providerName });
152+
let message;
153+
if (removeNamespace) {
154+
message = i18n.t('ingress-uninstaller-uninstall-complete-with-namespace-message',
155+
{provider: providerName, name: ingressControllerName, namespace: ingressControllerNamespace});
156+
} else {
157+
message = i18n.t('ingress-uninstaller-uninstall-complete-message',
158+
{provider: providerName, name: ingressControllerName, namespace: ingressControllerNamespace});
159+
}
160+
dialogHelper.closeBusyDialog();
161+
await window.api.ipc.invoke('show-info-message', title, message);
162+
return Promise.resolve(true);
129163
} catch (err) {
130164
dialogHelper.closeBusyDialog();
131165
throw err;

0 commit comments

Comments
 (0)