Skip to content

Commit 860966a

Browse files
authored
feat(core): make the CfnParameter class mutable (#9365)
Closes #9364 ---- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
1 parent 975efbe commit 860966a

File tree

3 files changed

+236
-14
lines changed

3 files changed

+236
-14
lines changed

packages/@aws-cdk/cloudformation-include/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,24 @@ Note that [Custom Resources](https://docs.aws.amazon.com/AWSCloudFormation/lates
110110
will be of type CfnResource, and hence won't need to be casted.
111111
This holds for any resource that isn't in the CloudFormation schema.
112112

113+
## Parameters
114+
115+
If your template uses [CloudFormation Parameters] (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html),
116+
you can retrieve them from your template:
117+
118+
```typescript
119+
import * as core from '@aws-cdk/core';
120+
121+
const param: core.CfnParameter = cfnTemplate.getParameter('MyParameter');
122+
```
123+
124+
The `CfnParameter` object is mutable,
125+
and any changes you make to it will be reflected in the resulting template:
126+
127+
```typescript
128+
param.default = 'MyDefault';
129+
```
130+
113131
## Conditions
114132

115133
If your template uses [CloudFormation Conditions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html),

packages/@aws-cdk/cloudformation-include/test/valid-templates.test.ts

+46
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,52 @@ describe('CDK Include', () => {
397397
}).toThrow(/Parameter with name 'FakeBucketNameThatDoesNotExist' was not found in the template/);
398398
});
399399

