Skip to content

First pass at WKO 4.0 support #173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions electron/app/js/ipcRendererPreload.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ contextBridge.exposeInMainWorld(
'k8s-get-service-details',
'k8s-get-ingresses',
'k8s-get-operator-version-from-domain-config-map',
'k8s-get-operator-version',
'k8s-get-k8s-config',
'k8s-get-k8s-cluster-info',
'k8s-get-wko-domain-status',
Expand Down
62 changes: 61 additions & 1 deletion electron/app/js/kubectlUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,28 @@ async function getOperatorLogs(kubectlExe, operatorNamespace, options) {
});
}

async function getOperatorVersion(kubectlExe, operatorNamespace, options) {
const results = {
isSuccess: true
};

return new Promise(resolve => {
getOperatorLogs(kubectlExe, operatorNamespace, options).then(logResult => {
if (logResult.isSuccess === false) {
results.isSuccess = false;
results.reason = i18n.t('kubectl-get-operator-version-error-message', {error: logResult.reason});
return resolve(results);
}
_getOperatorVersionFromLogs(logResult.operatorLogs, results);
resolve(results);
}).catch(err => {
results.isSuccess = false;
results.reason = i18n.t('kubectl-get-operator-version-error-message', {error: getErrorMessage(err)});
resolve(results);
});
});
}

