mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +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
|
@ -1329,10 +1329,10 @@
|
|||
class="form-control"
|
||||
name="ingress_route_{{ $index }}"
|
||||
ng-model="publishedPort.IngressRoute"
|
||||
placeholder="foo"
|
||||
placeholder="route"
|
||||
ng-required="!publishedPort.NeedsDeletion"
|
||||
ng-change="ctrl.onChangePortMappingIngressRoute()"
|
||||
ng-pattern="/^\/?([a-zA-Z0-9]+[a-zA-Z0-9-/_]*[a-zA-Z0-9]|[a-zA-Z0-9]+)$/"
|
||||
ng-pattern="/^(\/?[a-zA-Z0-9]+([a-zA-Z0-9-/_]*[a-zA-Z0-9])?|[a-zA-Z0-9]+)|(\/){1}$/"
|
||||
ng-disabled="ctrl.disableLoadBalancerEdit() || ctrl.isEditAndNotNewPublishedPort($index)"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
KubernetesApplicationPersistedFolderFormValue,
|
||||
KubernetesApplicationPublishedPortFormValue,
|
||||
KubernetesApplicationPlacementFormValue,
|
||||
KubernetesApplicationFormValidationDuplicate,
|
||||
KubernetesFormValueDuplicate,
|
||||
} from 'Kubernetes/models/application/formValues';
|
||||
import KubernetesFormValidationHelper from 'Kubernetes/helpers/formValidationHelper';
|
||||
import KubernetesApplicationConverter from 'Kubernetes/converters/application';
|
||||
|
@ -367,14 +367,16 @@ class KubernetesCreateApplicationController {
|
|||
const publishedPort = this.formValues.PublishedPorts[index];
|
||||
const ingress = _.find(this.filteredIngresses, { Name: publishedPort.IngressName });
|
||||
publishedPort.IngressHost = ingress.Host;
|
||||
this.onChangePublishedPorts();
|
||||
}
|
||||
|
||||
onChangePortMappingIngressRoute() {
|
||||
const state = this.state.duplicates.publishedPorts.ingressRoutes;
|
||||
|
||||
if (this.formValues.PublishingType === KubernetesApplicationPublishingTypes.INGRESS) {
|
||||
const newRoutes = _.map(this.formValues.PublishedPorts, (p) => (p.IsNew ? p.IngressRoute : undefined));
|
||||
const toDelRoutes = _.map(this.formValues.PublishedPorts, (p) => (p.NeedsDeletion ? p.IngressRoute : undefined));
|
||||
const allRoutes = _.flatMapDeep(this.ingresses, (c) => _.map(c.Paths, 'Path'));
|
||||
const newRoutes = _.map(this.formValues.PublishedPorts, (p) => (p.IsNew && p.IngressRoute ? (p.IngressHost || p.IngressName) + p.IngressRoute : undefined));
|
||||
const toDelRoutes = _.map(this.formValues.PublishedPorts, (p) => (p.NeedsDeletion && p.IngressRoute ? (p.IngressHost || p.IngressName) + p.IngressRoute : undefined));
|
||||
const allRoutes = _.flatMap(this.ingresses, (i) => _.map(i.Paths, (p) => (p.Host || i.Name) + p.Path));
|
||||
const duplicates = KubernetesFormValidationHelper.getDuplicates(newRoutes);
|
||||
_.forEach(newRoutes, (route, idx) => {
|
||||
if (_.includes(allRoutes, route) && !_.includes(toDelRoutes, route)) {
|
||||
|
@ -814,7 +816,6 @@ class KubernetesCreateApplicationController {
|
|||
actionInProgress: false,
|
||||
useLoadBalancer: false,
|
||||
useServerMetrics: false,
|
||||
canUseIngress: false,
|
||||
sliders: {
|
||||
cpu: {
|
||||
min: 0,
|
||||
|
@ -834,17 +835,17 @@ class KubernetesCreateApplicationController {
|
|||
availableSizeUnits: ['MB', 'GB', 'TB'],
|
||||
alreadyExists: false,
|
||||
duplicates: {
|
||||
environmentVariables: new KubernetesApplicationFormValidationDuplicate(),
|
||||
persistedFolders: new KubernetesApplicationFormValidationDuplicate(),
|
||||
configurationPaths: new KubernetesApplicationFormValidationDuplicate(),
|
||||
existingVolumes: new KubernetesApplicationFormValidationDuplicate(),
|
||||
environmentVariables: new KubernetesFormValueDuplicate(),
|
||||
persistedFolders: new KubernetesFormValueDuplicate(),
|
||||
configurationPaths: new KubernetesFormValueDuplicate(),
|
||||
existingVolumes: new KubernetesFormValueDuplicate(),
|
||||
publishedPorts: {
|
||||
containerPorts: new KubernetesApplicationFormValidationDuplicate(),
|
||||
nodePorts: new KubernetesApplicationFormValidationDuplicate(),
|
||||
ingressRoutes: new KubernetesApplicationFormValidationDuplicate(),
|
||||
loadBalancerPorts: new KubernetesApplicationFormValidationDuplicate(),
|
||||
containerPorts: new KubernetesFormValueDuplicate(),
|
||||
nodePorts: new KubernetesFormValueDuplicate(),
|
||||
ingressRoutes: new KubernetesFormValueDuplicate(),
|
||||
loadBalancerPorts: new KubernetesFormValueDuplicate(),
|
||||
},
|
||||
placements: new KubernetesApplicationFormValidationDuplicate(),
|
||||
placements: new KubernetesFormValueDuplicate(),
|
||||
},
|
||||
isEdit: false,
|
||||
params: {
|
||||
|
|
|
@ -247,7 +247,7 @@
|
|||
</div>
|
||||
|
||||
<!-- internal notice -->
|
||||
<div ng-if="ctrl.application.ServiceType === ctrl.KubernetesServiceTypes.CLUSTER_IP">
|
||||
<div ng-if="ctrl.application.ServiceType === ctrl.KubernetesServiceTypes.CLUSTER_IP && !ctrl.state.useIngress">
|
||||
<div class="small text-muted">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||
This application is only available for internal usage inside the cluster via the application name <code>{{ ctrl.application.ServiceName }}</code>
|
||||
|
@ -261,6 +261,24 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ingress notice -->
|
||||
<div ng-if="ctrl.application.ServiceType === ctrl.KubernetesServiceTypes.CLUSTER_IP && ctrl.state.useIngress">
|
||||
<div class="small text-muted">
|
||||
<p>
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||
This application is available for internal usage inside the cluster via the application name <code>{{ ctrl.application.ServiceName }}</code>
|
||||
<span class="btn btn-primary btn-xs" ng-click="ctrl.copyApplicationName()"><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy</span>
|
||||
<span id="copyNotificationApplicationName" style="margin-left: 7px; display: none; color: #23ae89;" class="small"
|
||||
><i class="fa fa-check" aria-hidden="true"></i> copied</span
|
||||
>
|
||||
</p>
|
||||
<p>It can also be accessed via specific HTTP route(s).</p>
|
||||
</div>
|
||||
<div class="small text-muted" style="margin-top: 2px;">
|
||||
<p>Refer to the below port configuration to access the application.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- table -->
|
||||
<div style="margin-top: 15px;">
|
||||
<table class="table">
|
||||
|
|
|
@ -295,6 +295,10 @@ class KubernetesApplicationController {
|
|||
this.formValues.SelectedRevision = _.find(this.application.Revisions, { revision: this.application.CurrentRevision.revision });
|
||||
}
|
||||
|
||||
this.state.useIngress = _.find(application.PublishedPorts, (p) => {
|
||||
return this.portHasIngressRules(p);
|
||||
});
|
||||
|
||||
this.placements = computePlacements(nodes, this.application);
|
||||
} catch (err) {
|
||||
this.Notifications.error('Failure', err, 'Unable to retrieve application details');
|
||||
|
@ -322,6 +326,7 @@ class KubernetesApplicationController {
|
|||
},
|
||||
eventWarningCount: 0,
|
||||
expandedNote: false,
|
||||
useIngress: false,
|
||||
};
|
||||
|
||||
this.state.activeTab = this.LocalStorage.getActiveTab('application');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue