Skip to content

Commit 6c34997

Browse files
First pass at WKO 4.0 support (#173)
* intermediate checkin * first pass at adding WKO 4.0 support * bumping version to 1.4.0 due to new feature/behavior change
1 parent 3b650c1 commit 6c34997

25 files changed

+1191
-421
lines changed

electron/app/js/ipcRendererPreload.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ contextBridge.exposeInMainWorld(
190190
'k8s-get-service-details',
191191
'k8s-get-ingresses',
192192
'k8s-get-operator-version-from-domain-config-map',
193+
'k8s-get-operator-version',
193194
'k8s-get-k8s-config',
194195
'k8s-get-k8s-cluster-info',
195196
'k8s-get-wko-domain-status',

electron/app/js/kubectlUtils.js

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,28 @@ async function getOperatorLogs(kubectlExe, operatorNamespace, options) {
209209
});
210210
}
211211

212+
async function getOperatorVersion(kubectlExe, operatorNamespace, options) {
213+
const results = {
214+
isSuccess: true
215+
};
216+
217+
return new Promise(resolve => {
218+
getOperatorLogs(kubectlExe, operatorNamespace, options).then(logResult => {
219+
if (logResult.isSuccess === false) {
220+
results.isSuccess = false;
221+
results.reason = i18n.t('kubectl-get-operator-version-error-message', {error: logResult.reason});
222+
return resolve(results);
223+
}
224+
_getOperatorVersionFromLogs(logResult.operatorLogs, results);
225+
resolve(results);
226+
}).catch(err => {
227+
results.isSuccess = false;
228+
results.reason = i18n.t('kubectl-get-operator-version-error-message', {error: getErrorMessage(err)});
229+
resolve(results);
230+
});
231+
});
232+
}
233+
212234
async function getOperatorVersionFromDomainConfigMap(kubectlExe, domainNamespace, options) {
213235
const args = [ 'get', 'configmap', 'weblogic-scripts-cm', '-n', domainNamespace, '-o',
214236
'jsonpath={.metadata.labels.weblogic\\.operatorVersion}'];
@@ -346,7 +368,7 @@ async function validateApplicationExist(kubectlExe, options, application, namesp
346368
return Promise.resolve(result);
347369
}
348370

349-
async function isOperatorAlreadyInstalled(kubectlExe, operatorName, operatorNamespace, options) {
371+
async function isOperatorAlreadyInstalled(kubectlExe, operatorNamespace, options) {
350372
// We are currently using kubectl to see if the operator deployment exists. The operator deployment
351373
// name is always weblogic-operator...
352374
//
@@ -971,6 +993,43 @@ function isNotFoundError(err) {
971993
return /\(NotFound\)/.test(errString);
972994
}
973995

996+
function _getOperatorVersionFromLogs(operatorLogs, results) {
997+
const versionRegex = /^Oracle WebLogic Kubernetes Operator, version:\s*(\d+\.\d+\.\d+),.*$/;
998+
if (Array.isArray(operatorLogs) && operatorLogs.length > 0) {
999+
for (const logEntry of operatorLogs) {
1000+
const parsedEntry = _parseLogEntryAsJson(logEntry);
1001+
if (typeof parsedEntry === 'undefined') {
1002+
continue;
1003+
}
1004+
1005+
const message = parsedEntry.message || '';
1006+
const match = message.match(versionRegex);
1007+
if (Array.isArray(match) && match.length > 1) {
1008+
results.isSuccess = true;
1009+
results.version = match[1];
1010+
getLogger().debug('Found installed operator version %s', results.version);
1011+
return;
1012+
}
1013+
}
1014+
results.isSuccess = false;
1015+
results.reason = i18n.t('kubectl-get-operator-version-not-found-error-message');
1016+
} else {
1017+
results.isSuccess = false;
1018+
results.reason = i18n.t('kubectl-get-operator-version-logs-empty-error-message');
1019+
}
1020+
}
1021+
1022+
function _parseLogEntryAsJson(logEntry) {
1023+
let result;
1024+
1025+
try {
1026+
result = JSON.parse(logEntry);
1027+
} catch (err) {
1028+
// Assume the entry is not in JSON format and return undefined
1029+
}
1030+
return result;
1031+
}
1032+
9741033
module.exports = {
9751034
apply,
9761035
applyUsingUrl,
@@ -982,6 +1041,7 @@ module.exports = {
9821041
createOrReplaceTLSSecret,
9831042
createServiceAccountIfNotExists,
9841043
getCurrentContext,
1044+
getOperatorVersion,
9851045
isOperatorAlreadyInstalled,
9861046
isVerrazzanoInstalled,
9871047
setCurrentContext,

electron/app/locales/en/electron.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,14 +315,17 @@
315315
"kubectl-cluster-info-error-message": "Unable to get the Kubernetes cluster info: {{error}}",
316316
"kubectl-get-wko-domain-status-error-message": "Unable to get Kubernetes wko domain status: {{error}}",
317317
"kubectl-get-operator-status-error-message": "Unable to get wko operator status: {{error}}",
318-
"kubectl-get-operator-logs-error-message": "Unable to get wko operator logs: {{error}}",
318+
"kubectl-get-operator-logs-error-message": "Unable to get WebLogic Kubernetes Operator logs: {{error}}",
319+
"kubectl-get-operator-version-error-message": "Unable to determine the WebLogic Kubernetes Operator version: {{error}}",
320+
"kubectl-get-operator-version-logs-empty-error-message": "Unable to determine the WebLogic Kubernetes Operator version because the operator log was empty",
319321
"kubectl-get-operator-version-from-cm-error-message": "Unable to get operator version: {{error}}",
320322
"kubectl-tlsfile-not-specified-error-message": "TLS file path was not provided",
321323
"kubectl-tlsfile-not-exists-error-message": "TLS file {{filePath}} does not exist",
322324
"kubectl-tlsfile-failed-error-message": "Unable to verify TLS file {{filePath}} exists: {{error}}",
323325
"kubectl-get-vz-install-failed-error-message": "Unable to get Verrazzano installation: {{error}}",
324326
"kubectl-get-named-vz-install-error-message": "Unable to get Verrazzano installation with name {{name}}: {{error}}",
325327
"kubectl-get-vz-application-status-error-message": "Unable to get Verrazzano application status: {{error}}",
328+
"kubectl-get-operator-version-not-found-error-message": "Failed to find the operator version from its log entries",
326329

327330
"helm-not-specified-error-message": "Helm executable path was not provided",
328331
"helm-not-exists-error-message": "Helm executable {{filePath}} does not exist",

electron/app/locales/en/webui.json

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,9 @@
517517
"domain-design-pv-volume-log-home-enabled-help": "Whether or not to write the WebLogic Server log files to a location outside the domain home.",
518518
"domain-design-pv-volume-log-home-label": "Log Home Path",
519519
"domain-design-pv-volume-log-home-help": "The path to use to write the WebLogic Server log files.",
520+
"domain-design-wko-installed-version-label": "WebLogic Kubernetes Operator Installed Version",
521+
"domain-design-wko-installed-version-help": "The version of the WebLogic Kubernetes Operator that is installed in the Kubernetes cluster.",
522+
"domain-design-wko-installed-version-tooltip": "Get the installed version of the WebLogic Kubernetes Operator from the Kubernetes cluster.",
520523

521524
"domain-design-image-title": "Primary Image to Use for the Domain",
522525
"domain-design-hints-goto-create-image": "Go To Create Primary Image Page",
@@ -558,6 +561,10 @@
558561
"domain-design-aux-image-registry-address-help": "The image registry hostname and port to use to log in to the registry, if required. This field's value is parsed from the Auxiliary Image Tag field and an empty value assumes Docker Hub is the registry being used.",
559562
"domain-design-aux-image-pull-policy-label": "Auxiliary Image Pull Policy",
560563
"domain-design-aux-image-pull-policy-help": "When to pull the domain's auxiliary image from the image registry.",
564+
"domain-design-aux-image-source-wdt-home-label": "WebLogic Deploy Tooling Install Home in Auxiliary Image",
565+
"domain-design-aux-image-source-wdt-home-help": "The source location of the WebLogic Deploy Tooling installation within the auxiliary image.",
566+
"domain-design-aux-image-source-model-home-label": "WebLogic Deploy Tooling Model Home in Auxiliary Image",
567+
"domain-design-aux-image-source-model-home-help": "The source directory location of the WebLogic Deploy Tooling model files within the auxiliary image.",
561568
"domain-design-aux-image-registry-pull-requires-authentication-label": "Specify Auxiliary Image Pull Credentials",
562569
"domain-design-aux-image-registry-pull-requires-authentication-help": "Whether you want to specify authentication credentials for pulling the auxiliary image from the registry.",
563570
"domain-design-aux-image-registry-use-existing-pull-secret-label": "Use Existing Auxiliary Image Pull Secret",
@@ -1104,6 +1111,17 @@
11041111
"kubectl-get-current-context-error-title": "Kubernetes Client Failed",
11051112
"kubectl-get-current-context-error-message": "kubectl failed to get the current Kubernetes cluster context: {{error}}.",
11061113

1114+
"wko-get-install-version-aborted-error-title": "Getting Installed WebLogic Kubernetes Operator Version Aborted",
1115+
"wko-get-install-version-kubectl-exe-invalid-error-message": "Unable to get the installed WebLogic Kubernetes Operator version because the Kubernetes client executable is invalid: {{error}}.",
1116+
"wko-get-install-version-project-not-saved-error-prefix": "Unable to get the installed WebLogic Kubernetes Operator version because project save failed",
1117+
"wko-get-install-version-set-context-error-message": "Unable to get the installed WebLogic Kubernetes Operator version because setting the Kubernetes client cluster context failed: {{error}}.",
1118+
"wko-get-install-version-checking-installed-in-progress": "Verifying that the WebLogic Kubernetes Operator is installed",
1119+
"wko-get-install-version-install-check-failed-error-message": "Unable to get the installed version of WebLogic Kubernetes Operator because checking to see if it is installed failed: {{error}}.",
1120+
"wko-get-install-version-not-installed-error-message": "Unable to get the installed version of WebLogic Kubernetes Operator because WebLogic Kubernetes Operator is not installed.",
1121+
"wko-get-install-version-get-in-progress": "Getting the installed version of WebLogic Kubernetes Operator",
1122+
"wko-get-install-version-get-failed-title": "Getting Installed WebLogic Kubernetes Operator Version Failed",
1123+
"wko-get-install-version-get-failed-error-message": "Unable to get the installed version of WebLogic Kubernetes Operator from Kubernetes namespace {{operatorNamespace}}: {{error}}.",
1124+
11071125
"wko-installer-aborted-error-title": "WebLogic Kubernetes Operator Installation Aborted",
11081126
"wko-installer-kubectl-exe-invalid-error-message": "Unable to install WebLogic Kubernetes Operator because the Kubernetes client executable is invalid: {{error}}.",
11091127
"wko-installer-helm-exe-invalid-error-message": "Unable to install WebLogic Kubernetes Operator because the Helm executable is invalid: {{error}}.",
@@ -1270,6 +1288,7 @@
12701288
"flow-verify-kubectl-connectivity-name": "Verify Connectivity",
12711289
"flow-install-operator-name": "Install Operator",
12721290
"flow-update-operator-name": "Update Operator",
1291+
"flow-wko-get-install-version-name": "Get WebLogic Kubernetes Operator Installed Version",
12731292
"flow-uninstall-operator-name": "Uninstall Operator",
12741293
"flow-deploy-domain-name": "Deploy Domain",
12751294
"flow-domain-exists-check-in-progress": "Verifying Domain {{domainUid}} exists",
@@ -1443,9 +1462,9 @@
14431462
"vz-install-status-checker-status-catch-all-error-message": "Checking the status of the Verrazzano installation with an unexpected error: {{error}}",
14441463

14451464
"vz-get-install-version-aborted-error-title": "Getting Installed Verrazzano Version Aborted",
1446-
"vz-get-install-version-kubectl-exe-invalid-error-message": "Unable to install Verrazzano because the Kubernetes client executable is invalid: {{error}}.",
1447-
"vz-get-install-version-project-not-saved-error-prefix": "Unable to install Verrazzano because project save failed",
1448-
"vz-get-install-version-set-context-error-message": "Unable to install Verrazzano because setting the Kubernetes client cluster context failed: {{error}}.",
1465+
"vz-get-install-version-kubectl-exe-invalid-error-message": "Unable to get the installed Verrazzano version because the Kubernetes client executable is invalid: {{error}}.",
1466+
"vz-get-install-version-project-not-saved-error-prefix": "Unable to get the installed Verrazzano version because project save failed",
1467+
"vz-get-install-version-set-context-error-message": "Unable to get the installed Verrazzano version because setting the Kubernetes client cluster context failed: {{error}}.",
14491468
"vz-get-install-version-get-in-progress": "Getting the installed version of Verrazzano",
14501469
"vz-get-install-version-install-check-failed-error-message": "Unable to get the installed version of Verrazzano because checking to see if it is installed failed: {{error}}.",
14511470
"vz-get-install-version-not-installed-error-message": "unable to get the installed version of Verrazzano because Verrazzano is not installed.",

electron/app/main.js

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,8 @@ class Main {
765765
return kubectlUtils.getApplicationStatus(kubectlExe, application, namespace, options);
766766
});
767767

768-
ipcMain.handle('is-wko-installed', async (event, kubectlExe, operatorName, operatorNamespace, kubectlOptions) => {
769-
return kubectlUtils.isOperatorAlreadyInstalled(kubectlExe, operatorName, operatorNamespace, kubectlOptions);
768+
ipcMain.handle('is-wko-installed', async (event, kubectlExe, operatorNamespace, kubectlOptions) => {
769+
return kubectlUtils.isOperatorAlreadyInstalled(kubectlExe, operatorNamespace, kubectlOptions);
770770
});
771771

772772
ipcMain.handle('k8s-create-namespace', async (event, kubectlExe, namespace, kubectlOptions) => {
@@ -810,16 +810,31 @@ class Main {
810810
return helmUtils.addOrUpdateWkoHelmChart(helmExe, helmOptions);
811811
});
812812

813-
ipcMain.handle('helm-install-wko', async (event, helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions) => {
814-
return helmUtils.installWko(helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions);
813+
ipcMain.handle('helm-install-wko',async (event, helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions, kubectlExe, kubectlOptions) => {
814+
const results = await helmUtils.installWko(helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions);
815+
if (results.isSuccess) {
816+
const versionResults = await kubectlUtils.getOperatorVersion(kubectlExe, operatorNamespace, kubectlOptions);
817+
if (versionResults.isSuccess) {
818+
results.version = versionResults.version;
819+
}
820+
}
821+
return Promise.resolve(results);
815822
});
816823

817824
ipcMain.handle('helm-uninstall-wko', async (event, helmExe, helmReleaseName, operatorNamespace, helmOptions) => {
818825
return helmUtils.uninstallWko(helmExe, helmReleaseName, operatorNamespace, helmOptions);
819826
});
820827

821-
ipcMain.handle('helm-update-wko', async (event, helmExe, operatorName, operatorNamespace, helmChartValues, helmOptions) => {
822-
return helmUtils.updateWko(helmExe, operatorName, operatorNamespace, helmChartValues, helmOptions);
828+
ipcMain.handle('helm-update-wko', async (event, helmExe, operatorName,
829+
operatorNamespace, helmChartValues, helmOptions, kubectlExe = undefined, kubectlOptions = undefined) => {
830+
const results = await helmUtils.updateWko(helmExe, operatorName, operatorNamespace, helmChartValues, helmOptions);
831+
if (kubectlExe && results.isSuccess) {
832+
const versionResults = await kubectlUtils.getOperatorVersion(kubectlExe, operatorNamespace, kubectlOptions);
833+
if (versionResults.isSuccess) {
834+
results.version = versionResults.version;
835+
}
836+
}
837+
return Promise.resolve(results);
823838
});
824839

825840
ipcMain.handle('helm-list-all-namespaces', async (event, helmExe, helmOptions) => {
@@ -880,6 +895,10 @@ class Main {
880895
return kubectlUtils.getOperatorVersionFromDomainConfigMap(kubectlExe, domainNamespace, options);
881896
});
882897

898+
ipcMain.handle('k8s-get-operator-version', async (event, kubectlExe, operatorNamespace, options) => {
899+
return kubectlUtils.getOperatorVersion(kubectlExe, operatorNamespace, options);
900+
});
901+
883902
ipcMain.handle('get-tls-keyfile', async (event) => {
884903
const title = i18n.t('dialog-tls-keyfile', {});
885904
return chooseFromFileSystem(event.sender.getOwnerBrowserWindow(), {

electron/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

electron/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "wktui",
33
"productName": "WebLogic Kubernetes Toolkit UI",
4-
"version": "1.3.1",
4+
"version": "1.4.0",
55
"description": "WebLogic Kubernetes Toolkit UI",
66
"copyright": "Copyright (c) 2021, 2022, Oracle and/or its affiliates.",
77
"homepage": "https://github.com/oracle/weblogic-toolkit-ui",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ define(['knockout', 'utils/observable-properties', 'utils/common-utilities', 'ut
5656
this.auxImageRegistryPullEmail = props.createProperty();
5757
this.auxImageRegistryPullEmail.addValidator(...validationHelper.getEmailAddressValidators());
5858
this.auxImagePullPolicy = props.createProperty('IfNotPresent');
59+
this.auxImageSourceModelHome = props.createProperty('/auxiliary/models');
60+
this.auxImageSourceWDTInstallHome = props.createProperty('/auxiliary/weblogic-deploy');
5961

6062
this.clusterKeys = [
6163
'uid', 'name', 'maxServers', 'replicas', 'minHeap', 'maxHeap', 'cpuRequest', 'cpuLimit', 'memoryRequest',

webui/src/js/models/wko-definition.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ define(['utils/observable-properties', 'utils/validation-helper'],
7070

7171
this.helmTimeoutMinutes = props.createProperty(5);
7272

73+
this.installedVersion = props.createProperty();
74+
7375
// internal fields that should not be read or written to the project file.
7476
this.internal = {
7577
operatorImagePullRegistryAddress: props.createProperty()

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
124124
}
125125

126126
// Run helm upgrade so that operator picks up the new namespace.
127+
//
128+
// Skip passing kubectlExe and kubectlOptions args since the installed version
129+
// of operator was already set.
130+
//
127131
const helmOptions = helmHelper.getHelmOptions();
128132
const upgradeResults = await window.api.ipc.invoke('helm-update-wko', helmExe, operatorName,
129133
operatorNamespace, helmChartValues, helmOptions);
@@ -423,7 +427,7 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
423427
async checkOperatorIsInstalled(kubectlExe, kubectlOptions, operatorName, operatorNamespace, errTitle) {
424428
try {
425429
const isInstalledResults =
426-
await window.api.ipc.invoke('is-wko-installed', kubectlExe, operatorName, operatorNamespace, kubectlOptions);
430+
await window.api.ipc.invoke('is-wko-installed', kubectlExe, operatorNamespace, kubectlOptions);
427431
if (!isInstalledResults.isInstalled) {
428432
let errMessage;
429433
if (isInstalledResults.reason) {

0 commit comments

Comments
 (0)