feat(k8s/application): add placement constraints validation (#4214)
* feat(k8s/application): add constraints validation * feat(k8s/application): minor UI update Co-authored-by: Anthony Lapenna <lapenna.anthony@gmail.com>pull/4217/head
parent
36bf9c24b9
commit
8d6f6e306a
|
@ -150,3 +150,10 @@ export class KubernetesApplicationAutoScalerFormValue {
|
|||
Object.assign(this, JSON.parse(JSON.stringify(_KubernetesApplicationAutoScalerFormValue)));
|
||||
}
|
||||
}
|
||||
|
||||
export function KubernetesApplicationFormValidationDuplicate() {
|
||||
return {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -944,17 +944,17 @@
|
|||
|
||||
<div class="col-sm-12 small text-muted" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px;">
|
||||
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||
Deploy this application on nodes that respect <b>ALL</b> of the following placement rules.
|
||||
Deploy this application on nodes that respect <b>ALL</b> of the following placement rules. Placement rules are based on node labels.
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 form-inline" style="margin-top: 10px;">
|
||||
<div ng-repeat="placement in ctrl.formValues.Placements" style="margin-top: 2px;">
|
||||
<div ng-repeat-start="placement in ctrl.formValues.Placements" style="margin-top: 2px;">
|
||||
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
||||
<select
|
||||
class="form-control"
|
||||
ng-model="placement.Label"
|
||||
ng-options="label as (label.Key | kubernetesNodeLabelHumanReadbleText) for label in ctrl.nodesLabels"
|
||||
ng-change="ctrl.onPlacementLabelChange($index)"
|
||||
ng-change="ctrl.onChangePlacementLabel($index)"
|
||||
ng-disabled="ctrl.isEditAndNotNewPlacement($index)"
|
||||
>
|
||||
</select>
|
||||
|
@ -978,6 +978,15 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-repeat-end ng-show="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<div class="col-sm-5 input-group">
|
||||
<div class="small text-warning" style="margin-top: 5px;" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<p ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This label is already defined.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="ctrl.showPlacementPolicySection()">
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
KubernetesApplicationPersistedFolderFormValue,
|
||||
KubernetesApplicationPublishedPortFormValue,
|
||||
KubernetesApplicationPlacementFormValue,
|
||||
KubernetesApplicationFormValidationDuplicate,
|
||||
} from 'Kubernetes/models/application/formValues';
|
||||
import KubernetesFormValidationHelper from 'Kubernetes/helpers/formValidationHelper';
|
||||
import KubernetesApplicationConverter from 'Kubernetes/converters/application';
|
||||
|
@ -259,10 +260,12 @@ class KubernetesCreateApplicationController {
|
|||
placement.Label = label;
|
||||
placement.Value = label.Values[0];
|
||||
this.formValues.Placements.push(placement);
|
||||
this.onChangePlacement();
|
||||
}
|
||||
|
||||
restorePlacement(index) {
|
||||
this.formValues.Placements[index].NeedsDeletion = false;
|
||||
this.onChangePlacement();
|
||||
}
|
||||
|
||||
removePlacement(index) {
|
||||
|
@ -271,10 +274,25 @@ class KubernetesCreateApplicationController {
|
|||
} else {
|
||||
this.formValues.Placements.splice(index, 1);
|
||||
}
|
||||
this.onChangePlacement();
|
||||
}
|
||||
|
||||
onPlacementLabelChange(index) {
|
||||
// call all validation functions when a placement is added/removed/restored
|
||||
onChangePlacement() {
|
||||
this.onChangePlacementLabelValidate();
|
||||
}
|
||||
|
||||
onChangePlacementLabel(index) {
|
||||
this.formValues.Placements[index].Value = this.formValues.Placements[index].Label.Values[0];
|
||||
this.onChangePlacementLabelValidate();
|
||||
}
|
||||
|
||||
onChangePlacementLabelValidate() {
|
||||
const state = this.state.duplicates.placements;
|
||||
const source = _.map(this.formValues.Placements, (p) => (p.NeedsDeletion ? undefined : p.Label.Key));
|
||||
const duplicates = KubernetesFormValidationHelper.getDuplicates(source);
|
||||
state.refs = duplicates;
|
||||
state.hasDuplicates = Object.keys(duplicates).length > 0;
|
||||
}
|
||||
|
||||
/* #endregion */
|
||||
|
@ -816,40 +834,17 @@ class KubernetesCreateApplicationController {
|
|||
availableSizeUnits: ['MB', 'GB', 'TB'],
|
||||
alreadyExists: false,
|
||||
duplicates: {
|
||||
environmentVariables: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
persistedFolders: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
configurationPaths: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
existingVolumes: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
environmentVariables: new KubernetesApplicationFormValidationDuplicate(),
|
||||
persistedFolders: new KubernetesApplicationFormValidationDuplicate(),
|
||||
configurationPaths: new KubernetesApplicationFormValidationDuplicate(),
|
||||
existingVolumes: new KubernetesApplicationFormValidationDuplicate(),
|
||||
publishedPorts: {
|
||||
containerPorts: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
nodePorts: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
ingressRoutes: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
loadBalancerPorts: {
|
||||
refs: {},
|
||||
hasDuplicates: false,
|
||||
},
|
||||
containerPorts: new KubernetesApplicationFormValidationDuplicate(),
|
||||
nodePorts: new KubernetesApplicationFormValidationDuplicate(),
|
||||
ingressRoutes: new KubernetesApplicationFormValidationDuplicate(),
|
||||
loadBalancerPorts: new KubernetesApplicationFormValidationDuplicate(),
|
||||
},
|
||||
placements: new KubernetesApplicationFormValidationDuplicate(),
|
||||
},
|
||||
isEdit: false,
|
||||
params: {
|
||||
|
|
Loading…
Reference in New Issue