mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
feat(k8s/ingresses): add more granularity to ingress configuration (#4220)
* feat(k8s/configure): separate ingress class name and ingress class type * feat(k8s/resource-pool): ability to add custom annotations to ingress classes on RP create/edit * feat(k8s/ingresses): remove 'allow users to use ingress' switch * feat(k8s/configure): minor UI update * feat(k8s/resource-pool): minor UI update * feat(k8s/application): update ingress route form validation * refactor(k8s/resource-pool): remove console.log statement * feat(k8s/resource-pool): update ingress annotation placeholders * feat(k8s/configure): add pattern form validation on ingress class * fix(k8s/resource-pool): automatically associate ingress class to ingress * fix(k8s/resource-pool): fix invalid ingress when updating a resource pool * fix(k8s/resource-pool): update ingress rewrite target annotation value * feat(k8s/application): ingress form validation * fix(k8s/application): squash ingress rules with empty host inside a single one * feat(k8s/resource-pool): ingress host validation * fix(k8s/resource-pool): rewrite rewrite option and only display it for ingress of type nginx * feat(k8s/application): do not expose ingress applications over node port * feat(k8s/application): add specific notice for ingress Co-authored-by: Anthony Lapenna <lapenna.anthony@gmail.com>
This commit is contained in:
parent
68851aada4
commit
d850e18ff0
21 changed files with 699 additions and 220 deletions
|
@ -3,11 +3,15 @@ import _ from 'lodash-es';
|
|||
import filesizeParser from 'filesize-parser';
|
||||
import { KubernetesResourceQuotaDefaults } from 'Kubernetes/models/resource-quota/models';
|
||||
import KubernetesResourceReservationHelper from 'Kubernetes/helpers/resourceReservationHelper';
|
||||
import { KubernetesResourcePoolFormValues, KubernetesResourcePoolIngressClassFormValue } from 'Kubernetes/models/resource-pool/formValues';
|
||||
import { KubernetesResourcePoolFormValues, KubernetesResourcePoolIngressClassAnnotationFormValue } from 'Kubernetes/models/resource-pool/formValues';
|
||||
import { KubernetesIngressConverter } from 'Kubernetes/ingress/converter';
|
||||
import KubernetesFormValidationHelper from 'Kubernetes/helpers/formValidationHelper';
|
||||
import { KubernetesFormValueDuplicate } from 'Kubernetes/models/application/formValues';
|
||||
|
||||
class KubernetesCreateResourcePoolController {
|
||||
/* #region CONSTRUCTOR */
|
||||
/* @ngInject */
|
||||
constructor($async, $state, Notifications, KubernetesNodeService, KubernetesResourcePoolService, Authentication, EndpointProvider) {
|
||||
constructor($async, $state, Notifications, KubernetesNodeService, KubernetesResourcePoolService, KubernetesIngressService, Authentication, EndpointProvider) {
|
||||
this.$async = $async;
|
||||
this.$state = $state;
|
||||
this.Notifications = Notifications;
|
||||
|
@ -16,14 +20,42 @@ class KubernetesCreateResourcePoolController {
|
|||
|
||||
this.KubernetesNodeService = KubernetesNodeService;
|
||||
this.KubernetesResourcePoolService = KubernetesResourcePoolService;
|
||||
this.KubernetesIngressService = KubernetesIngressService;
|
||||
|
||||
this.onInit = this.onInit.bind(this);
|
||||
this.createResourcePoolAsync = this.createResourcePoolAsync.bind(this);
|
||||
this.getResourcePoolsAsync = this.getResourcePoolsAsync.bind(this);
|
||||
this.getIngressesAsync = this.getIngressesAsync.bind(this);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
onChangeIngressHostname() {
|
||||
const state = this.state.duplicates.ingressHosts;
|
||||
|
||||
const hosts = _.map(this.formValues.IngressClasses, 'Host');
|
||||
const allHosts = _.map(this.allIngresses, 'Host');
|
||||
const duplicates = KubernetesFormValidationHelper.getDuplicates(hosts);
|
||||
_.forEach(hosts, (host, idx) => {
|
||||
if (_.includes(allHosts, host) && host !== undefined) {
|
||||
duplicates[idx] = host;
|
||||
}
|
||||
});
|
||||
state.refs = duplicates;
|
||||
state.hasDuplicates = Object.keys(duplicates).length > 0;
|
||||
}
|
||||
|
||||
isValid() {
|
||||
return !this.state.isAlreadyExist;
|
||||
/* #region ANNOTATIONS MANAGEMENT */
|
||||
addAnnotation(ingressClass) {
|
||||
ingressClass.Annotations.push(new KubernetesResourcePoolIngressClassAnnotationFormValue());
|
||||
}
|
||||
|
||||
removeAnnotation(ingressClass, index) {
|
||||
ingressClass.Annotations.splice(index, 1);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
isCreateButtonDisabled() {
|
||||
return this.state.actionInProgress || (this.formValues.HasQuota && !this.isQuotaValid()) || this.state.isAlreadyExist || this.state.duplicates.ingressHosts.hasDuplicates;
|
||||
}
|
||||
|
||||
onChangeName() {
|
||||
|
@ -50,6 +82,7 @@ class KubernetesCreateResourcePoolController {
|
|||
}
|
||||
}
|
||||
|
||||
/* #region CREATE RESOURCE POOL */
|
||||
async createResourcePoolAsync() {
|
||||
this.state.actionInProgress = true;
|
||||
try {
|
||||
|
@ -69,7 +102,26 @@ class KubernetesCreateResourcePoolController {
|
|||
createResourcePool() {
|
||||
return this.$async(this.createResourcePoolAsync);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
/* #region GET INGRESSES */
|
||||
async getIngressesAsync() {
|
||||
this.state.ingressesLoading = true;
|
||||
try {
|
||||
this.allIngresses = await this.KubernetesIngressService.get();
|
||||
} catch (err) {
|
||||
this.Notifications.error('Failure', err, 'Unable to retrieve ingresses.');
|
||||
} finally {
|
||||
this.state.ingressesLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
getIngresses() {
|
||||
return this.$async(this.getIngressesAsync);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
/* #region GET RESOURCE POOLS */
|
||||
async getResourcePoolsAsync() {
|
||||
try {
|
||||
this.resourcePools = await this.KubernetesResourcePoolService.get();
|
||||
|
@ -81,7 +133,9 @@ class KubernetesCreateResourcePoolController {
|
|||
getResourcePools() {
|
||||
return this.$async(this.getResourcePoolsAsync);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
/* #region ON INIT */
|
||||
async onInit() {
|
||||
try {
|
||||
const endpoint = this.EndpointProvider.currentEndpoint();
|
||||
|
@ -95,7 +149,10 @@ class KubernetesCreateResourcePoolController {
|
|||
sliderMaxCpu: 0,
|
||||
viewReady: false,
|
||||
isAlreadyExist: false,
|
||||
canUseIngress: endpoint.Kubernetes.Configuration.UseIngress,
|
||||
canUseIngress: endpoint.Kubernetes.Configuration.IngressClasses.length,
|
||||
duplicates: {
|
||||
ingressHosts: new KubernetesFormValueDuplicate(),
|
||||
},
|
||||
};
|
||||
|
||||
const nodes = await this.KubernetesNodeService.get();
|
||||
|
@ -107,8 +164,9 @@ class KubernetesCreateResourcePoolController {
|
|||
this.state.sliderMaxMemory = KubernetesResourceReservationHelper.megaBytesValue(this.state.sliderMaxMemory);
|
||||
await this.getResourcePools();
|
||||
if (this.state.canUseIngress) {
|
||||
await this.getIngresses();
|
||||
const ingressClasses = endpoint.Kubernetes.Configuration.IngressClasses;
|
||||
this.formValues.IngressClasses = _.map(ingressClasses, (item) => new KubernetesResourcePoolIngressClassFormValue(item));
|
||||
this.formValues.IngressClasses = KubernetesIngressConverter.ingressClassesToFormValues(ingressClasses);
|
||||
}
|
||||
} catch (err) {
|
||||
this.Notifications.error('Failure', err, 'Unable to load view data');
|
||||
|
@ -120,6 +178,7 @@ class KubernetesCreateResourcePoolController {
|
|||
$onInit() {
|
||||
return this.$async(this.onInit);
|
||||
}
|
||||
/* #endregion */
|
||||
}
|
||||
|
||||
export default KubernetesCreateResourcePoolController;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue