fix aks pool count validator and add some unit tests (#11907)

This commit is contained in:
Nancy 2024-09-12 17:49:15 -07:00 committed by GitHub
parent 9cfcc682f8
commit c6ad2e6636
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 127 additions and 40 deletions

View File

@ -178,7 +178,9 @@ export default defineComponent({
},
poolCountValidator() {
return (val: number) => this.validationRules?.count?.[0](val, this.pool.enableAutoScaling);
const canBeZero: boolean = this.pool.mode === 'User';
return (val: number) => this.validationRules?.count?.[0](val, canBeZero);
}
},
});
@ -309,9 +311,10 @@ export default defineComponent({
type="number"
:mode="mode"
label-key="aks.nodePools.count.label"
:rules="[poolCountValidator]"
:min="pool.enableAutoScaling ? 0 : 1"
:rules="[poolCountValidator()]"
:min="pool.mode === 'User' ? 0 : 1"
:max="1000"
data-testid="aks-pool-count-input"
/>
</div>
<div class="col span-3">

View File

@ -52,7 +52,8 @@ import {
outboundTypeUserDefined,
privateDnsZone,
nodePoolNames,
nodePoolNamesUnique
nodePoolNamesUnique,
nodePoolCount
} from '../util/validators';
export const defaultNodePool = {
@ -342,6 +343,7 @@ export default defineComponent({
privateDnsZone: privateDnsZone(this, 'aks.privateDnsZone.label', 'aksConfig.privateDnsZone'),
poolNames: nodePoolNames(this),
poolNamesUnique: nodePoolNamesUnique(this),
poolCount: nodePoolCount(this),
vmSizeAvailable: () => {
if (this.touchedVmSize) {
@ -433,40 +435,6 @@ export default defineComponent({
return this.canUseAvailabilityZones || !isUsingAvailabilityZones ? undefined : this.t('aks.errors.availabilityZones');
},
poolCount: (count?: number, autoscale = false) => {
let min = 1;
let errMsg = this.t('aks.errors.poolCount');
if (autoscale) {
min = 0;
errMsg = this.t('aks.errors.poolAutoscaleCount');
}
if (count || count === 0) {
return count >= min ? undefined : errMsg;
} else {
let allValid = true;
this.nodePools.forEach((pool: AKSNodePool) => {
const { count = 0, enableAutoScaling } = pool;
if (enableAutoScaling) {
min = 0;
} else {
min = 1;
}
if (count < min) {
pool._validation['_validCount'] = false;
allValid = false;
} else {
pool._validation['_validCount'] = true;
}
});
return allValid ? undefined : this.t('aks.errors.poolCount');
}
},
poolMin: (min?:number) => {
if (min || min === 0) {
return min < 0 || min > 1000 ? this.t('aks.errors.poolMin') : undefined;

View File

@ -227,4 +227,39 @@ describe('aks node pool component', () => {
expect(wrapper.props().pool.nodeLabels).toStrictEqual(newLabels);
});
it('should validate pool count using the provided count validator function', async() => {
const countValidator = jest.fn();
mount(AksNodePool, {
propsData: {
pool: { ...defaultPool, count: -1 },
validationRules: { count: [countValidator] }
},
...requiredSetup()
});
expect(countValidator).toHaveBeenCalledWith(-1, false);
});
it.each([
['System', false],
['User', true],
])('should validate node pool count differently if the pool mode is User', async(mode, allowZeroCount) => {
const countValidator = jest.fn();
mount(AksNodePool, {
propsData: {
pool: {
...defaultPool, count: -1, mode
},
validationRules: { count: [countValidator] }
},
...requiredSetup()
});
expect(countValidator).toHaveBeenCalledWith(-1, allowZeroCount);
});
});

View File

@ -163,8 +163,8 @@ aks:
availabilityZones: Availability zones are not available in the selected region.
privateDnsZone: Private DNS Zone Resource ID must be in the format /subscriptions/SUBSCRIPTION_ID/resourceGroups/RESOURCEGROUP_NAME/providers/Microsoft.Network/privateDnsZones/PRIVATE_DNS_ZONE_NAME. The Private DNS Zone Resource Name must be in the format privatelink.REGION.azmk8s.io, SUBZONE.privatelink.REGION.azmk8s.io, private.REGION.azmk8s.io, or SUBZONE.private.REGION.azmk8s.io
poolName: Node pool names must be 1-12 characters long, consist only of lowercase letters and numbers, and start with a letter.
poolCount: Node count must be at least one when autoscaling is disabled.
poolAutoscaleCount: Node count cannot be less than zero.
poolCount: Node count must be at least one in System pools.
poolUserCount: Node count cannot be less than zero.
poolMinMax: The minimum number of nodes must be less than or equal to the maximum number of nodes, and the node count must be between or equal to the minimum and maximum.
poolMin: The minimum number of nodes must be greater than 0 and at most 1000.
poolMax: The maximum number of nodes must be greater than 0 and at most 1000.

View File

@ -139,3 +139,48 @@ describe('fx: nodePoolNames', () => {
expect(validator(name)).toStrictEqual(expected);
});
});
describe('fx: nodePoolCount', () => {
// AksNodePool unit tests check that the second arg is passed in as expected
it('validates that count is at least 1 when second arg is false', () => {
const validator = validators.nodePoolCount(mockCtx);
expect(validator(1, false)).toBeUndefined();
expect(validator(0, false)).toStrictEqual(MOCK_TRANSLATION);
});
it('validates that count is at least 0 when second arg is true', () => {
const validator = validators.nodePoolCount(mockCtx);
expect(validator(1, true)).toBeUndefined();
expect(validator(0, true)).toBeUndefined();
expect(validator(-1, true)).toStrictEqual(MOCK_TRANSLATION);
});
it('validates each node pool in the provided context when not passed a count value', () => {
const ctx = {
...mockCtx,
nodePools: [
{
name: 'abc', _validation: {}, mode: 'System', count: 0
},
{
name: 'def', _validation: {}, mode: 'System', count: 1
},
{
name: 'hij', _validation: {}, mode: 'User', count: 0
},
{
name: 'klm', _validation: {}, mode: 'User', count: -1
}
] as unknown as AKSNodePool[]
};
const validator = validators.nodePoolCount(ctx);
validator();
expect(ctx.nodePools[0]?._validation?._validCount).toStrictEqual(false);
expect(ctx.nodePools[1]?._validation?._validCount).toStrictEqual(true);
expect(ctx.nodePools[2]?._validation?._validCount).toStrictEqual(true);
expect(ctx.nodePools[3]?._validation?._validCount).toStrictEqual(false);
});
});

View File

@ -177,3 +177,39 @@ export const nodePoolNamesUnique = (ctx: any) => {
}
};
};
export const nodePoolCount = (ctx:any) => {
return (count?: number, canBeZero = false) => {
let min = 1;
let errMsg = ctx.t('aks.errors.poolCount');
if (canBeZero) {
min = 0;
errMsg = ctx.t('aks.errors.poolUserCount');
}
if (count || count === 0) {
return count >= min ? undefined : errMsg;
} else {
let allValid = true;
ctx.nodePools.forEach((pool: AKSNodePool) => {
const { count = 0, mode } = pool;
if (mode === 'User') {
min = 0;
} else {
min = 1;
}
if (count < min) {
pool._validation['_validCount'] = false;
allValid = false;
} else {
pool._validation['_validCount'] = true;
}
});
return allValid ? undefined : ctx.t('aks.errors.poolCount');
}
};
};