diff --git a/electron/app/js/ipcRendererPreload.js b/electron/app/js/ipcRendererPreload.js index 340e6b26a..be76317f6 100644 --- a/electron/app/js/ipcRendererPreload.js +++ b/electron/app/js/ipcRendererPreload.js @@ -174,6 +174,7 @@ contextBridge.exposeInMainWorld( 'k8s-apply', 'k8s-label-namespace', 'k8s-get-service-details', + 'k8s-get-ingresses', 'k8s-get-operator-version-from-domain-config-map', 'k8s-get-k8s-config', 'k8s-get-k8s-cluster-info', diff --git a/electron/app/js/kubectlUtils.js b/electron/app/js/kubectlUtils.js index 5795cfe74..d1a51a729 100644 --- a/electron/app/js/kubectlUtils.js +++ b/electron/app/js/kubectlUtils.js @@ -565,6 +565,30 @@ async function getServiceDetails(kubectlExe, namespace, serviceName, options) { }); } +async function getIngresses(kubectlExe, namespace, serviceType, options) { + const getArgs = [ 'get', serviceType ]; + getArgs.push('-n', namespace, '--output=json'); + const httpsProxyUrl = getHttpsProxyUrl(); + const bypassProxyHosts = getBypassProxyHosts(); + + const env = getKubectlEnvironment(options, httpsProxyUrl, bypassProxyHosts); + const results = { + isSuccess: true + }; + + return new Promise(resolve => { + executeFileCommand(kubectlExe, getArgs, env).then((serviceDetailsJson) => { + results.serviceDetails = JSON.parse(serviceDetailsJson); + resolve(results); + }).catch(err => { + results.isSuccess = false; + results.reason = i18n.t('kubectl-get-ingresses-error-message', + {namespace: namespace, error: getErrorMessage(err), type: serviceType }); + resolve(results); + }); + }); +} + async function apply(kubectlExe, fileData, options) { const httpsProxyUrl = getHttpsProxyUrl(); const bypassProxyHosts = getBypassProxyHosts(); @@ -777,6 +801,7 @@ module.exports = { validateKubectlExe, deleteObjectIfExists, getServiceDetails, + getIngresses, getK8sConfigView, getK8sClusterInfo, getWkoDomainStatus, diff --git a/electron/app/locales/en/electron.json b/electron/app/locales/en/electron.json index 7a6ef6a04..51b23c4fd 100644 --- a/electron/app/locales/en/electron.json +++ b/electron/app/locales/en/electron.json @@ -282,6 +282,7 @@ "kubectl-label-ns-failed-error-message": "Unable to add label {{label}} to Kubernetes namespace {{namespace}} due to an error: {{error}}", "kubectl-delete-object-failed-error-message": "Failed to delete {{object}} in {{namespace}}, reason: {{error}}", "kubectl-get-service-details-error-message": "Unable to get service details in Kubernetes namespace {{namespace}}: {{error}}", + "kubectl-get-ingresses-error-message": "Unable to get {{type}} details in Kubernetes namespace {{namespace}}: {{error}}", "kubectl-config-view-error-message": "Unable to get the Kubernetes config view: {{error}}", "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}}", diff --git a/electron/app/locales/en/webui.json b/electron/app/locales/en/webui.json index 90b14556f..30de76d27 100644 --- a/electron/app/locales/en/webui.json +++ b/electron/app/locales/en/webui.json @@ -770,6 +770,7 @@ "ingress-routes-updater-already-exists-title": "Update Existing Ingress Routes", "ingress-routes-updater-routes-prompt-question": "The following routes `{{routes}}` already exist in the Kubernetes cluster, are you sure you want to overwrite them?", "ingress-routes-updater-get-service-details-error-message": "Unable to update ingress routes because an error occurred getting the ingress service details in Kubernetes namespace {{namespace}}: {{error}}.", + "ingress-routes-updater-get-ingresses-error-message": "Unable to getting ingress details in Kubernetes namespace {{namespace}}: {{error}}.", "ingress-routes-updater-route-target-service-not-exists-error-message": "Unable to update ingress routes because the application was unable to get the details for the target service {{targetService}} specified in route {{name}}: {{error}}.", "ingress-routes-updater-route-target-port-not-exists-error-message": "Unable to update ingress routes because the target port {{targetPort}} specified in route {{name}} does not exists.", "ingress-routes-updater-check-route-target-service-in-progress": "Validating target services and ports for routes", diff --git a/electron/app/main.js b/electron/app/main.js index cc0cddd60..c706330d7 100644 --- a/electron/app/main.js +++ b/electron/app/main.js @@ -813,6 +813,10 @@ class Main { return kubectlUtils.getServiceDetails(kubectlExe, ingressNamespace, serviceName, options); }); + ipcMain.handle('k8s-get-ingresses', async (event, kubectlExe, namespace, serviceType, options) => { + return kubectlUtils.getIngresses(kubectlExe, namespace, serviceType, options); + }); + ipcMain.handle('k8s-get-k8s-config', async (event, kubectlExe, options) => { return kubectlUtils.getK8sConfigView(kubectlExe, options); }); diff --git a/webui/src/js/utils/ingress-routes-updater.js b/webui/src/js/utils/ingress-routes-updater.js index 732aea420..75b3134b2 100644 --- a/webui/src/js/utils/ingress-routes-updater.js +++ b/webui/src/js/utils/ingress-routes-updater.js @@ -154,8 +154,8 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di let k8sClusterAddress; try { k8sClusterAddress = await this._getK8sClusterAddress(kubectlExe, kubectlOptions); - overlappingRoutes = await this.getOverlappingRoutes(kubectlExe, kubectlOptions, k8sClusterAddress, - ingressControllerProvider, ingressControllerNamespace, routes); + overlappingRoutes = await this.getOverlappingRoutes(kubectlExe, kubectlOptions, + ingressControllerProvider, this.project.k8sDomain.kubernetesNamespace.value, routes); } catch (err) { dialogHelper.closeBusyDialog(); await window.api.ipc.invoke('show-error-message', errTitle, err.message); @@ -366,18 +366,29 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di return Promise.resolve(true); } - async getOverlappingRoutes(kubectlExe, kubectlOptions, k8sClusterAddress, provider, namespace, routes) { + async getOverlappingRoutes(kubectlExe, kubectlOptions, provider, namespace, routes) { try { let existingRouteList = []; + const results = + await this.getIngresses(kubectlExe, provider, namespace, kubectlOptions); + if (!results.isSuccess) { + const errMessage = i18n.t('ingress-routes-updater-get-ingresses-error-message', + { namespace: namespace, error: results.reason}); + throw new Error(errMessage); + } for (const route of routes) { - const serviceDetail = - await this.getIngressServiceDetails(kubectlExe, provider, namespace, route, k8sClusterAddress, kubectlOptions); - if (!serviceDetail.isSuccess) { - const errMessage = i18n.t('ingress-routes-updater-get-service-details-error-message', - { namespace: this.project.ingress.ingressControllerNamespace.value, error: serviceDetail.reason }); - throw new Error(errMessage); + results.serviceDetails.items.map( item => { + if (item.metadata.name === route['name']) { + existingRouteList.push(route['name']); + } + }); + if (results.serviceTCPDetails) { + results.serviceTCPDetails.items.map( item => { + if (item.metadata.name === route['name']) { + existingRouteList.push(route['name']); + } + }); } - existingRouteList.push(route['name']); } return Promise.resolve(existingRouteList.length > 0 ? existingRouteList : false); } catch (err) { @@ -514,6 +525,30 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di return Promise.resolve(results); } + async getIngresses(kubectlExe, ingressControllerProvider, namespace, kubectlOptions) { + let serviceType = 'Ingress'; + if (ingressControllerProvider === 'traefik') { + serviceType = 'IngressRoute'; + } + + const results = await window.api.ipc.invoke('k8s-get-ingresses', + kubectlExe, namespace, serviceType, kubectlOptions); + + if (results.isSuccess && ingressControllerProvider === 'traefik') { + serviceType = 'IngressRouteTCP'; + const resultsTCP = await window.api.ipc.invoke('k8s-get-ingresses', + kubectlExe, namespace, serviceType, kubectlOptions); + if (resultsTCP.isSuccess) { + results.serviceTCPDetails = resultsTCP.serviceDetails; + } else { + return Promise.resolve(resultsTCP); + } + + } + + return Promise.resolve(results); + } + async checkTargetService(kubectlExe, ingressDefinition, kubectlOptions, errTitle) { const results = await window.api.ipc.invoke('k8s-get-service-details', kubectlExe, ingressDefinition.targetServiceNameSpace, ingressDefinition.targetService, kubectlOptions);