Skip to content

refactoring most calls to get service details #97

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 14, 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
8 changes: 4 additions & 4 deletions electron/app/locales/en/webui.json
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,8 @@
"ingress-design-ingress-route-traefik-mw-label": "Traefik Middleware",
"ingress-design-ingress-route-traefik-mw-help": "Customize Traefik Middlewares Object",

"ingress-design-ingress-routes-getting-target-service-title" : "Retrieving existing domain service details",
"ingress-design-ingress-routes-getting-target-service-error-message": "Failed to get existing domain service details from Kubernetes namespace {{namespace}}: {{error}}.",
"ingress-design-ingress-routes-get-services-in-namespace-title" : "Retrieving existing domain service details",
"ingress-design-ingress-routes-get-services-in-namespace-error-message": "Failed to get existing domain services from Kubernetes namespace {{namespace}}: {{error}}.",

"ingress-design-ingress-route-name-field-validation-error": "Route {{routeName}}",
"ingress-design-ingress-route-field-validation-error": "Route: {{routeName}}, Field: {{fieldName}}",
Expand Down Expand Up @@ -790,7 +790,7 @@
"ingress-routes-updater-tls-key-invalid-error-message": "Unable to update ingress routes because the TLS Private Key File '{{file}}' does not exist.",
"ingress-routes-updater-project-not-saved-error-prefix": "Unable to update ingress routes because project save failed",
"ingress-routes-updater-check-ingress-service-exists": "Checking ingress controller service exists",
"ingress-routes-updater-service-not-installed-error-message": "Unable to update ingress routes because the ingress controller service {{serviceName}} for ingress controller {{name}} was not found in Kubernetes namespace {{namespace}}. The ingress controller may not have been installed correctly: {{error}}.",
"ingress-routes-updater-service-not-exists-error-message": "Unable to update ingress routes because the ingress controller service {{serviceName}} for ingress controller {{name}} was not found in Kubernetes namespace {{namespace}}. The ingress controller may not have been installed correctly: {{error}}.",
"ingress-routes-updater-create-tls-secret-in-progress": "Creating ingress TLS secret",
"ingress-routes-updater-generate-tls-files-error-message": "Unable to update ingress routes because an error occurred while generating the TLS certificate and private key files: {{error}}.",
"ingress-routes-updater-create-tls-secret-error-message": "Unable to update ingress routes because an error occurred while creating the TLS secret {{name}} in Kubernetes namespace {{namespace}}: {{error}}",
Expand All @@ -800,7 +800,7 @@
"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-target-service-not-exists-error-message": "Unable to update ingress routes because the application was unable to get the details for the target service {{serviceName}} 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",
"ingress-routes-updater-update-route-in-progress": "Updating ingress route {{routeName}}",
Expand Down
75 changes: 28 additions & 47 deletions webui/src/js/utils/ingress-routes-updater.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di
const ingressControllerNamespace = this.project.ingress.ingressControllerNamespace.value;

const results = await this.doesIngressServiceExist(kubectlExe, kubectlOptions, ingressControllerProvider,
ingressControllerName, ingressControllerNamespace, errTitle);
ingressControllerName, ingressControllerNamespace, errTitle, errPrefix);
if (!results) {
return Promise.resolve(false);
}
Expand Down Expand Up @@ -179,7 +179,7 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di
busyDialogMessage = i18n.t('ingress-routes-updater-check-route-target-service-in-progress');
dialogHelper.updateBusyDialog(busyDialogMessage, 7/totalSteps);
for (const route of routes) {
if (! await this.checkTargetService(kubectlExe, route, kubectlOptions)) {
if (! await this.checkTargetService(kubectlExe, route, kubectlOptions, errTitle, errPrefix)) {
return Promise.resolve(false);
}
}
Expand Down Expand Up @@ -328,24 +328,12 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di
return Promise.resolve(true);
}

