Skip to content

Commit e257dca

Browse files
refactoring kubectl page for vz multi-cluster connectivity infro (#208)
1 parent 3eae371 commit e257dca

19 files changed

+610
-99
lines changed

Jenkinsfile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/*
2-
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates.
33
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
44
*/
55
pipeline {
66
agent { label 'ol8' }
7+
options {
8+
timeout(time: 480, unit: 'MINUTES')
9+
}
710
environment {
811
WKTUI_PROXY = "${env.ORACLE_HTTP_PROXY}"
912
ELECTRON_GET_USE_PROXY = "true"
@@ -54,6 +57,9 @@ pipeline {
5457
parallel {
5558
stage('Linux Build') {
5659
agent { label 'ol8' }
60+
options {
61+
timeout(time: 300, unit: 'MINUTES')
62+
}
5763
environment {
5864
linux_node_dir_name = "node-v${node_version}-linux-x64"
5965
linux_node_installer = "${linux_node_dir_name}.tar.gz"
@@ -194,6 +200,9 @@ pipeline {
194200
}
195201
stage('MacOS Build') {
196202
agent { label('macosx') }
203+
options {
204+
timeout(time: 300, unit: 'MINUTES')
205+
}
197206
environment {
198207
mac_node_dir_name = "node-v${node_version}-darwin-x64"
199208
mac_node_installer = "node-v${node_version}-darwin-x64.tar.gz"
@@ -301,6 +310,9 @@ pipeline {
301310
}
302311
stage('Windows Build') {
303312
agent { label 'windows'}
313+
options {
314+
timeout(time: 300, unit: 'MINUTES')
315+
}
304316
environment {
305317
windows_node_dir_name = "node-v${node_version}-win-x64"
306318
windows_node_installer = "node-v${node_version}-win-x64.zip"

electron/app/js/ipcRendererPreload.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ contextBridge.exposeInMainWorld(
180180
'do-push-image',
181181
'kubectl-get-current-context',
182182
'kubectl-set-current-context',
183+
'kubectl-get-contexts',
183184
'validate-kubectl-exe',
184185
'kubectl-verify-connection',
185186
'validate-helm-exe',

electron/app/js/kubectlUtils.js

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
3+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates.
44
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
55
*/
66
'use strict';
@@ -90,6 +90,30 @@ async function setCurrentContext(kubectlExe, context, options) {
9090
});
9191
}
9292

93+
async function getContexts(kubectlExe, options) {
94+
const args = [ 'config', 'get-contexts', '--output=name' ];
95+
const httpsProxyUrl = getHttpsProxyUrl();
96+
const bypassProxyHosts = getBypassProxyHosts();
97+
const env = getKubectlEnvironment(options, httpsProxyUrl, bypassProxyHosts);
98+
const results = {
99+
isSuccess: true
100+
};
101+
102+
return new Promise(resolve => {
103+
executeFileCommand(kubectlExe, args, env).then(currentContext => {
104+
results['contexts'] = currentContext.trim().split('\n');
105+
getLogger().debug('getContexts result = %s', results['contexts']);
106+
resolve(results);
107+
}).catch(err => {
108+
// kubectl config get-contexts returns an error if the config file doesn't exist...
109+
results.isSuccess = false;
110+
results.reason =
111+
i18n.t('kubectl-get-contexts-error-message',{ error: getErrorMessage(err) });
112+
resolve(results);
113+
});
114+
});
115+
}
116+
93117
async function getK8sConfigView(kubectlExe, options) {
94118
const args = [ 'config', 'view', '-o', 'json'];
95119
const httpsProxyUrl = getHttpsProxyUrl();
@@ -1018,6 +1042,78 @@ async function doCreateSecret(kubectlExe, createArgs, env, namespace, secret, re
10181042
});
10191043
}
10201044

1045+
async function getVerrazzanoIngressExternalAddress(kubectlExe, options) {
1046+
const gatewayService = 'istio-ingressgateway';
1047+
const gatewayNamespace = 'istio-system';
1048+
1049+
const args = [ 'get', 'service', gatewayService, '-n', gatewayNamespace, '-o', 'json'];
1050+
const httpsProxyUrl = getHttpsProxyUrl();
1051+
const bypassProxyHosts = getBypassProxyHosts();
1052+
const env = getKubectlEnvironment(options, httpsProxyUrl, bypassProxyHosts);
1053+
const results = {
1054+
isSuccess: true
1055+
};
1056+
1057+
return new Promise(resolve => {
1058+
executeFileCommand(kubectlExe, args, env).then(serviceJson => {
1059+
const service = JSON.parse(serviceJson);
1060+
const ingressArray = service.status?.loadBalancer?.ingress;
1061+
1062+
if (Array.isArray(ingressArray) && ingressArray.length > 0) {
1063+
results.externalAddress = ingressArray[0].ip;
1064+
}
1065+
if (!results.externalAddress) {
1066+
results.reason = i18n.t('kubectl-get-vz-ingress-external-address-not-found',
1067+
{ gatewayService, gatewayNamespace });
1068+
}
1069+
resolve(results);
1070+
}).catch(err => {
1071+
results.isSuccess = false;
1072+
results.reason =
1073+
i18n.t('kubectl-get-vz-ingress-external-address-error-message',
1074+
{ gatewayService, gatewayNamespace, error: getErrorMessage(err) });
1075+
resolve(results);
1076+
});
1077+
});
1078+
}
1079+
1080+
async function getVerrazzanoApplicationHostnames(kubectlExe, applicationName, applicationNamespace, options) {
1081+
const gatewayType = 'gateways.networking.istio.io';
1082+
const appGatewayName = `${applicationNamespace}-${applicationName}-gw`;
1083+
1084+
const args = [ 'get', gatewayType, appGatewayName, '-n', applicationNamespace, '-o', 'json'];
1085+
const httpsProxyUrl = getHttpsProxyUrl();
1086+
const bypassProxyHosts = getBypassProxyHosts();
1087+
const env = getKubectlEnvironment(options, httpsProxyUrl, bypassProxyHosts);
1088+
const results = {
1089+
isSuccess: true
1090+
};
1091+
1092+
return new Promise(resolve => {
1093+
executeFileCommand(kubectlExe, args, env).then(gatewayJson => {
1094+
const gateway = JSON.parse(gatewayJson);
1095+
const serversArray = gateway.spec?.servers;
1096+
if (Array.isArray(serversArray) && serversArray.length > 0) {
1097+
const hostsArray = serversArray[0].hosts;
1098+
if (Array.isArray(hostsArray) && hostsArray.length > 0) {
1099+
results.hostnames = hostsArray;
1100+
}
1101+
}
1102+
if (results.hostnames) {
1103+
results.reason = i18n.t('kubectl-get-vz-app-hostnames-not-found',
1104+
{ appName: applicationName, appNamespace: applicationNamespace });
1105+
}
1106+
resolve(results);
1107+
}).catch(err => {
1108+
results.isSuccess = false;
1109+
results.reason =
1110+
i18n.t('kubectl-get-vz-app-hostnames-error-message',
1111+
{ appName: applicationName, appNamespace: applicationNamespace, error: getErrorMessage(err) });
1112+
resolve(results);
1113+
});
1114+
});
1115+
}
1116+
10211117
function maskPasswordInCommand(err) {
10221118
// How about other cases?
10231119
return err.replace(/--docker-password=[^\s]+/, '--docker-password=*****');
@@ -1075,6 +1171,7 @@ module.exports = {
10751171
createOrReplacePullSecret,
10761172
createOrReplaceTLSSecret,
10771173
createServiceAccountIfNotExists,
1174+
getContexts,
10781175
getCurrentContext,
10791176
getOperatorVersion,
10801177
isOperatorAlreadyInstalled,
@@ -1086,6 +1183,8 @@ module.exports = {
10861183
getIngresses,
10871184
getK8sConfigView,
10881185
getK8sClusterInfo,
1186+
getVerrazzanoApplicationHostnames,
1187+
getVerrazzanoIngressExternalAddress,
10891188
getWkoDomainStatus,
10901189
getApplicationStatus,
10911190
getOperatorStatus,

electron/app/js/vzUtils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright (c) 2022, Oracle and/or its affiliates.
3+
* Copyright (c) 2022, 2023, Oracle and/or its affiliates.
44
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
55
*/
66
const kubectlUtils = require('./kubectlUtils');

electron/app/locales/en/electron.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@
281281

282282
"kubectl-current-context-error-message": "Failed to get the current kubectl cluster context: {{error}}",
283283
"kubectl-use-context-error-message": "Failed to change the current kubectl cluster context to {{context}}: {{error}}",
284+
"kubectl-get-contexts-error-message": "Failed to get the available kubectl contexts: {{error}}",
284285
"kubectl-not-specified-error-message": "Kubernetes client path was not provided",
285286
"kubectl-not-exists-error-message": "Kubernetes client {{filePath}} does not exist",
286287
"kubectl-exists-failed-error-message": "Unable to verify Kubernetes client {{filePath}} exists: {{error}}",
@@ -322,6 +323,8 @@
322323
"kubectl-get-vz-application-status-error-message": "Unable to get Verrazzano application status: {{error}}",
323324
"kubectl-get-operator-version-not-found-error-message": "Failed to find the operator version from its log entries",
324325
"kubectl-verify-vz-components-deployed-error-message": "Unable to find one or more components in namespace {{namespace}}: {{missingComponents}}",
326+
"kubectl-get-vz-ingress-external-address-not-found": "Unable to find the External IP Address in the Istio Gateway service {{gatewayService}} in Kubernetes namespace {{gatewayNamespace}}",
327+
"kubectl-get-vz-ingress-external-address-error-message": "Failed to find the External IP Address in the Istio Gateway service {{gatewayService}} in Kubernetes namespace {{gatewayNamespace}}: {{error}}",
325328

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

electron/app/locales/en/webui.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@
3939

4040
"kubectl-form-name": "Kubernetes Client Configuration",
4141
"kubectl-title": "Configure the Kubernetes Client",
42+
"kubectl-instructions-heading": "Instructions",
43+
"kubectl-executables-heading": "Client Executables",
44+
"kubectl-wko-connectivity-heading": "Kubernetes Cluster Connectivity Configuration",
45+
"kubectl-vz-connectivity-heading": "Verrazzano Admin Cluster Connectivity Configuration",
46+
"kubectl-vz-managed-clusters-heading": "Verrazzano Managed Clusters Connectivity Configuration",
47+
"kubectl-vz-managed-clusters-table-aria-label": "Verrazzano Managed Clusters Connectivity Table",
48+
"kubectl-vz-managed-clusters-add-row-tooltip": "Add a new Verrazzano Managed Cluster Connectivity row",
49+
"kubectl-vz-managed-clusters-delete-row-tooltip": "Delete the Verrazzano Managed Cluster Connectivity row",
50+
"kubectl-vz-managed-cluster-name-heading": "Verrazzano Managed Cluster Name",
51+
"kubectl-vz-managed-cluster-name-help": "Name of the Verrazzano Managed Cluster.",
52+
"kubectl-vz-managed-cluster-kubeconfig-heading": "Kubernetes Client Config File(s)",
53+
"kubectl-vz-managed-cluster-kubeconfig-help": "The Kubernetes client configuration file(s) to use for connecting to the Verrazzano Managed Cluster.",
54+
"kubectl-vz-managed-cluster-kubecontext-heading": "Kubectl Config Context to Use",
55+
"kubectl-vz-managed-cluster-kubecontext-help": "The Kubernetes client configuration context name to use for connecting to the Verrazzano Managed Cluster.",
56+
"kubectl-vz-managed-cluster-choose-kubecontext-tooltip": "Choose the Kubernetes cluster context for the Verrazzano Managed Cluster from the available contexts in the Kubernetes Client Config File",
57+
"kubectl-vz-managed-cluster-get-context-tooltip": "Get the current Kubernetes cluster context for the Verrazzano Managed Cluster from the Kubernetes Client Config File",
58+
4259
"kubectl-k8s-flavor-label": "Kubernetes Cluster Type",
4360
"kubectl-k8s-flavor-help": "The Kubernetes cluster provider type where the Oracle Fusion Middleware domain will be deployed.",
4461
"kubectl-exe-file-path-label": "Kubectl Executable to Use",
@@ -48,6 +65,8 @@
4865
"kubectl-config-file-help": "The Kubernetes client configuration file(s) to use. Leave this empty to use the default location.",
4966
"kubectl-config-file-tooltip": "Choose the Kubernetes Client Config File(s)",
5067
"kubectl-config-context-label": "Kubectl Config Context to Use",
68+
"kubectl-config-wko-choose-context-tooltip": "Choose the Kubernetes cluster context from the available contexts in the Kubernetes Client Config File",
69+
"kubectl-config-vz-choose-admin-context-tooltip": "Choose the Kubernetes cluster context for the Verrazzano Admin Cluster from the available contexts in the Kubernetes Client Config File",
5170
"kubectl-config-context-tooltip": "Get the current Kubernetes cluster context from the Kubernetes Client Config File",
5271
"kubectl-config-context-help": "The Kubernetes config file context name for the cluster to which you want to connect. The default is to use whatever the current context is, if any.",
5372
"kubectl-helm-exe-file-path-label": "Helm Executable to Use",
@@ -1126,6 +1145,11 @@
11261145

11271146
"kubectl-get-current-context-error-title": "Kubernetes Client Failed",
11281147
"kubectl-get-current-context-error-message": "kubectl failed to get the current Kubernetes cluster context: {{error}}.",
1148+
"kubectl-get-contexts-error-title": "Kubernetes Client Failed",
1149+
"kubectl-get-contexts-error-message": "kubectl failed to get the available Kubernetes cluster contexts: {{error}}.",
1150+
"kubectl-choose-context-dialog-title": "Kubernetes Client Choose Cluster Context",
1151+
"kubectl-choose-context-name-label": "Cluster Context Name",
1152+
"kubectl-choose-context-name-help": "Select the Kubernetes cluster context to use.",
11291153

11301154
"wko-get-install-version-aborted-error-title": "Getting Installed WebLogic Kubernetes Operator Version Aborted",
11311155
"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}}.",

electron/app/main.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,10 @@ class Main {
755755
return kubectlUtils.setCurrentContext(kubectlExe, context, kubectlOptions);
756756
});
757757

758+
ipcMain.handle('kubectl-get-contexts', async (event, kubectlExe, kubectlOptions) => {
759+
return kubectlUtils.getContexts(kubectlExe, kubectlOptions);
760+
});
761+
758762
ipcMain.handle('validate-kubectl-exe', async (event, kubectlExe) => {
759763
return kubectlUtils.validateKubectlExe(kubectlExe);
760764
});

electron/package-lock.json

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

electron/package.json

Lines changed: 2 additions & 2 deletions
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.4.2",
4+
"version": "1.5.0",
55
"description": "WebLogic Kubernetes Toolkit UI",
66
"copyright": "Copyright (c) 2021, 2023, Oracle and/or its affiliates.",
77
"homepage": "https://github.com/oracle/weblogic-toolkit-ui",
@@ -51,7 +51,7 @@
5151
"@electron/notarize": "^1.2.3",
5252
"chai": "^4.3.7",
5353
"chai-as-promised": "^7.1.1",
54-
"electron": "^22.1.0",
54+
"electron": "^22.2.0",
5555
"electron-builder": "^23.6.0",
5656
"eslint": "^8.33.0",
5757
"mocha": "^10.2.0",

webui/src/css/app.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates.
33
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
44
*/
55
.sendOffScreen {
@@ -257,7 +257,7 @@
257257
border: 1px solid var(--oj-collection-border-color);
258258
}
259259

260-
.wkt-paths-table, .wkt-domain-node-selectors-table {
260+
.wkt-paths-table, .wkt-domain-node-selectors-table, .wkt-vz-managed-clusters-table {
261261
border: 1px solid var(--oj-collection-border-color);
262262
width: 100%;
263263
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @license
3-
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
3+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates.
44
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
55
*/
66
'use strict';
@@ -22,6 +22,7 @@ define(['utils/observable-properties'],
2222
executableFilePath: props.createProperty(window.api.k8s.getKubectlFilePath()),
2323
kubeConfigContextToUse: props.createProperty(),
2424
helmExecutableFilePath: props.createProperty(window.api.k8s.getHelmFilePath()),
25+
vzManagedClusters: props.createListProperty(['uid', 'name', 'kubeConfig', 'KubeContext']).persistByKey('uid'),
2526

2627
readFrom: function(json) {
2728
props.createGroup(name, this).readFrom(json);

0 commit comments

Comments
 (0)