400+
test('reflects changes to a retrieved CfnParameter object in the resulting template', () => {
401+
const cfnTemplate = includeTestTemplate(stack, 'bucket-with-parameters.json');
402+
const stringParam = cfnTemplate.getParameter('BucketName');
403+
const numberParam = cfnTemplate.getParameter('CorsMaxAge');
404+
405+
stringParam.default = 'MyDefault';
406+
stringParam.allowedPattern = '[0-9]*$';
407+
stringParam.allowedValues = ['123123', '456789'];
408+
stringParam.constraintDescription = 'MyNewConstraint';
409+
stringParam.description = 'a string of numeric characters';
410+
stringParam.maxLength = 6;
411+
stringParam.minLength = 2;
412+
413+
numberParam.maxValue = 100;
414+
numberParam.minValue = 4;
415+
numberParam.noEcho = false;
416+
numberParam.type = "NewType";
417+
const originalTemplate = loadTestFileToJsObject('bucket-with-parameters.json');
418+
419+
expect(stack).toMatchTemplate({
420+
"Resources": {
421+
...originalTemplate.Resources,
422+
},
423+
"Parameters": {
424+
...originalTemplate.Parameters,
425+
"BucketName": {
426+
...originalTemplate.Parameters.BucketName,
427+
"Default": "MyDefault",
428+
"AllowedPattern": "[0-9]*$",
429+
"AllowedValues": [ "123123", "456789" ],
430+
"ConstraintDescription": "MyNewConstraint",
431+
"Description": "a string of numeric characters",
432+
"MaxLength": 6,
433+
"MinLength": 2,
434+
},
435+
"CorsMaxAge": {
436+
...originalTemplate.Parameters.CorsMaxAge,
437+
"MaxValue": 100,
438+
"MinValue": 4,
439+
"NoEcho": false,
440+
"Type": "NewType",
441+
},
442+
},
443+
});
444+
});
445+
400446
test('reflects changes to a retrieved CfnCondition object in the resulting template', () => {
401447
const cfnTemplate = includeTestTemplate(stack, 'resource-attribute-condition.json');
402448
const alwaysFalseCondition = cfnTemplate.getCondition('AlwaysFalseCond');

packages/@aws-cdk/core/lib/cfn-parameter.ts

+172-14
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,17 @@ export interface CfnParameterProps {
9797
* update a stack.
9898
*/
9999
export class CfnParameter extends CfnElement {
100-
private readonly type: string;
100+
private _type: string;
101+
private _default?: any;
102+
private _allowedPattern?: string;
103+
private _allowedValues?: string[];
104+
private _constraintDescription?: string;
105+
private _description?: string;
106+
private _maxLength?: number;
107+
private _maxValue?: number;
108+
private _minLength?: number;
109+
private _minValue?: number;
110+
private _noEcho?: boolean;
101111

102112
/**
103113
* Creates a parameter construct.
@@ -107,17 +117,165 @@ export class CfnParameter extends CfnElement {
107117
* @param scope The parent construct.
108118
* @param props The parameter properties.
109119
*/
110-
constructor(scope: Construct, id: string, private readonly props: CfnParameterProps = {}) {
120+
constructor(scope: Construct, id: string, props: CfnParameterProps = {}) {
111121
super(scope, id);
112122

113-
this.type = props.type || 'String';
123+
this._type = props.type || 'String';
124+
this._default = props.default;
125+
this._allowedPattern = props.allowedPattern;
126+
this._allowedValues = props.allowedValues;
127+
this._constraintDescription = props.constraintDescription;
128+
this._description = props.description;
129+
this._maxLength = props.maxLength;
130+
this._maxValue = props.maxValue;
131+
this._minLength = props.minLength;
132+
this._minValue = props.minValue;
133+
this._noEcho = props.noEcho;
134+
}
135+
136+
/**
137+
* The data type for the parameter (DataType).
138+
*
139+
* @default String
140+
*/
141+
public get type(): string {
142+
return this._type;
143+
}
144+
145+
public set type(type: string) {
146+
this._type = type;
147+
}
148+
149+
/**
150+
* A value of the appropriate type for the template to use if no value is specified
151+
* when a stack is created. If you define constraints for the parameter, you must specify
152+
* a value that adheres to those constraints.
153+
*
154+
* @default - No default value for parameter.
155+
*/
156+
public get default(): any {
157+
return this._default;
158+
}
159+
160+
public set default(value: any) {
161+
this._default = value;
162+
}
163+
164+
/**
165+
* A regular expression that represents the patterns to allow for String types.
166+
*
167+
* @default - No constraints on patterns allowed for parameter.
168+
*/
169+
public get allowedPattern(): string | undefined {
170+
return this._allowedPattern;
171+
}
172+
173+
public set allowedPattern(pattern: string | undefined) {
174+
this._allowedPattern = pattern;
175+
}
176+
177+
/**
178+
* An array containing the list of values allowed for the parameter.
179+
*
180+
* @default - No constraints on values allowed for parameter.
181+
*/
182+
public get allowedValues(): string[] | undefined {
183+
return this._allowedValues;
184+
}
185+
186+
public set allowedValues(values: string[] | undefined) {
187+
this._allowedValues = values;
188+
}
189+
190+
/**
191+
* A string that explains a constraint when the constraint is violated.
192+
* For example, without a constraint description, a parameter that has an allowed
193+
* pattern of [A-Za-z0-9]+ displays the following error message when the user specifies
194+
* an invalid value:
195+
*
196+
* @default - No description with customized error message when user specifies invalid values.
197+
*/
198+
public get constraintDescription(): string | undefined {
199+
return this._constraintDescription;
200+
}
201+
202+
public set constraintDescription(desc: string | undefined) {
203+
this._constraintDescription = desc;
204+
}
205+
206+
/**
207+
* A string of up to 4000 characters that describes the parameter.
208+
*
209+
* @default - No description for the parameter.
210+
*/
211+
public get description(): string | undefined {
212+
return this._description;
213+
}
214+
215+
public set description(desc: string | undefined) {
216+
this._description = desc;
217+
}
218+
219+
/**
220+
* An integer value that determines the largest number of characters you want to allow for String types.
221+
*
222+
* @default - None.
223+
*/
224+
public get maxLength(): number | undefined {
225+
return this._maxLength;
226+
}
227+
228+
public set maxLength(len: number | undefined) {
229+
this._maxLength = len;
230+
}
231+
232+
/**
233+
* An integer value that determines the smallest number of characters you want to allow for String types.
234+
*
235+
* @default - None.
236+
*/
237+
public get minLength(): number | undefined {
238+
return this._minLength;
239+
}
240+
241+
public set minLength(len: number | undefined) {
242+
this._minLength = len;
243+
}
244+
245+
/**
246+
* A numeric value that determines the largest numeric value you want to allow for Number types.
247+
*
248+
* @default - None.
249+
*/
250+
public get maxValue(): number | undefined {
251+
return this._maxValue;
252+
}
253+
254+
public set maxValue(len: number | undefined) {
255+
this._maxValue = len;
256+
}
257+
/**
258+
* A numeric value that determines the smallest numeric value you want to allow for Number types.
259+
*
260+
* @default - None.
261+
*/
262+
public get minValue(): number | undefined {
263+
return this._minValue;
264+
}
265+
266+
public set minValue(len: number | undefined) {
267+
this._minValue = len;
114268
}
115269

116270
/**
117271
* Indicates if this parameter is configured with "NoEcho" enabled.
118272
*/
119273
public get noEcho(): boolean {
120-
return !!this.props.noEcho;
274+
return !!this._noEcho;
275+
}
276+
277+
public set noEcho(echo: boolean) {
278+
this._noEcho = echo;
121279
}
122280

123281
/**
@@ -165,16 +323,16 @@ export class CfnParameter extends CfnElement {
165323
Parameters: {
166324
[this.logicalId]: {
167325
Type: this.type,
168-
Default: this.props.default,
169-
AllowedPattern: this.props.allowedPattern,
170-
AllowedValues: this.props.allowedValues,
171-
ConstraintDescription: this.props.constraintDescription,
172-
Description: this.props.description,
173-
MaxLength: this.props.maxLength,
174-
MaxValue: this.props.maxValue,
175-
MinLength: this.props.minLength,
176-
MinValue: this.props.minValue,
177-
NoEcho: this.props.noEcho,
326+
Default: this.default,
327+
AllowedPattern: this.allowedPattern,
328+
AllowedValues: this.allowedValues,
329+
ConstraintDescription: this.constraintDescription,
330+
Description: this.description,
331+
MaxLength: this.maxLength,
332+
MaxValue: this.maxValue,
333+
MinLength: this.minLength,
334+
MinValue: this.minValue,
335+
NoEcho: this._noEcho,
178336
},
179337
},
180338
};

0 commit comments

Comments
 (0)