async doesIngressServiceExist(kubectlExe, kubectlOptions, provider, name, namespace, errTitle) {
try {
const serviceName = provider === 'nginx' ? `${name}-ingress-nginx-controller` : name;
const result = await window.api.ipc.invoke('k8s-get-service-details', kubectlExe, namespace,
serviceName, kubectlOptions);
if (!result.isSuccess) {
const errMessage = i18n.t('ingress-routes-updater-service-not-installed-error-message', {
error: result.reason,
serviceName: serviceName,
name: name,
namespace: namespace
});
dialogHelper.closeBusyDialog();
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
return Promise.resolve(false);
}
} catch (err) {
return Promise.reject(err);
async doesIngressServiceExist(kubectlExe, kubectlOptions, provider, name, namespace, errTitle, errPrefix) {
const serviceName = provider === 'nginx' ? `${name}-ingress-nginx-controller` : name;
const result = await k8sHelper.getDetailsForService(kubectlExe, kubectlOptions, name, namespace, serviceName,
errTitle, errPrefix);
if (!result) {
return Promise.resolve(false);
}
return Promise.resolve(true);
}
Expand Down Expand Up @@ -412,12 +400,15 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di
return Promise.resolve(clusterAddress);
}

// TODO - this code should be refactored to use k8sHelper's getDetailsForService()/getServiceDetailsForNamespace()
// between the complexity of this code and the code calling it, I left this as is for now... --rpatrick
//
async getIngressServiceDetails(kubectlExe, ingressControllerProvider, ingressControllerNamespace,
ingressDefinition, k8sCluster, kubectlOptions) {
// serviceName == '' for Nginx and Traefik for all ingress routes created by the UI
// serviceName = 'voyager-<ingress route name>' for each ingress route if it's provider is
// voyagerProviderMappedValue is baremetal

//
let serviceName = '';
if (ingressControllerProvider === 'voyager') {
serviceName = 'voyager-' + ingressDefinition.name;
Expand All @@ -426,8 +417,6 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di

const results = await window.api.ipc.invoke('k8s-get-service-details',
kubectlExe, ingressControllerNamespace, serviceName, kubectlOptions);
wktLogger.debug('k8s-get-service-details for service %s returned: %s', serviceName,
JSON.stringify(results, 0, null));
if (results.isSuccess) {
let ingressPlainPort = 80;
let ingressSSLPort = 443;
Expand Down Expand Up @@ -549,33 +538,25 @@ function(IngressActionsBase, project, wktConsole, k8sHelper, i18n, projectIo, di
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);

if (results.isSuccess) {
const serviceDetail = results.serviceDetails;
let found = false;
serviceDetail.spec['ports'].forEach((port) => {
if (Number(port.port) === Number(ingressDefinition.targetPort)) {
found = true;
}
});
async checkTargetService(kubectlExe, ingressDefinition, kubectlOptions, errTitle, errPrefix) {
const results = await k8sHelper.getDetailsForService(kubectlExe, kubectlOptions, ingressDefinition.name,
ingressDefinition.targetServiceNameSpace, ingressDefinition.targetService, errTitle, errPrefix);
if (!results) {
return Promise.resolve(false);
}

if (!found) {
const errMessage = i18n.t('ingress-routes-updater-route-target-port-not-exists-error-message', {
name: ingressDefinition['name'],
targetPort: ingressDefinition['targetPort']
});
dialogHelper.closeBusyDialog();
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
return Promise.resolve(false);
const serviceDetail = results;
let found = false;
serviceDetail.spec['ports'].forEach((port) => {
if (Number(port.port) === Number(ingressDefinition.targetPort)) {
found = true;
}
} else {
const errMessage = i18n.t('ingress-routes-updater-route-target-service-not-exists-error-message', {
});

if (!found) {
const errMessage = i18n.t('ingress-routes-updater-route-target-port-not-exists-error-message', {
name: ingressDefinition['name'],
targetService: ingressDefinition['targetService'],
error:results.reason
targetPort: ingressDefinition['targetPort']
});
dialogHelper.closeBusyDialog();
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
Expand Down
35 changes: 35 additions & 0 deletions webui/src/js/utils/wkt-actions-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,41 @@ function(project, wktConsole, i18n, projectIo, dialogHelper,
return Promise.resolve(true);
}

async getDetailsForService(kubectlExe, kubectlOptions, objectName, serviceNamespace, serviceName, errTitle, errPrefix,
shouldCloseBusyDialog = true) {
const results = await window.api.ipc.invoke('k8s-get-service-details', kubectlExe, serviceNamespace,
serviceName, kubectlOptions);

if (!results.isSuccess) {
const errMessage = i18n.t(`${errPrefix}-service-not-exists-error-message`, {
name: objectName,
namespace: serviceNamespace,
serviceName: serviceName,
error:results.reason
});
this._closeBusyDialog(shouldCloseBusyDialog);
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
return Promise.resolve(false);
}
return Promise.resolve(results.serviceDetails);
}

async getServicesDetailsForNamespace(kubectlExe, kubectlOptions, serviceNamespace, errTitle, errPrefix,
shouldCloseBusyDialog = true) {
const results = await window.api.ipc.invoke('k8s-get-service-details', kubectlExe, serviceNamespace,
'', kubectlOptions);
if (!results.isSuccess) {
const errMessage = i18n.t(`${errPrefix}-get-services-in-namespace-error-message`, {
error: results.reason,
namespace: namespace
});
this._closeBusyDialog(shouldCloseBusyDialog);
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
return Promise.resolve(false);
}
return Promise.resolve(results.serviceDetails);
}

_closeBusyDialog(shouldCloseBusyDialog) {
if (shouldCloseBusyDialog) {
dialogHelper.closeBusyDialog();
Expand Down
33 changes: 15 additions & 18 deletions webui/src/js/viewModels/ingress-design-view-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,23 +212,23 @@ function(i18n, accUtils, ko, ArrayDataProvider, BufferingDataProvider, project,
async function getTargetServiceDetails(myProject) {
const kubectlExe = k8sHelper.getKubectlExe();
const kubectlOptions = k8sHelper.getKubectlOptions();
const results = await window.api.ipc.invoke('k8s-get-service-details',
kubectlExe, myProject.k8sDomain.kubernetesNamespace.value, '', kubectlOptions);
let serviceLists = {};
if (results.isSuccess) {
for (const item of results.serviceDetails.items) {
serviceLists[item.metadata.name] = { ports: item.spec.ports};
const namespace = myProject.k8sDomain.kubernetesNamespace.value;
const errTitle = i18n.t('ingress-design-ingress-routes-get-services-in-namespace-title');
const errPrefix = 'ingress-design-ingress-routes';

dialogHelper.openBusyDialog(i18n.t('ingress-design-route-get-services-title', { namespace: namespace }));
const results =
await k8sHelper.getServicesDetailsForNamespace(kubectlExe, kubectlOptions, namespace, errTitle, errPrefix);
if (results) {
const servicesList = {};
console.log('results.items is a ' + typeof(results.items));
for (const item of results.items) {
servicesList[item.metadata.name] = { ports: item.spec.ports };
}
} else {
const errTitle = i18n.t('ingress-design-ingress-routes-getting-target-service-title');
const errMessage = i18n.t('ingress-design-ingress-routes-getting-target-service-error-message', {
error: results.reason,
namespace: namespace
});
await window.api.ipc.invoke('show-error-message', errTitle, errMessage);
return Promise.resolve(false);
dialogHelper.closeBusyDialog();
return Promise.resolve({ serviceList: servicesList });
}
return Promise.resolve( { serviceList: serviceLists});
return Promise.resolve(false);
}

this.handleEditRoute = async (event, context) => {
Expand All @@ -237,10 +237,7 @@ function(i18n, accUtils, ko, ArrayDataProvider, BufferingDataProvider, project,
const index = context.item.index;
let route = this.routes.observable()[index];

dialogHelper.openBusyDialog(this.labelMapper('route-get-services-title',
{ namespace: this.project.k8sDomain.kubernetesNamespace.value }));
const targetServiceDetails = await getTargetServiceDetails(this.project);
dialogHelper.closeBusyDialog();
if (targetServiceDetails) {
const options = {route: route, serviceList: targetServiceDetails.serviceList};
dialogHelper.promptDialog('route-edit-dialog', options).then(result => {
Expand Down
32 changes: 29 additions & 3 deletions webui/src/js/viewModels/route-edit-dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
let options = [];
if (this.serviceList[svcName]) {
for (const port of this.serviceList[svcName].ports) {
options.push( { id : port.port, value: port.port, text: port.port} );
options.push( { id : port.port, value: port.port, text: port.port.toString()} );
}
}

Expand Down Expand Up @@ -154,7 +154,6 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
});

this.getTargetPortPlaceholder = ko.computed(() => {
console.log('targetSvcPorts is a ' + typeof(this.targetSvcPorts));
const ports = this.targetSvcPorts();
if (Array.isArray(ports) && ports.length > 0) {
return this.labelMapper('route-targetport-placeholder');
Expand Down Expand Up @@ -204,8 +203,35 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
};

this.targetSvcNameChanged = (event) => {
const newServiceName = event.detail.value;
this.targetSvcPorts.removeAll();
this.buildTargetSvcPorts(event.detail.value).forEach(port => this.targetSvcPorts.push(port));
this.buildTargetSvcPorts(newServiceName).forEach(port => this.targetSvcPorts.push(port));

// If the new service name is a known service and the current target port value is not
// associated with the service, clear the target port selection.
//
let foundService = false;
for (const name in this.serviceList) {
if (name === newServiceName) {
foundService = true;
break;
}
}
if (foundService) {
const currentPortValue = this['targetPort'].observable();
if (currentPortValue !== DEFAULT_ROUTE_PORT) {
let foundPort = false;
for (const port of this.targetSvcPorts()) {
if (currentPortValue === port.text) {
foundPort = true;
break;
}
}
if (!foundPort) {
this['targetPort'].observable(DEFAULT_ROUTE_PORT);
}
}
}
};

this.okInput = () => {
Expand Down