From b6fbf8eecce72c167d85fc4222e5f859d5ca495d Mon Sep 17 00:00:00 2001 From: LP B Date: Tue, 30 Nov 2021 05:14:52 +0100 Subject: [PATCH] fix(k8s/ingress): ensure new ports are only added to ingress only if app is published via ingress (#6153) * fix(k8s/ingress): ensure new ports are only added to ingress only if app is published via ingress * refactor(k8s/ingress): removed deleted ports of ingress in a single pass --- app/kubernetes/ingress/converter.js | 36 ++++++++++++------- .../models/application/formValues.js | 1 + app/kubernetes/services/applicationService.js | 8 +++-- .../create/createApplication.html | 8 ++++- .../create/createApplicationController.js | 25 ++++++------- tsconfig.json | 7 +++- 6 files changed, 53 insertions(+), 32 deletions(-) diff --git a/app/kubernetes/ingress/converter.js b/app/kubernetes/ingress/converter.js index e3ac6112d..efbb6aeb7 100644 --- a/app/kubernetes/ingress/converter.js +++ b/app/kubernetes/ingress/converter.js @@ -7,6 +7,7 @@ import { KubernetesResourcePoolIngressClassFormValue, KubernetesResourcePoolIngressClassHostFormValue, } from 'Kubernetes/models/resource-pool/formValues'; +import { KubernetesApplicationPublishingTypes } from '../models/application/models'; import { KubernetesIngress, KubernetesIngressRule } from './models'; import { KubernetesIngressCreatePayload, KubernetesIngressRuleCreatePayload, KubernetesIngressRulePathCreatePayload } from './payloads'; import { KubernetesIngressClassAnnotation, KubernetesIngressClassRewriteTargetAnnotations } from './constants'; @@ -45,23 +46,31 @@ export class KubernetesIngressConverter { return res; } + /** + * Converts Application Form Value (from Create Application View) to Ingresses + * @param {KubernetesApplicationFormValues} formValues + * @param {string} serviceName + * @returns {KubernetesIngressRule[]} + */ static applicationFormValuesToIngresses(formValues, serviceName) { + const isPublishingToIngress = formValues.PublishingType === KubernetesApplicationPublishingTypes.INGRESS; const ingresses = angular.copy(formValues.OriginalIngresses); _.forEach(formValues.PublishedPorts, (p) => { const ingress = _.find(ingresses, { Name: p.IngressName }); - if (ingress && p.NeedsDeletion) { - const path = _.find(ingress.Paths, { Port: p.ContainerPort, ServiceName: serviceName, Path: p.IngressRoute }); - _.remove(ingress.Paths, path); - } else if (ingress && p.IsNew) { - const rule = new KubernetesIngressRule(); - rule.IngressName = ingress.Name; - rule.ServiceName = serviceName; - rule.Port = p.ContainerPort; - if (p.IngressRoute) { - rule.Path = _.startsWith(p.IngressRoute, '/') ? p.IngressRoute : '/' + p.IngressRoute; + if (ingress) { + if (p.NeedsDeletion) { + _.remove(ingress.Paths, (path) => path.Port === p.ContainerPort && path.ServiceName === serviceName && path.Path === p.IngressRoute); + } else if (isPublishingToIngress && p.IsNew) { + const rule = new KubernetesIngressRule(); + rule.IngressName = ingress.Name; + rule.ServiceName = serviceName; + rule.Port = p.ContainerPort; + if (p.IngressRoute) { + rule.Path = _.startsWith(p.IngressRoute, '/') ? p.IngressRoute : '/' + p.IngressRoute; + } + rule.Host = p.IngressHost; + ingress.Paths.push(rule); } - rule.Host = p.IngressHost; - ingress.Paths.push(rule); } }); return ingresses; @@ -69,7 +78,8 @@ export class KubernetesIngressConverter { /** * - * @param {KubernetesResourcePoolIngressClassFormValue} formValues + * @param {KubernetesResourcePoolIngressClassFormValue[]} formValues + * @returns {KubernetesIngress} Ingress */ static resourcePoolIngressClassFormValueToIngress(formValues) { const res = new KubernetesIngress(); diff --git a/app/kubernetes/models/application/formValues.js b/app/kubernetes/models/application/formValues.js index e33e52630..78c1b055a 100644 --- a/app/kubernetes/models/application/formValues.js +++ b/app/kubernetes/models/application/formValues.js @@ -27,6 +27,7 @@ export function KubernetesApplicationFormValues() { this.PlacementType = KubernetesApplicationPlacementTypes.PREFERRED; this.Placements = []; // KubernetesApplicationPlacementFormValue lis; this.OriginalIngresses = undefined; + this.IsPublishingService = false; } export const KubernetesApplicationConfigurationFormValueOverridenKeyTypes = Object.freeze({ diff --git a/app/kubernetes/services/applicationService.js b/app/kubernetes/services/applicationService.js index fa80b8e85..0fb529f02 100644 --- a/app/kubernetes/services/applicationService.js +++ b/app/kubernetes/services/applicationService.js @@ -346,10 +346,14 @@ class KubernetesApplicationService { await apiService.patch(oldAppPayload, newAppPayload); } - // accept either formValues or applications as parameters - // depending on partial value + // accept either formValues or applications as parameters depending on partial value // true = KubernetesApplication // false = KubernetesApplicationFormValues + // + // e.g. signatures are + // + // patch(oldValues: KubernetesApplication, newValues: KubernetesApplication, partial: (undefined | false)): Promise + // patch(oldValues: KubernetesApplicationFormValues, newValues: KubernetesApplicationFormValues, partial: true): Promise patch(oldValues, newValues, partial = false) { if (partial) { return this.$async(this.patchPartialAsync, oldValues, newValues); diff --git a/app/kubernetes/views/applications/create/createApplication.html b/app/kubernetes/views/applications/create/createApplication.html index 08f7831d0..912a583de 100644 --- a/app/kubernetes/views/applications/create/createApplication.html +++ b/app/kubernetes/views/applications/create/createApplication.html @@ -1246,7 +1246,13 @@ Enable publishing for this application diff --git a/app/kubernetes/views/applications/create/createApplicationController.js b/app/kubernetes/views/applications/create/createApplicationController.js index 8ed872c8d..9ba03ce19 100644 --- a/app/kubernetes/views/applications/create/createApplicationController.js +++ b/app/kubernetes/views/applications/create/createApplicationController.js @@ -144,8 +144,6 @@ class KubernetesCreateApplicationController { this.setPullImageValidity = this.setPullImageValidity.bind(this); this.onChangeFileContent = this.onChangeFileContent.bind(this); this.onServicePublishChange = this.onServicePublishChange.bind(this); - - this.$scope.$watch(() => this.formValues.IsPublishingService, this.onServicePublishChange); } /* #endregion */ @@ -426,34 +424,31 @@ class KubernetesCreateApplicationController { /* #endregion */ + /* #region PUBLISHED PORTS UI MANAGEMENT */ onServicePublishChange() { - // service creation - if (this.formValues.PublishedPorts.length === 0) { - if (this.formValues.IsPublishingService) { - // toggle enabled - this.addPublishedPort(); - } + // enable publishing with no previous ports exposed + if (this.formValues.IsPublishingService && !this.formValues.PublishedPorts.length) { + this.addPublishedPort(); return; } // service update if (this.formValues.IsPublishingService) { - // toggle enabled this.formValues.PublishedPorts.forEach((port) => (port.NeedsDeletion = false)); } else { - // toggle disabled - // all new ports need to be deleted, existing ports need to be marked as needing deletion + // delete new ports, mark old ports to be deleted this.formValues.PublishedPorts = this.formValues.PublishedPorts.filter((port) => !port.IsNew).map((port) => ({ ...port, NeedsDeletion: true })); } } - /* #region PUBLISHED PORTS UI MANAGEMENT */ addPublishedPort() { const p = new KubernetesApplicationPublishedPortFormValue(); const ingresses = this.ingresses; - p.IngressName = ingresses && ingresses.length ? ingresses[0].Name : undefined; - p.IngressHost = ingresses && ingresses.length ? ingresses[0].Hosts[0] : undefined; - p.IngressHosts = ingresses && ingresses.length ? ingresses[0].Hosts : undefined; + if (this.formValues.PublishingType === KubernetesApplicationPublishingTypes.INGRESS) { + p.IngressName = ingresses && ingresses.length ? ingresses[0].Name : undefined; + p.IngressHost = ingresses && ingresses.length ? ingresses[0].Hosts[0] : undefined; + p.IngressHosts = ingresses && ingresses.length ? ingresses[0].Hosts : undefined; + } if (this.formValues.PublishedPorts.length) { p.Protocol = this.formValues.PublishedPorts[0].Protocol; } diff --git a/tsconfig.json b/tsconfig.json index 2fd3a3530..a5f6838b2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,7 +28,12 @@ "lib": ["dom", "dom.iterable", "esnext"], "paths": { // paths relative to the baseUrl - "@/*": ["./*", "../app/*"] + "@/*": ["./*", "../app/*"], + "Agent/*": ["agent/*"], + "Azure/*": ["azure/*"], + "Docker/*": ["docker/*"], + "Kubernetes/*": ["kubernetes/*"], + "Portainer/*": ["portainer/*"], } }, "exclude": ["api", "build", "dist", "distribution", "node_modules", "test", "webpack"],