fix(app): remove duplicate validation messages [EE-5933] (#10967)

pull/10979/head
Ali 2024-01-17 16:30:30 +13:00 committed by GitHub
parent 93593e1379
commit a58b4f479b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 80 additions and 6 deletions

View File

@ -24,7 +24,7 @@ func (kcl *KubeClient) GetNodesLimits() (portainer.K8sNodesLimits, error) {
for _, item := range nodes.Items {
cpu := item.Status.Allocatable.Cpu().MilliValue()
memory := item.Status.Allocatable.Memory().Value()
memory := item.Status.Allocatable.Memory().Value() // bytes
nodesLimits[item.ObjectMeta.Name] = &portainer.K8sNodeLimits{
CPU: cpu,
@ -57,7 +57,7 @@ func (client *KubeClient) GetMaxResourceLimits(skipNamespace string, overCommitE
memory := int64(0)
for _, node := range nodes.Items {
limits.CPU += node.Status.Allocatable.Cpu().MilliValue()
memory += node.Status.Allocatable.Memory().Value()
memory += node.Status.Allocatable.Memory().Value() // bytes
}
limits.Memory = memory / 1000000 // B to MB

View File

@ -285,7 +285,7 @@
namespace-has-quota="ctrl.state.resourcePoolHasQuota"
max-memory-limit="ctrl.state.sliders.memory.max"
max-cpu-limit="ctrl.state.sliders.cpu.max"
validation-data="{maxMemoryLimit: ctrl.state.sliders.memory.max, maxCpuLimit: ctrl.state.sliders.cpu.max, isEnvironmentAdmin: ctrl.isAdmin}"
validation-data="{maxMemoryLimit: ctrl.state.sliders.memory.max, maxCpuLimit: ctrl.state.sliders.cpu.max, isEnvironmentAdmin: ctrl.isAdmin, nodeLimits: ctrl.nodesLimits.nodesLimits}"
resource-quota-capacity-exceeded="ctrl.resourceQuotaCapacityExceeded()"
></resource-reservation-form-section>

View File

@ -14,6 +14,12 @@ export function deploymentTypeValidation(
.test(
'exhaused',
`This application would exceed available resources. Please review resource reservations or the instance count.`,
() => !validationData?.isQuotaExceeded
(value) => {
// ignore this validation if the user has selected Replicated, in this case, the isQuotaExceeded will below the instance count input
if (value === 'Replicated') {
return true;
}
return !validationData?.isQuotaExceeded;
}
);
}

View File

@ -24,7 +24,13 @@ export function replicationValidation(
.test(
'overflow',
'This application would exceed available resources. Please review resource reservations or the instance count.',
() => !resourceReservationsOverflow // must not have resource reservations overflow
(value) => {
// the user can't fix the error here with 1 replica. There are validation errors in the resource reservations section that are helpful in a case of resourceReservationsOverflow.
if (value === 1) {
return true;
}
return !resourceReservationsOverflow;
}
)
.test(
'quota',

View File

@ -1,11 +1,21 @@
import { SchemaOf, number, object } from 'yup';
import { SchemaOf, TestContext, number, object } from 'yup';
import KubernetesResourceReservationHelper from '@/kubernetes/helpers/resourceReservationHelper';
import { ResourceQuotaFormValues } from './types';
type NodeLimit = {
CPU: number;
Memory: number;
};
type NodesLimits = Record<string, NodeLimit>;
type ValidationData = {
maxMemoryLimit: number;
maxCpuLimit: number;
isEnvironmentAdmin: boolean;
nodeLimits: NodesLimits;
};
export function resourceReservationValidation(
@ -28,6 +38,23 @@ export function resourceReservationValidation(
({ value }) =>
`Value must be between 0 and ${validationData?.maxMemoryLimit}MB now - the previous value of ${value} exceeds this`
)
.test(
'hasSuitableNode',
`These reservations would exceed the resources currently available in the cluster.`,
// eslint-disable-next-line prefer-arrow-callback, func-names
function (value: number | undefined, context: TestContext) {
if (!validationData || value === undefined) {
// explicitely check for undefined, since 0 is a valid value
return true;
}
const { memoryLimit, cpuLimit } = context.parent;
return hasSuitableNode(
memoryLimit,
cpuLimit,
validationData.nodeLimits
);
}
)
.required(),
cpuLimit: number()
.min(0)
@ -45,6 +72,41 @@ export function resourceReservationValidation(
({ value }) =>
`Value must be between 0 and ${validationData?.maxCpuLimit} now - the previous value of ${value} exceeds this`
)
.test(
'hasSuitableNode',
`These reservations would exceed the resources currently available in the cluster.`,
// eslint-disable-next-line prefer-arrow-callback, func-names
function (value: number | undefined, context: TestContext) {
if (!validationData || value === undefined) {
// explicitely check for undefined, since 0 is a valid value
return true;
}
const { memoryLimit, cpuLimit } = context.parent;
return hasSuitableNode(
memoryLimit,
cpuLimit,
validationData.nodeLimits
);
}
)
.required(),
});
}
function hasSuitableNode(
memoryLimit: number,
cpuLimit: number,
nodeLimits: NodesLimits
) {
// transform the nodelimits from bytes to MB
const limits = Object.values(nodeLimits).map((nodeLimit) => ({
...nodeLimit,
Memory: KubernetesResourceReservationHelper.megaBytesValue(
nodeLimit.Memory
),
}));
// make sure there's a node available with enough memory and cpu
return limits.some(
(nodeLimit) => nodeLimit.Memory >= memoryLimit && nodeLimit.CPU >= cpuLimit
);
}