Skip to content

Commit cb8bb83

Browse files
check enum values
1 parent 571c2dd commit cb8bb83

File tree

4 files changed

+98
-7
lines changed

4 files changed

+98
-7
lines changed

tools/spectral/ipa/__tests__/IPA119NoDefaultForCloudProviders.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,32 @@ testRule('xgen-IPA-119-no-default-for-cloud-providers', [
4646
},
4747
],
4848
},
49+
{
50+
name: 'invalid when cloud provider field has default value',
51+
document: {
52+
components: {
53+
schemas: {
54+
Schema: {
55+
properties: {
56+
provider: {
57+
type: 'string',
58+
enum: ['AWS', 'GCP', 'AZURE'],
59+
default: 'AWS',
60+
},
61+
},
62+
},
63+
},
64+
},
65+
},
66+
errors: [
67+
{
68+
code: 'xgen-IPA-119-no-default-for-cloud-providers',
69+
message: 'When using a provider field or param, API producers should not define a default value.',
70+
path: ['components', 'schemas', 'Schema', 'properties', 'provider'],
71+
severity: DiagnosticSeverity.Warning,
72+
},
73+
],
74+
},
4975
{
5076
name: 'valid when non-provider field has default value',
5177
document: {
@@ -137,6 +163,22 @@ testRule('xgen-IPA-119-no-default-for-cloud-providers', [
137163
},
138164
},
139165
},
166+
components: {
167+
schemas: {
168+
Schema: {
169+
properties: {
170+
provider: {
171+
type: 'string',
172+
enum: ['AWS', 'GCP', 'AZURE'],
173+
default: 'AWS',
174+
'x-xgen-IPA-exception': {
175+
'xgen-IPA-119-no-default-for-cloud-providers': 'Reason',
176+
},
177+
},
178+
},
179+
},
180+
},
181+
},
140182
},
141183
errors: [],
142184
},

tools/spectral/ipa/rulesets/IPA-119.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ rules:
77
xgen-IPA-119-no-default-for-cloud-providers:
88
description: |
99
When using a provider field or parameter, API producers should not define a default value.
10-
As providers are added, having a default value can impact usability.
11-
This rule checks fields containing "provider" or "cloudProvider" and ensures they do not have a default value.
10+
This rule checks fields and parameters named "cloudProvider" and ensures they do not have a default value.
1211
It also checks enum fields that might contain cloud provider values.
12+
All cloudProviderEnumValues should be listed in the enum array.
1313
severity: warn
1414
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-119-no-default-for-cloud-providers'
1515
given:
@@ -22,3 +22,7 @@ rules:
2222
function: IPA119NoDefaultForCloudProviders
2323
functionOptions:
2424
propertyNameToLookFor: 'cloudProvider'
25+
cloudProviderEnumValues:
26+
- 'AWS'
27+
- 'GCP'
28+
- 'AZURE'

tools/spectral/ipa/rulesets/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -780,9 +780,9 @@ Rules are based on [http://go/ipa/IPA-119](http://go/ipa/IPA-119).
780780

781781
![warn](https://img.shields.io/badge/warning-yellow)
782782
When using a provider field or parameter, API producers should not define a default value.
783-
As providers are added, having a default value can impact usability.
784-
This rule checks fields containing "provider" or "cloudProvider" and ensures they do not have a default value.
783+
This rule checks fields and parameters named "cloudProvider" and ensures they do not have a default value.
785784
It also checks enum fields that might contain cloud provider values.
785+
All cloudProviderEnumValues should be listed in the enum array.
786786

787787

788788

tools/spectral/ipa/rulesets/functions/IPA119NoDefaultForCloudProviders.js

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { resolveObject } from './utils/componentUtils.js';
99

1010
const RULE_NAME = 'xgen-IPA-119-no-default-for-cloud-providers';
1111
const ERROR_MESSAGE = 'When using a provider field or param, API producers should not define a default value.';
12-
export default (input, { propertyNameToLookFor }, { path, documentInventory }) => {
12+
export default (input, { propertyNameToLookFor, cloudProviderEnumValues }, { path, documentInventory }) => {
1313
const oas = documentInventory.resolved;
1414
const propertyObject = resolveObject(oas, path);
1515
const fieldType = path[path.length - 2];
@@ -19,14 +19,28 @@ export default (input, { propertyNameToLookFor }, { path, documentInventory }) =
1919
return;
2020
}
2121

22-
const errors = checkViolationsAndReturnErrors(input, propertyObject, path, propertyNameToLookFor, fieldType);
22+
const errors = checkViolationsAndReturnErrors(
23+
input,
24+
propertyObject,
25+
path,
26+
propertyNameToLookFor,
27+
fieldType,
28+
cloudProviderEnumValues
29+
);
2330
if (errors.length !== 0) {
2431
return collectAndReturnViolation(path, RULE_NAME, errors);
2532
}
2633
collectAdoption(path, RULE_NAME);
2734
};
2835

29-
function checkViolationsAndReturnErrors(propertyName, propertyObject, path, propertyNameToLookFor, fieldType) {
36+
function checkViolationsAndReturnErrors(
37+
propertyName,
38+
propertyObject,
39+
path,
40+
propertyNameToLookFor,
41+
fieldType,
42+
cloudProviderEnumValues
43+
) {
3044
try {
3145
if (fieldType === 'properties') {
3246
if (propertyName === propertyNameToLookFor && propertyObject.default !== undefined) {
@@ -37,6 +51,21 @@ function checkViolationsAndReturnErrors(propertyName, propertyObject, path, prop
3751
},
3852
];
3953
}
54+
55+
if (Array.isArray(propertyObject.enum) && propertyObject.enum.length > 0) {
56+
const enumValues = propertyObject.enum;
57+
const hasCloudProviderEnumValue = cloudProviderEnumValues.every((cloudProviderValue) =>
58+
enumValues.includes(cloudProviderValue)
59+
);
60+
if (hasCloudProviderEnumValue && propertyObject.default !== undefined) {
61+
return [
62+
{
63+
path,
64+
message: ERROR_MESSAGE,
65+
},
66+
];
67+
}
68+
}
4069
} else if (fieldType === 'parameters') {
4170
if (propertyObject.name === propertyNameToLookFor && propertyObject.schema.default !== undefined) {
4271
return [
@@ -46,6 +75,22 @@ function checkViolationsAndReturnErrors(propertyName, propertyObject, path, prop
4675
},
4776
];
4877
}
78+
79+
if (Array.isArray(propertyObject.schema.enum) && propertyObject.schema.enum.length > 0) {
80+
const enumValues = propertyObject.schema.enum;
81+
const hasCloudProviderEnumValue = cloudProviderEnumValues.every((cloudProviderValue) =>
82+
enumValues.includes(cloudProviderValue)
83+
);
84+
85+
if (hasCloudProviderEnumValue && propertyObject.schema.default !== undefined) {
86+
return [
87+
{
88+
path,
89+
message: ERROR_MESSAGE,
90+
},
91+
];
92+
}
93+
}
4994
}
5095

5196
return [];

0 commit comments

Comments
 (0)