async function getOperatorVersionFromDomainConfigMap(kubectlExe, domainNamespace, options) {
const args = [ 'get', 'configmap', 'weblogic-scripts-cm', '-n', domainNamespace, '-o',
'jsonpath={.metadata.labels.weblogic\\.operatorVersion}'];
Expand Down Expand Up @@ -346,7 +368,7 @@ async function validateApplicationExist(kubectlExe, options, application, namesp
return Promise.resolve(result);
}

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

function _getOperatorVersionFromLogs(operatorLogs, results) {
const versionRegex = /^Oracle WebLogic Kubernetes Operator, version:\s*(\d+\.\d+\.\d+),.*$/;
if (Array.isArray(operatorLogs) && operatorLogs.length > 0) {
for (const logEntry of operatorLogs) {
const parsedEntry = _parseLogEntryAsJson(logEntry);
if (typeof parsedEntry === 'undefined') {
continue;
}

const message = parsedEntry.message || '';
const match = message.match(versionRegex);
if (Array.isArray(match) && match.length > 1) {
results.isSuccess = true;
results.version = match[1];
getLogger().debug('Found installed operator version %s', results.version);
return;
}
}
results.isSuccess = false;
results.reason = i18n.t('kubectl-get-operator-version-not-found-error-message');
} else {
results.isSuccess = false;
results.reason = i18n.t('kubectl-get-operator-version-logs-empty-error-message');
}
}

function _parseLogEntryAsJson(logEntry) {
let result;

try {
result = JSON.parse(logEntry);
} catch (err) {
// Assume the entry is not in JSON format and return undefined
}
return result;
}

module.exports = {
apply,
applyUsingUrl,
Expand All @@ -982,6 +1041,7 @@ module.exports = {
createOrReplaceTLSSecret,
createServiceAccountIfNotExists,
getCurrentContext,
getOperatorVersion,
isOperatorAlreadyInstalled,
isVerrazzanoInstalled,
setCurrentContext,
Expand Down
5 changes: 4 additions & 1 deletion electron/app/locales/en/electron.json
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,17 @@
"kubectl-cluster-info-error-message": "Unable to get the Kubernetes cluster info: {{error}}",
"kubectl-get-wko-domain-status-error-message": "Unable to get Kubernetes wko domain status: {{error}}",
"kubectl-get-operator-status-error-message": "Unable to get wko operator status: {{error}}",
"kubectl-get-operator-logs-error-message": "Unable to get wko operator logs: {{error}}",
"kubectl-get-operator-logs-error-message": "Unable to get WebLogic Kubernetes Operator logs: {{error}}",
"kubectl-get-operator-version-error-message": "Unable to determine the WebLogic Kubernetes Operator version: {{error}}",
"kubectl-get-operator-version-logs-empty-error-message": "Unable to determine the WebLogic Kubernetes Operator version because the operator log was empty",
"kubectl-get-operator-version-from-cm-error-message": "Unable to get operator version: {{error}}",
"kubectl-tlsfile-not-specified-error-message": "TLS file path was not provided",
"kubectl-tlsfile-not-exists-error-message": "TLS file {{filePath}} does not exist",
"kubectl-tlsfile-failed-error-message": "Unable to verify TLS file {{filePath}} exists: {{error}}",
"kubectl-get-vz-install-failed-error-message": "Unable to get Verrazzano installation: {{error}}",
"kubectl-get-named-vz-install-error-message": "Unable to get Verrazzano installation with name {{name}}: {{error}}",
"kubectl-get-vz-application-status-error-message": "Unable to get Verrazzano application status: {{error}}",
"kubectl-get-operator-version-not-found-error-message": "Failed to find the operator version from its log entries",

"helm-not-specified-error-message": "Helm executable path was not provided",
"helm-not-exists-error-message": "Helm executable {{filePath}} does not exist",
Expand Down
25 changes: 22 additions & 3 deletions electron/app/locales/en/webui.json
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,9 @@
"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.",
"domain-design-pv-volume-log-home-label": "Log Home Path",
"domain-design-pv-volume-log-home-help": "The path to use to write the WebLogic Server log files.",
"domain-design-wko-installed-version-label": "WebLogic Kubernetes Operator Installed Version",
"domain-design-wko-installed-version-help": "The version of the WebLogic Kubernetes Operator that is installed in the Kubernetes cluster.",
"domain-design-wko-installed-version-tooltip": "Get the installed version of the WebLogic Kubernetes Operator from the Kubernetes cluster.",

"domain-design-image-title": "Primary Image to Use for the Domain",
"domain-design-hints-goto-create-image": "Go To Create Primary Image Page",
Expand Down Expand Up @@ -558,6 +561,10 @@
"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.",
"domain-design-aux-image-pull-policy-label": "Auxiliary Image Pull Policy",
"domain-design-aux-image-pull-policy-help": "When to pull the domain's auxiliary image from the image registry.",
"domain-design-aux-image-source-wdt-home-label": "WebLogic Deploy Tooling Install Home in Auxiliary Image",
"domain-design-aux-image-source-wdt-home-help": "The source location of the WebLogic Deploy Tooling installation within the auxiliary image.",
"domain-design-aux-image-source-model-home-label": "WebLogic Deploy Tooling Model Home in Auxiliary Image",
"domain-design-aux-image-source-model-home-help": "The source directory location of the WebLogic Deploy Tooling model files within the auxiliary image.",
"domain-design-aux-image-registry-pull-requires-authentication-label": "Specify Auxiliary Image Pull Credentials",
"domain-design-aux-image-registry-pull-requires-authentication-help": "Whether you want to specify authentication credentials for pulling the auxiliary image from the registry.",
"domain-design-aux-image-registry-use-existing-pull-secret-label": "Use Existing Auxiliary Image Pull Secret",
Expand Down Expand Up @@ -1104,6 +1111,17 @@
"kubectl-get-current-context-error-title": "Kubernetes Client Failed",
"kubectl-get-current-context-error-message": "kubectl failed to get the current Kubernetes cluster context: {{error}}.",

"wko-get-install-version-aborted-error-title": "Getting Installed WebLogic Kubernetes Operator Version Aborted",
"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}}.",
"wko-get-install-version-project-not-saved-error-prefix": "Unable to get the installed WebLogic Kubernetes Operator version because project save failed",
"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}}.",
"wko-get-install-version-checking-installed-in-progress": "Verifying that the WebLogic Kubernetes Operator is installed",
"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}}.",
"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.",
"wko-get-install-version-get-in-progress": "Getting the installed version of WebLogic Kubernetes Operator",
"wko-get-install-version-get-failed-title": "Getting Installed WebLogic Kubernetes Operator Version Failed",
"wko-get-install-version-get-failed-error-message": "Unable to get the installed version of WebLogic Kubernetes Operator from Kubernetes namespace {{operatorNamespace}}: {{error}}.",

"wko-installer-aborted-error-title": "WebLogic Kubernetes Operator Installation Aborted",
"wko-installer-kubectl-exe-invalid-error-message": "Unable to install WebLogic Kubernetes Operator because the Kubernetes client executable is invalid: {{error}}.",
"wko-installer-helm-exe-invalid-error-message": "Unable to install WebLogic Kubernetes Operator because the Helm executable is invalid: {{error}}.",
Expand Down Expand Up @@ -1270,6 +1288,7 @@
"flow-verify-kubectl-connectivity-name": "Verify Connectivity",
"flow-install-operator-name": "Install Operator",
"flow-update-operator-name": "Update Operator",
"flow-wko-get-install-version-name": "Get WebLogic Kubernetes Operator Installed Version",
"flow-uninstall-operator-name": "Uninstall Operator",
"flow-deploy-domain-name": "Deploy Domain",
"flow-domain-exists-check-in-progress": "Verifying Domain {{domainUid}} exists",
Expand Down Expand Up @@ -1443,9 +1462,9 @@
"vz-install-status-checker-status-catch-all-error-message": "Checking the status of the Verrazzano installation with an unexpected error: {{error}}",

"vz-get-install-version-aborted-error-title": "Getting Installed Verrazzano Version Aborted",
"vz-get-install-version-kubectl-exe-invalid-error-message": "Unable to install Verrazzano because the Kubernetes client executable is invalid: {{error}}.",
"vz-get-install-version-project-not-saved-error-prefix": "Unable to install Verrazzano because project save failed",
"vz-get-install-version-set-context-error-message": "Unable to install Verrazzano because setting the Kubernetes client cluster context failed: {{error}}.",
"vz-get-install-version-kubectl-exe-invalid-error-message": "Unable to get the installed Verrazzano version because the Kubernetes client executable is invalid: {{error}}.",
"vz-get-install-version-project-not-saved-error-prefix": "Unable to get the installed Verrazzano version because project save failed",
"vz-get-install-version-set-context-error-message": "Unable to get the installed Verrazzano version because setting the Kubernetes client cluster context failed: {{error}}.",
"vz-get-install-version-get-in-progress": "Getting the installed version of Verrazzano",
"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}}.",
"vz-get-install-version-not-installed-error-message": "unable to get the installed version of Verrazzano because Verrazzano is not installed.",
Expand Down
31 changes: 25 additions & 6 deletions electron/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -765,8 +765,8 @@ class Main {
return kubectlUtils.getApplicationStatus(kubectlExe, application, namespace, options);
});

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

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

ipcMain.handle('helm-install-wko', async (event, helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions) => {
return helmUtils.installWko(helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions);
ipcMain.handle('helm-install-wko',async (event, helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions, kubectlExe, kubectlOptions) => {
const results = await helmUtils.installWko(helmExe, helmReleaseName, operatorNamespace, helmChartValues, helmOptions);
if (results.isSuccess) {
const versionResults = await kubectlUtils.getOperatorVersion(kubectlExe, operatorNamespace, kubectlOptions);
if (versionResults.isSuccess) {
results.version = versionResults.version;
}
}
return Promise.resolve(results);
});

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

ipcMain.handle('helm-update-wko', async (event, helmExe, operatorName, operatorNamespace, helmChartValues, helmOptions) => {
return helmUtils.updateWko(helmExe, operatorName, operatorNamespace, helmChartValues, helmOptions);
ipcMain.handle('helm-update-wko', async (event, helmExe, operatorName,
operatorNamespace, helmChartValues, helmOptions, kubectlExe = undefined, kubectlOptions = undefined) => {
const results = await helmUtils.updateWko(helmExe, operatorName, operatorNamespace, helmChartValues, helmOptions);
if (kubectlExe && results.isSuccess) {
const versionResults = await kubectlUtils.getOperatorVersion(kubectlExe, operatorNamespace, kubectlOptions);
if (versionResults.isSuccess) {
results.version = versionResults.version;
}
}
return Promise.resolve(results);
});

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

ipcMain.handle('k8s-get-operator-version', async (event, kubectlExe, operatorNamespace, options) => {
return kubectlUtils.getOperatorVersion(kubectlExe, operatorNamespace, options);
});

ipcMain.handle('get-tls-keyfile', async (event) => {
const title = i18n.t('dialog-tls-keyfile', {});
return chooseFromFileSystem(event.sender.getOwnerBrowserWindow(), {
Expand Down
4 changes: 2 additions & 2 deletions electron/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion electron/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "wktui",
"productName": "WebLogic Kubernetes Toolkit UI",
"version": "1.3.1",
"version": "1.4.0",
"description": "WebLogic Kubernetes Toolkit UI",
"copyright": "Copyright (c) 2021, 2022, Oracle and/or its affiliates.",
"homepage": "https://github.com/oracle/weblogic-toolkit-ui",
Expand Down
2 changes: 2 additions & 0 deletions webui/src/js/models/k8s-domain-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ define(['knockout', 'utils/observable-properties', 'utils/common-utilities', 'ut
this.auxImageRegistryPullEmail = props.createProperty();
this.auxImageRegistryPullEmail.addValidator(...validationHelper.getEmailAddressValidators());
this.auxImagePullPolicy = props.createProperty('IfNotPresent');
this.auxImageSourceModelHome = props.createProperty('/auxiliary/models');
this.auxImageSourceWDTInstallHome = props.createProperty('/auxiliary/weblogic-deploy');

this.clusterKeys = [
'uid', 'name', 'maxServers', 'replicas', 'minHeap', 'maxHeap', 'cpuRequest', 'cpuLimit', 'memoryRequest',
Expand Down
2 changes: 2 additions & 0 deletions webui/src/js/models/wko-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ define(['utils/observable-properties', 'utils/validation-helper'],

this.helmTimeoutMinutes = props.createProperty(5);

this.installedVersion = props.createProperty();

// internal fields that should not be read or written to the project file.
this.internal = {
operatorImagePullRegistryAddress: props.createProperty()
Expand Down
6 changes: 5 additions & 1 deletion webui/src/js/utils/k8s-domain-deployer.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
}

// Run helm upgrade so that operator picks up the new namespace.
//
// Skip passing kubectlExe and kubectlOptions args since the installed version
// of operator was already set.
//
const helmOptions = helmHelper.getHelmOptions();
const upgradeResults = await window.api.ipc.invoke('helm-update-wko', helmExe, operatorName,
operatorNamespace, helmChartValues, helmOptions);
Expand Down Expand Up @@ -423,7 +427,7 @@ function (K8sDomainActionsBase, project, wktConsole, i18n, projectIo, dialogHelp
async checkOperatorIsInstalled(kubectlExe, kubectlOptions, operatorName, operatorNamespace, errTitle) {
try {
const isInstalledResults =
await window.api.ipc.invoke('is-wko-installed', kubectlExe, operatorName, operatorNamespace, kubectlOptions);
await window.api.ipc.invoke('is-wko-installed', kubectlExe, operatorNamespace, kubectlOptions);
if (!isInstalledResults.isInstalled) {
let errMessage;
if (isInstalledResults.reason) {
Expand Down
Loading