mirror of https://github.com/portainer/portainer
fix(ingress): fix-multiple-route-on-same-ingress EE-2597 (#6609)
* fix multiple route for same ingress & improvement for multiple ingress controllerpull/6673/head
parent
98d8cd99fb
commit
9aeedf1bfa
|
@ -89,17 +89,39 @@ export class KubernetesIngressConverter {
|
||||||
return ingresses;
|
return ingresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
static deleteIngressByServiceName(formValues, service) {
|
static removeIngressesPaths(ingresses, services) {
|
||||||
const ingresses = angular.copy(formValues.OriginalIngresses);
|
const originalIngress = angular.copy(ingresses);
|
||||||
ingresses.forEach((ingress) => {
|
originalIngress.forEach((ingress) => {
|
||||||
const path = _.find(ingress.Paths, { ServiceName: service.Name });
|
services.forEach((service) => {
|
||||||
if (path) {
|
_.remove(ingress.Paths, { ServiceName: service.Name });
|
||||||
_.remove(ingress.Paths, path);
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return ingresses;
|
return originalIngress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static generateNewIngresses(ingresses, services) {
|
||||||
|
const originalIngresses = angular.copy(ingresses);
|
||||||
|
services
|
||||||
|
.filter((s) => s.Ingress)
|
||||||
|
.forEach((service) => {
|
||||||
|
if (service.Ports.length !== 0) {
|
||||||
|
const matchedIngress = _.find(originalIngresses, { Name: service.Ports[0].ingress.IngressName });
|
||||||
|
if (matchedIngress) {
|
||||||
|
const rule = new KubernetesIngressRule();
|
||||||
|
rule.ServiceName = service.Name;
|
||||||
|
rule.IngressName = service.Ports[0].ingress.IngressName;
|
||||||
|
rule.Host = service.Ports[0].ingress.Host;
|
||||||
|
rule.Path = _.startsWith(service.Ports[0].ingress.Path, '/') ? service.Ports[0].ingress.Path : '/' + service.Ports[0].ingress.Path;
|
||||||
|
rule.Port = service.Ports[0].port;
|
||||||
|
|
||||||
|
matchedIngress.Paths.push(rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return originalIngresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need this function for [ resource summary ] controller
|
||||||
static newApplicationFormValuesToIngresses(formValues, serviceName, servicePorts) {
|
static newApplicationFormValuesToIngresses(formValues, serviceName, servicePorts) {
|
||||||
const ingresses = angular.copy(formValues.OriginalIngresses);
|
const ingresses = angular.copy(formValues.OriginalIngresses);
|
||||||
servicePorts.forEach((port) => {
|
servicePorts.forEach((port) => {
|
||||||
|
@ -118,27 +140,6 @@ export class KubernetesIngressConverter {
|
||||||
return ingresses;
|
return ingresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
static editingFormValuesToIngresses(formValues, serviceName, servicePorts) {
|
|
||||||
const ingresses = angular.copy(formValues.OriginalIngresses);
|
|
||||||
servicePorts.forEach((port) => {
|
|
||||||
const ingressMatched = _.find(ingresses, { Name: port.ingress.IngressName });
|
|
||||||
if (ingressMatched) {
|
|
||||||
const pathMatched = _.find(ingressMatched.Paths, { ServiceName: serviceName });
|
|
||||||
_.remove(ingressMatched.Paths, pathMatched);
|
|
||||||
|
|
||||||
const rule = new KubernetesIngressRule();
|
|
||||||
rule.ServiceName = serviceName;
|
|
||||||
rule.IngressName = port.ingress.IngressName;
|
|
||||||
rule.Host = port.ingress.Host;
|
|
||||||
rule.Path = _.startsWith(port.ingress.Path, '/') ? port.ingress.Path : '/' + port.ingress.Path;
|
|
||||||
rule.Port = port.port;
|
|
||||||
|
|
||||||
ingressMatched.Paths.push(rule);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return ingresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {KubernetesResourcePoolIngressClassFormValue[]} formValues
|
* @param {KubernetesResourcePoolIngressClassFormValue[]} formValues
|
||||||
|
|
|
@ -225,12 +225,15 @@ class KubernetesApplicationService {
|
||||||
|
|
||||||
if (services) {
|
if (services) {
|
||||||
services.forEach(async (service) => {
|
services.forEach(async (service) => {
|
||||||
this.KubernetesServiceService.create(service);
|
await this.KubernetesServiceService.create(service);
|
||||||
if (service.Ingress) {
|
|
||||||
const ingresses = KubernetesIngressConverter.newApplicationFormValuesToIngresses(formValues, service.Name, service.Ports);
|
|
||||||
await Promise.all(this._generateIngressPatchPromises(formValues.OriginalIngresses, ingresses));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Generate all ingresses from current form by passing services object
|
||||||
|
const ingresses = KubernetesIngressConverter.generateNewIngresses(formValues.OriginalIngresses, services);
|
||||||
|
if (ingresses) {
|
||||||
|
//Update original ingress with current ingress
|
||||||
|
await Promise.all(this._generateIngressPatchPromises(formValues.OriginalIngresses, ingresses));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service) {
|
if (service) {
|
||||||
|
@ -310,54 +313,54 @@ class KubernetesApplicationService {
|
||||||
|
|
||||||
await newApiService.patch(oldApp, newApp);
|
await newApiService.patch(oldApp, newApp);
|
||||||
|
|
||||||
|
// Create services
|
||||||
if (oldServices.length === 0 && newServices.length !== 0) {
|
if (oldServices.length === 0 && newServices.length !== 0) {
|
||||||
newServices.forEach(async (service) => {
|
newServices.forEach(async (service) => {
|
||||||
await this.KubernetesServiceService.create(service);
|
await this.KubernetesServiceService.create(service);
|
||||||
if (service.Ingress) {
|
|
||||||
const ingresses = KubernetesIngressConverter.newApplicationFormValuesToIngresses(oldFormValues, service.Name, service.Ports);
|
|
||||||
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, ingresses));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Create multiple ingress
|
||||||
|
const ingresses = KubernetesIngressConverter.generateNewIngresses(oldFormValues.OriginalIngresses, newServices);
|
||||||
|
if (ingresses) {
|
||||||
|
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, ingresses));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete services ( only called when all services been deleted )
|
||||||
if (oldServices.length !== 0 && newServices.length === 0) {
|
if (oldServices.length !== 0 && newServices.length === 0) {
|
||||||
oldServices.forEach(async (oldService) => {
|
const ingresses = KubernetesIngressConverter.removeIngressesPaths(oldFormValues.OriginalIngresses, oldServices);
|
||||||
if (oldService.Ingress) {
|
if (ingresses) {
|
||||||
const ingresses = KubernetesIngressConverter.deleteIngressByServiceName(oldFormValues, oldService);
|
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, ingresses));
|
||||||
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, ingresses));
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
await this.KubernetesServiceService.deleteAll(oldServices);
|
await this.KubernetesServiceService.deleteAll(oldServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Patch services ( Action including: Delete, Update, Create )
|
||||||
if (oldServices.length !== 0 && newServices.length !== 0) {
|
if (oldServices.length !== 0 && newServices.length !== 0) {
|
||||||
newServices.forEach(async (newService) => {
|
|
||||||
const oldServiceMatched = _.find(oldServices, { Name: newService.Name });
|
|
||||||
if (oldServiceMatched) {
|
|
||||||
await this.KubernetesServiceService.patch(oldServiceMatched, newService);
|
|
||||||
if (newService.Ingress) {
|
|
||||||
const ingresses = KubernetesIngressConverter.editingFormValuesToIngresses(oldFormValues, newService.Name, newService.Ports);
|
|
||||||
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, ingresses));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await this.KubernetesServiceService.create(newService);
|
|
||||||
if (newService.Ingress) {
|
|
||||||
const ingresses = KubernetesIngressConverter.newApplicationFormValuesToIngresses(oldFormValues, newService.Name, newService.Ports);
|
|
||||||
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, ingresses));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
oldServices.forEach(async (oldService) => {
|
oldServices.forEach(async (oldService) => {
|
||||||
const newServiceMatched = _.find(newServices, { Name: oldService.Name });
|
const newServiceMatched = _.find(newServices, { Name: oldService.Name });
|
||||||
if (!newServiceMatched) {
|
if (!newServiceMatched) {
|
||||||
await this.KubernetesServiceService.deleteSingle(oldService);
|
await this.KubernetesServiceService.deleteSingle(oldService);
|
||||||
if (oldService.Ingress) {
|
|
||||||
const ingresses = KubernetesIngressConverter.deleteIngressByServiceName(oldFormValues, oldService);
|
|
||||||
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, ingresses));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
newServices.forEach(async (newService) => {
|
||||||
|
const oldServiceMatched = _.find(oldServices, { Name: newService.Name });
|
||||||
|
if (oldServiceMatched) {
|
||||||
|
await this.KubernetesServiceService.patch(oldServiceMatched, newService);
|
||||||
|
} else {
|
||||||
|
await this.KubernetesServiceService.create(newService);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear all ingress which is related to services in this application
|
||||||
|
const clearIngress = KubernetesIngressConverter.removeIngressesPaths(oldFormValues.OriginalIngresses, oldServices);
|
||||||
|
|
||||||
|
// Generate all ingress from services in this application
|
||||||
|
const newIngress = KubernetesIngressConverter.generateNewIngresses(clearIngress, newServices);
|
||||||
|
|
||||||
|
// Compare new ingress with old ingress to get api patch
|
||||||
|
await Promise.all(this._generateIngressPatchPromises(oldFormValues.OriginalIngresses, newIngress));
|
||||||
}
|
}
|
||||||
|
|
||||||
const newKind = KubernetesHorizontalPodAutoScalerHelper.getApplicationTypeString(newApp);
|
const newKind = KubernetesHorizontalPodAutoScalerHelper.getApplicationTypeString(newApp);
|
||||||
|
|
Loading…
Reference in New Issue