mirror of https://github.com/portainer/portainer
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 passpull/6176/head
parent
69c17986d9
commit
b6fbf8eecc
|
@ -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();
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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<unknown>
|
||||
// patch(oldValues: KubernetesApplicationFormValues, newValues: KubernetesApplicationFormValues, partial: true): Promise<unknown>
|
||||
patch(oldValues, newValues, partial = false) {
|
||||
if (partial) {
|
||||
return this.$async(this.patchPartialAsync, oldValues, newValues);
|
||||
|
|
|
@ -1246,7 +1246,13 @@
|
|||
Enable publishing for this application
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;">
|
||||
<input type="checkbox" class="form-control" name="enable_port_publishing" ng-model="ctrl.formValues.IsPublishingService" />
|
||||
<input
|
||||
type="checkbox"
|
||||
class="form-control"
|
||||
name="enable_port_publishing"
|
||||
ng-model="ctrl.formValues.IsPublishingService"
|
||||
ng-change="ctrl.onServicePublishChange()"
|
||||
/>
|
||||
<i></i>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"],
|
||||
|
|
Loading…
Reference in New Issue