Skip to content

Fix how we detect existing ingress objects #91

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 1 commit into from
Feb 7, 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 @@ -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',
Expand Down
25 changes: 25 additions & 0 deletions electron/app/js/kubectlUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -777,6 +801,7 @@ module.exports = {
validateKubectlExe,
deleteObjectIfExists,
getServiceDetails,
getIngresses,
getK8sConfigView,
getK8sClusterInfo,
getWkoDomainStatus,
Expand Down
1 change: 1 addition & 0 deletions electron/app/locales/en/electron.json
Original file line number Diff line number Diff line change
Expand Up @@ -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}}",
Expand Down
1 change: 1 addition & 0 deletions electron/app/locales/en/webui.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions electron/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down
55 changes: 45 additions & 10 deletions webui/src/js/utils/ingress-routes-updater.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down