codify-plugin-lib 1.0.128 → 1.0.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plan/plan.d.ts +3 -3
- package/dist/plan/plan.js +17 -17
- package/dist/plugin/plugin.js +1 -1
- package/dist/resource/resource-controller.d.ts +1 -1
- package/dist/resource/resource-controller.js +6 -6
- package/package.json +2 -2
- package/src/common/errors.test.ts +1 -1
- package/src/plan/plan.test.ts +5 -5
- package/src/plan/plan.ts +20 -20
- package/src/plugin/plugin.test.ts +6 -6
- package/src/plugin/plugin.ts +1 -1
- package/src/resource/resource-controller.test.ts +2 -2
- package/src/resource/resource-controller.ts +6 -6
- package/src/resource/resource-settings.test.ts +3 -3
- package/src/stateful-parameter/stateful-parameter-controller.test.ts +1 -1
- package/src/utils/test-utils.test.ts +2 -2
package/dist/plan/plan.d.ts
CHANGED
|
@@ -16,8 +16,8 @@ export declare class Plan<T extends StringIndexedObject> {
|
|
|
16
16
|
* Ex: name, type, dependsOn etc. Metadata parameters
|
|
17
17
|
*/
|
|
18
18
|
coreParameters: ResourceConfig;
|
|
19
|
-
|
|
20
|
-
constructor(id: string, changeSet: ChangeSet<T>, resourceMetadata: ResourceConfig,
|
|
19
|
+
isStateful: boolean;
|
|
20
|
+
constructor(id: string, changeSet: ChangeSet<T>, resourceMetadata: ResourceConfig, isStateful: boolean);
|
|
21
21
|
/**
|
|
22
22
|
* The desired config that a plan will achieve after executing all the actions.
|
|
23
23
|
*/
|
|
@@ -33,7 +33,7 @@ export declare class Plan<T extends StringIndexedObject> {
|
|
|
33
33
|
stateParameters: Partial<T> | null;
|
|
34
34
|
coreParameters: ResourceConfig;
|
|
35
35
|
settings: ParsedResourceSettings<T>;
|
|
36
|
-
|
|
36
|
+
isStateful: boolean;
|
|
37
37
|
}): Plan<T>;
|
|
38
38
|
/**
|
|
39
39
|
* When multiples of the same resource are allowed, this matching function will match a given config with one of the
|
package/dist/plan/plan.js
CHANGED
|
@@ -16,12 +16,12 @@ export class Plan {
|
|
|
16
16
|
* Ex: name, type, dependsOn etc. Metadata parameters
|
|
17
17
|
*/
|
|
18
18
|
coreParameters;
|
|
19
|
-
|
|
20
|
-
constructor(id, changeSet, resourceMetadata,
|
|
19
|
+
isStateful;
|
|
20
|
+
constructor(id, changeSet, resourceMetadata, isStateful) {
|
|
21
21
|
this.id = id;
|
|
22
22
|
this.changeSet = changeSet;
|
|
23
23
|
this.coreParameters = resourceMetadata;
|
|
24
|
-
this.
|
|
24
|
+
this.isStateful = isStateful;
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* The desired config that a plan will achieve after executing all the actions.
|
|
@@ -53,36 +53,36 @@ export class Plan {
|
|
|
53
53
|
: this.coreParameters.type;
|
|
54
54
|
}
|
|
55
55
|
static calculate(params) {
|
|
56
|
-
const { desiredParameters, currentParametersArray, stateParameters, coreParameters, settings,
|
|
56
|
+
const { desiredParameters, currentParametersArray, stateParameters, coreParameters, settings, isStateful } = params;
|
|
57
57
|
const currentParameters = Plan.matchCurrentParameters({
|
|
58
58
|
desiredParameters,
|
|
59
59
|
currentParametersArray,
|
|
60
60
|
stateParameters,
|
|
61
61
|
settings,
|
|
62
|
-
|
|
62
|
+
isStateful
|
|
63
63
|
});
|
|
64
64
|
const filteredCurrentParameters = Plan.filterCurrentParams({
|
|
65
65
|
desiredParameters,
|
|
66
66
|
currentParameters,
|
|
67
67
|
stateParameters,
|
|
68
68
|
settings,
|
|
69
|
-
|
|
69
|
+
isStateful
|
|
70
70
|
});
|
|
71
71
|
// Empty
|
|
72
72
|
if (!filteredCurrentParameters && !desiredParameters) {
|
|
73
|
-
return new Plan(uuidV4(), ChangeSet.empty(), coreParameters,
|
|
73
|
+
return new Plan(uuidV4(), ChangeSet.empty(), coreParameters, isStateful);
|
|
74
74
|
}
|
|
75
75
|
// CREATE
|
|
76
76
|
if (!filteredCurrentParameters && desiredParameters) {
|
|
77
|
-
return new Plan(uuidV4(), ChangeSet.create(desiredParameters), coreParameters,
|
|
77
|
+
return new Plan(uuidV4(), ChangeSet.create(desiredParameters), coreParameters, isStateful);
|
|
78
78
|
}
|
|
79
79
|
// DESTROY
|
|
80
80
|
if (filteredCurrentParameters && !desiredParameters) {
|
|
81
|
-
return new Plan(uuidV4(), ChangeSet.destroy(filteredCurrentParameters), coreParameters,
|
|
81
|
+
return new Plan(uuidV4(), ChangeSet.destroy(filteredCurrentParameters), coreParameters, isStateful);
|
|
82
82
|
}
|
|
83
83
|
// NO-OP, MODIFY or RE-CREATE
|
|
84
84
|
const changeSet = ChangeSet.calculateModification(desiredParameters, filteredCurrentParameters, settings.parameterSettings);
|
|
85
|
-
return new Plan(uuidV4(), changeSet, coreParameters,
|
|
85
|
+
return new Plan(uuidV4(), changeSet, coreParameters, isStateful);
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
88
|
* When multiples of the same resource are allowed, this matching function will match a given config with one of the
|
|
@@ -93,14 +93,14 @@ export class Plan {
|
|
|
93
93
|
* @private
|
|
94
94
|
*/
|
|
95
95
|
static matchCurrentParameters(params) {
|
|
96
|
-
const { desiredParameters, currentParametersArray, stateParameters, settings,
|
|
96
|
+
const { desiredParameters, currentParametersArray, stateParameters, settings, isStateful } = params;
|
|
97
97
|
if (!settings.allowMultiple) {
|
|
98
98
|
return currentParametersArray?.[0] ?? null;
|
|
99
99
|
}
|
|
100
100
|
if (!currentParametersArray) {
|
|
101
101
|
return null;
|
|
102
102
|
}
|
|
103
|
-
if (
|
|
103
|
+
if (isStateful) {
|
|
104
104
|
return stateParameters
|
|
105
105
|
? settings.allowMultiple.matcher(stateParameters, currentParametersArray)
|
|
106
106
|
: null;
|
|
@@ -124,7 +124,7 @@ export class Plan {
|
|
|
124
124
|
return new Plan(uuidV4(), new ChangeSet(data.operation, data.parameters), {
|
|
125
125
|
type: data.resourceType,
|
|
126
126
|
name: data.resourceName,
|
|
127
|
-
}, data.
|
|
127
|
+
}, data.isStateful);
|
|
128
128
|
function addDefaultValues() {
|
|
129
129
|
Object.entries(defaultValues ?? {})
|
|
130
130
|
.forEach(([key, defaultValue]) => {
|
|
@@ -178,7 +178,7 @@ export class Plan {
|
|
|
178
178
|
* or wants to set. If a parameter is not specified then it's not managed by Codify.
|
|
179
179
|
*/
|
|
180
180
|
static filterCurrentParams(params) {
|
|
181
|
-
const { desiredParameters: desired, currentParameters: current, stateParameters: state, settings,
|
|
181
|
+
const { desiredParameters: desired, currentParameters: current, stateParameters: state, settings, isStateful } = params;
|
|
182
182
|
if (!current) {
|
|
183
183
|
return null;
|
|
184
184
|
}
|
|
@@ -188,7 +188,7 @@ export class Plan {
|
|
|
188
188
|
}
|
|
189
189
|
// For stateful mode, we're done after filtering by the keys of desired + state. Stateless mode
|
|
190
190
|
// requires additional filtering for stateful parameter arrays and objects.
|
|
191
|
-
if (
|
|
191
|
+
if (isStateful) {
|
|
192
192
|
return filteredCurrent;
|
|
193
193
|
}
|
|
194
194
|
// TODO: Add object handling here in addition to arrays in the future
|
|
@@ -200,7 +200,7 @@ export class Plan {
|
|
|
200
200
|
if (!current) {
|
|
201
201
|
return null;
|
|
202
202
|
}
|
|
203
|
-
if (
|
|
203
|
+
if (isStateful) {
|
|
204
204
|
const keys = new Set([...Object.keys(state ?? {}), ...Object.keys(desired ?? {})]);
|
|
205
205
|
return Object.fromEntries(Object.entries(current)
|
|
206
206
|
.filter(([k]) => keys.has(k)));
|
|
@@ -276,7 +276,7 @@ export class Plan {
|
|
|
276
276
|
return {
|
|
277
277
|
planId: this.id,
|
|
278
278
|
operation: this.changeSet.operation,
|
|
279
|
-
|
|
279
|
+
isStateful: this.isStateful,
|
|
280
280
|
resourceName: this.coreParameters.name,
|
|
281
281
|
resourceType: this.coreParameters.type,
|
|
282
282
|
parameters: this.changeSet.parameterChanges,
|
package/dist/plugin/plugin.js
CHANGED
|
@@ -101,7 +101,7 @@ export class Plugin {
|
|
|
101
101
|
// Validate using desired/desired. If the apply was successful, no changes should be reported back.
|
|
102
102
|
// Default back desired back to current if it is not defined (for destroys only)
|
|
103
103
|
const validationPlan = await ptyLocalStorage.run(new BackgroundPty(), async () => {
|
|
104
|
-
const result = await resource.plan(plan.desiredConfig, plan.desiredConfig ?? plan.currentConfig, plan.
|
|
104
|
+
const result = await resource.plan(plan.desiredConfig, plan.desiredConfig ?? plan.currentConfig, plan.isStateful);
|
|
105
105
|
await getPty().kill();
|
|
106
106
|
return result;
|
|
107
107
|
});
|
|
@@ -15,7 +15,7 @@ export declare class ResourceController<T extends StringIndexedObject> {
|
|
|
15
15
|
constructor(resource: Resource<T>);
|
|
16
16
|
initialize(): Promise<void>;
|
|
17
17
|
validate(desiredConfig: Partial<T> & ResourceConfig): Promise<ValidateResponseData['resourceValidations'][0]>;
|
|
18
|
-
plan(desiredConfig: Partial<T> & ResourceConfig | null, stateConfig?: Partial<T> & ResourceConfig | null,
|
|
18
|
+
plan(desiredConfig: Partial<T> & ResourceConfig | null, stateConfig?: Partial<T> & ResourceConfig | null, isStateful?: boolean): Promise<Plan<T>>;
|
|
19
19
|
apply(plan: Plan<T>): Promise<void>;
|
|
20
20
|
import(config: Partial<T> & ResourceConfig): Promise<(Partial<T> & ResourceConfig)[] | null>;
|
|
21
21
|
private applyCreate;
|
|
@@ -73,8 +73,8 @@ export class ResourceController {
|
|
|
73
73
|
schemaValidationErrors: [],
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
async plan(desiredConfig, stateConfig = null,
|
|
77
|
-
this.validatePlanInputs(desiredConfig, stateConfig,
|
|
76
|
+
async plan(desiredConfig, stateConfig = null, isStateful = false) {
|
|
77
|
+
this.validatePlanInputs(desiredConfig, stateConfig, isStateful);
|
|
78
78
|
this.addDefaultValues(desiredConfig);
|
|
79
79
|
await this.applyTransformParameters(desiredConfig);
|
|
80
80
|
this.addDefaultValues(stateConfig);
|
|
@@ -96,7 +96,7 @@ export class ResourceController {
|
|
|
96
96
|
stateParameters,
|
|
97
97
|
coreParameters,
|
|
98
98
|
settings: this.parsedSettings,
|
|
99
|
-
|
|
99
|
+
isStateful,
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
102
|
// Refresh stateful parameters. These parameters have state external to the resource. allowMultiple
|
|
@@ -108,7 +108,7 @@ export class ResourceController {
|
|
|
108
108
|
stateParameters,
|
|
109
109
|
coreParameters,
|
|
110
110
|
settings: this.parsedSettings,
|
|
111
|
-
|
|
111
|
+
isStateful
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
114
|
async apply(plan) {
|
|
@@ -272,11 +272,11 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
272
272
|
}));
|
|
273
273
|
return result;
|
|
274
274
|
}
|
|
275
|
-
validatePlanInputs(desired, current,
|
|
275
|
+
validatePlanInputs(desired, current, isStateful) {
|
|
276
276
|
if (!desired && !current) {
|
|
277
277
|
throw new Error('Desired config and current config cannot both be missing');
|
|
278
278
|
}
|
|
279
|
-
if (!
|
|
279
|
+
if (!isStateful && !desired) {
|
|
280
280
|
throw new Error('Desired config must be provided in non-stateful mode');
|
|
281
281
|
}
|
|
282
282
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codify-plugin-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.129",
|
|
4
4
|
"description": "Library plugin library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"ajv": "^8.12.0",
|
|
16
16
|
"ajv-formats": "^2.1.1",
|
|
17
|
-
"codify-schemas": "1.0.
|
|
17
|
+
"codify-schemas": "1.0.60",
|
|
18
18
|
"@npmcli/promise-spawn": "^7.0.1",
|
|
19
19
|
"@homebridge/node-pty-prebuilt-multiarch": "^0.12.0-beta.5",
|
|
20
20
|
"uuid": "^10.0.0",
|
package/src/plan/plan.test.ts
CHANGED
|
@@ -20,7 +20,7 @@ describe('Plan entity tests', () => {
|
|
|
20
20
|
previousValue: null,
|
|
21
21
|
newValue: 'propBValue'
|
|
22
22
|
}],
|
|
23
|
-
|
|
23
|
+
isStateful: false,
|
|
24
24
|
}, controller.parsedSettings.defaultValues);
|
|
25
25
|
|
|
26
26
|
expect(plan.currentConfig).to.be.null;
|
|
@@ -49,7 +49,7 @@ describe('Plan entity tests', () => {
|
|
|
49
49
|
previousValue: 'propBValue',
|
|
50
50
|
newValue: null,
|
|
51
51
|
}],
|
|
52
|
-
|
|
52
|
+
isStateful: false,
|
|
53
53
|
}, controller.parsedSettings.defaultValues);
|
|
54
54
|
|
|
55
55
|
expect(plan.currentConfig).toMatchObject({
|
|
@@ -78,7 +78,7 @@ describe('Plan entity tests', () => {
|
|
|
78
78
|
previousValue: 'propBValue',
|
|
79
79
|
newValue: 'propBValue',
|
|
80
80
|
}],
|
|
81
|
-
|
|
81
|
+
isStateful: false,
|
|
82
82
|
}, controller.parsedSettings.defaultValues);
|
|
83
83
|
|
|
84
84
|
expect(plan.currentConfig).toMatchObject({
|
|
@@ -116,7 +116,7 @@ describe('Plan entity tests', () => {
|
|
|
116
116
|
previousValue: null,
|
|
117
117
|
newValue: 'propAValue',
|
|
118
118
|
}],
|
|
119
|
-
|
|
119
|
+
isStateful: false,
|
|
120
120
|
}, controller.parsedSettings.defaultValues);
|
|
121
121
|
|
|
122
122
|
expect(plan.currentConfig).to.be.null
|
|
@@ -142,7 +142,7 @@ describe('Plan entity tests', () => {
|
|
|
142
142
|
name: 'name1'
|
|
143
143
|
},
|
|
144
144
|
settings: new ParsedResourceSettings<TestConfig>({ id: 'type' }),
|
|
145
|
-
|
|
145
|
+
isStateful: false,
|
|
146
146
|
});
|
|
147
147
|
|
|
148
148
|
expect(plan.toResponse()).toMatchObject({
|
package/src/plan/plan.ts
CHANGED
|
@@ -34,13 +34,13 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
34
34
|
*/
|
|
35
35
|
coreParameters: ResourceConfig;
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
isStateful: boolean;
|
|
38
38
|
|
|
39
|
-
constructor(id: string, changeSet: ChangeSet<T>, resourceMetadata: ResourceConfig,
|
|
39
|
+
constructor(id: string, changeSet: ChangeSet<T>, resourceMetadata: ResourceConfig, isStateful: boolean) {
|
|
40
40
|
this.id = id;
|
|
41
41
|
this.changeSet = changeSet;
|
|
42
42
|
this.coreParameters = resourceMetadata;
|
|
43
|
-
this.
|
|
43
|
+
this.isStateful = isStateful;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
@@ -83,7 +83,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
83
83
|
stateParameters: Partial<T> | null,
|
|
84
84
|
coreParameters: ResourceConfig,
|
|
85
85
|
settings: ParsedResourceSettings<T>,
|
|
86
|
-
|
|
86
|
+
isStateful: boolean,
|
|
87
87
|
}): Plan<T> {
|
|
88
88
|
const {
|
|
89
89
|
desiredParameters,
|
|
@@ -91,7 +91,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
91
91
|
stateParameters,
|
|
92
92
|
coreParameters,
|
|
93
93
|
settings,
|
|
94
|
-
|
|
94
|
+
isStateful
|
|
95
95
|
} = params
|
|
96
96
|
|
|
97
97
|
const currentParameters = Plan.matchCurrentParameters<T>({
|
|
@@ -99,7 +99,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
99
99
|
currentParametersArray,
|
|
100
100
|
stateParameters,
|
|
101
101
|
settings,
|
|
102
|
-
|
|
102
|
+
isStateful
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
const filteredCurrentParameters = Plan.filterCurrentParams<T>({
|
|
@@ -107,7 +107,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
107
107
|
currentParameters,
|
|
108
108
|
stateParameters,
|
|
109
109
|
settings,
|
|
110
|
-
|
|
110
|
+
isStateful
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
// Empty
|
|
@@ -116,7 +116,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
116
116
|
uuidV4(),
|
|
117
117
|
ChangeSet.empty<T>(),
|
|
118
118
|
coreParameters,
|
|
119
|
-
|
|
119
|
+
isStateful,
|
|
120
120
|
)
|
|
121
121
|
}
|
|
122
122
|
|
|
@@ -126,7 +126,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
126
126
|
uuidV4(),
|
|
127
127
|
ChangeSet.create(desiredParameters),
|
|
128
128
|
coreParameters,
|
|
129
|
-
|
|
129
|
+
isStateful,
|
|
130
130
|
)
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -136,7 +136,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
136
136
|
uuidV4(),
|
|
137
137
|
ChangeSet.destroy(filteredCurrentParameters),
|
|
138
138
|
coreParameters,
|
|
139
|
-
|
|
139
|
+
isStateful,
|
|
140
140
|
)
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -151,7 +151,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
151
151
|
uuidV4(),
|
|
152
152
|
changeSet,
|
|
153
153
|
coreParameters,
|
|
154
|
-
|
|
154
|
+
isStateful,
|
|
155
155
|
);
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -168,14 +168,14 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
168
168
|
currentParametersArray: Partial<T>[] | null,
|
|
169
169
|
stateParameters: Partial<T> | null,
|
|
170
170
|
settings: ResourceSettings<T>,
|
|
171
|
-
|
|
171
|
+
isStateful: boolean,
|
|
172
172
|
}): Partial<T> | null {
|
|
173
173
|
const {
|
|
174
174
|
desiredParameters,
|
|
175
175
|
currentParametersArray,
|
|
176
176
|
stateParameters,
|
|
177
177
|
settings,
|
|
178
|
-
|
|
178
|
+
isStateful
|
|
179
179
|
} = params;
|
|
180
180
|
|
|
181
181
|
if (!settings.allowMultiple) {
|
|
@@ -186,7 +186,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
186
186
|
return null;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
if (
|
|
189
|
+
if (isStateful) {
|
|
190
190
|
return stateParameters
|
|
191
191
|
? settings.allowMultiple.matcher(stateParameters, currentParametersArray)
|
|
192
192
|
: null
|
|
@@ -222,7 +222,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
222
222
|
type: data.resourceType,
|
|
223
223
|
name: data.resourceName,
|
|
224
224
|
},
|
|
225
|
-
data.
|
|
225
|
+
data.isStateful
|
|
226
226
|
);
|
|
227
227
|
|
|
228
228
|
function addDefaultValues(): void {
|
|
@@ -288,14 +288,14 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
288
288
|
currentParameters: Partial<T> | null,
|
|
289
289
|
stateParameters: Partial<T> | null,
|
|
290
290
|
settings: ResourceSettings<T>,
|
|
291
|
-
|
|
291
|
+
isStateful: boolean,
|
|
292
292
|
}): Partial<T> | null {
|
|
293
293
|
const {
|
|
294
294
|
desiredParameters: desired,
|
|
295
295
|
currentParameters: current,
|
|
296
296
|
stateParameters: state,
|
|
297
297
|
settings,
|
|
298
|
-
|
|
298
|
+
isStateful
|
|
299
299
|
} = params;
|
|
300
300
|
|
|
301
301
|
if (!current) {
|
|
@@ -309,7 +309,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
309
309
|
|
|
310
310
|
// For stateful mode, we're done after filtering by the keys of desired + state. Stateless mode
|
|
311
311
|
// requires additional filtering for stateful parameter arrays and objects.
|
|
312
|
-
if (
|
|
312
|
+
if (isStateful) {
|
|
313
313
|
return filteredCurrent;
|
|
314
314
|
}
|
|
315
315
|
|
|
@@ -327,7 +327,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
327
327
|
return null;
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
-
if (
|
|
330
|
+
if (isStateful) {
|
|
331
331
|
const keys = new Set([...Object.keys(state ?? {}), ...Object.keys(desired ?? {})]);
|
|
332
332
|
return Object.fromEntries(
|
|
333
333
|
Object.entries(current)
|
|
@@ -426,7 +426,7 @@ export class Plan<T extends StringIndexedObject> {
|
|
|
426
426
|
return {
|
|
427
427
|
planId: this.id,
|
|
428
428
|
operation: this.changeSet.operation,
|
|
429
|
-
|
|
429
|
+
isStateful: this.isStateful,
|
|
430
430
|
resourceName: this.coreParameters.name,
|
|
431
431
|
resourceType: this.coreParameters.type,
|
|
432
432
|
parameters: this.changeSet.parameterChanges,
|
|
@@ -56,7 +56,7 @@ describe('Plugin tests', () => {
|
|
|
56
56
|
parameters: [
|
|
57
57
|
{ name: 'propA', operation: ParameterOperation.ADD, newValue: 'abc', previousValue: null },
|
|
58
58
|
],
|
|
59
|
-
|
|
59
|
+
isStateful: false,
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
await plugin.apply({ plan });
|
|
@@ -77,7 +77,7 @@ describe('Plugin tests', () => {
|
|
|
77
77
|
parameters: [
|
|
78
78
|
{ name: 'propA', operation: ParameterOperation.REMOVE, newValue: null, previousValue: 'abc' },
|
|
79
79
|
],
|
|
80
|
-
|
|
80
|
+
isStateful: true,
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
await testPlugin.apply({ plan })
|
|
@@ -100,7 +100,7 @@ describe('Plugin tests', () => {
|
|
|
100
100
|
parameters: [
|
|
101
101
|
{ name: 'propA', operation: ParameterOperation.MODIFY, newValue: 'def', previousValue: 'abc' },
|
|
102
102
|
],
|
|
103
|
-
|
|
103
|
+
isStateful: false,
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
await testPlugin.apply({ plan })
|
|
@@ -124,7 +124,7 @@ describe('Plugin tests', () => {
|
|
|
124
124
|
parameters: [
|
|
125
125
|
{ name: 'propA', operation: ParameterOperation.MODIFY, newValue: 'def', previousValue: 'abc' },
|
|
126
126
|
],
|
|
127
|
-
|
|
127
|
+
isStateful: false,
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
await testPlugin.apply({ plan })
|
|
@@ -224,7 +224,7 @@ describe('Plugin tests', () => {
|
|
|
224
224
|
parameters: [
|
|
225
225
|
{ name: 'propA', operation: ParameterOperation.MODIFY, newValue: 'def', previousValue: 'abc' },
|
|
226
226
|
],
|
|
227
|
-
|
|
227
|
+
isStateful: false,
|
|
228
228
|
};
|
|
229
229
|
|
|
230
230
|
await expect(() => testPlugin.apply({ plan }))
|
|
@@ -275,7 +275,7 @@ describe('Plugin tests', () => {
|
|
|
275
275
|
parameters: [
|
|
276
276
|
{ name: 'propA', operation: ParameterOperation.ADD, newValue: 'abc', previousValue: null },
|
|
277
277
|
],
|
|
278
|
-
|
|
278
|
+
isStateful: false,
|
|
279
279
|
};
|
|
280
280
|
|
|
281
281
|
await testPlugin.apply({ plan })
|
package/src/plugin/plugin.ts
CHANGED
|
@@ -150,7 +150,7 @@ describe('Resource tests', () => {
|
|
|
150
150
|
testPlan({
|
|
151
151
|
current: [{ propA: 'a', propB: 0 }],
|
|
152
152
|
state: { propA: 'a', propB: 0 },
|
|
153
|
-
|
|
153
|
+
isStateful: true,
|
|
154
154
|
})
|
|
155
155
|
)
|
|
156
156
|
|
|
@@ -169,7 +169,7 @@ describe('Resource tests', () => {
|
|
|
169
169
|
testPlan({
|
|
170
170
|
desired: { propA: 'a', propB: 0 },
|
|
171
171
|
current: [{ propA: 'b', propB: -1 }],
|
|
172
|
-
|
|
172
|
+
isStateful: true
|
|
173
173
|
})
|
|
174
174
|
);
|
|
175
175
|
|
|
@@ -106,9 +106,9 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
106
106
|
async plan(
|
|
107
107
|
desiredConfig: Partial<T> & ResourceConfig | null,
|
|
108
108
|
stateConfig: Partial<T> & ResourceConfig | null = null,
|
|
109
|
-
|
|
109
|
+
isStateful = false,
|
|
110
110
|
): Promise<Plan<T>> {
|
|
111
|
-
this.validatePlanInputs(desiredConfig, stateConfig,
|
|
111
|
+
this.validatePlanInputs(desiredConfig, stateConfig, isStateful);
|
|
112
112
|
|
|
113
113
|
this.addDefaultValues(desiredConfig);
|
|
114
114
|
await this.applyTransformParameters(desiredConfig);
|
|
@@ -143,7 +143,7 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
143
143
|
stateParameters,
|
|
144
144
|
coreParameters,
|
|
145
145
|
settings: this.parsedSettings,
|
|
146
|
-
|
|
146
|
+
isStateful,
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -157,7 +157,7 @@ export class ResourceController<T extends StringIndexedObject> {
|
|
|
157
157
|
stateParameters,
|
|
158
158
|
coreParameters,
|
|
159
159
|
settings: this.parsedSettings,
|
|
160
|
-
|
|
160
|
+
isStateful
|
|
161
161
|
})
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -377,13 +377,13 @@ ${JSON.stringify(refresh, null, 2)}
|
|
|
377
377
|
private validatePlanInputs(
|
|
378
378
|
desired: Partial<T> & ResourceConfig | null,
|
|
379
379
|
current: Partial<T> & ResourceConfig | null,
|
|
380
|
-
|
|
380
|
+
isStateful: boolean,
|
|
381
381
|
) {
|
|
382
382
|
if (!desired && !current) {
|
|
383
383
|
throw new Error('Desired config and current config cannot both be missing')
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
-
if (!
|
|
386
|
+
if (!isStateful && !desired) {
|
|
387
387
|
throw new Error('Desired config must be provided in non-stateful mode')
|
|
388
388
|
}
|
|
389
389
|
}
|
|
@@ -500,7 +500,7 @@ describe('Resource parameter tests', () => {
|
|
|
500
500
|
{ name: 'propB', operation: ParameterOperation.ADD, previousValue: null, newValue: null },
|
|
501
501
|
{ name: 'propC', operation: ParameterOperation.ADD, previousValue: null, newValue: null },
|
|
502
502
|
],
|
|
503
|
-
|
|
503
|
+
isStateful: false,
|
|
504
504
|
}, {}) as any
|
|
505
505
|
);
|
|
506
506
|
|
|
@@ -523,7 +523,7 @@ describe('Resource parameter tests', () => {
|
|
|
523
523
|
{ name: 'propB', operation: ParameterOperation.MODIFY, previousValue: null, newValue: null },
|
|
524
524
|
{ name: 'propC', operation: ParameterOperation.MODIFY, previousValue: null, newValue: null },
|
|
525
525
|
],
|
|
526
|
-
|
|
526
|
+
isStateful: false,
|
|
527
527
|
}, {}) as any
|
|
528
528
|
);
|
|
529
529
|
|
|
@@ -542,7 +542,7 @@ describe('Resource parameter tests', () => {
|
|
|
542
542
|
{ name: 'propB', operation: ParameterOperation.REMOVE, previousValue: null, newValue: null },
|
|
543
543
|
{ name: 'propC', operation: ParameterOperation.REMOVE, previousValue: null, newValue: null },
|
|
544
544
|
],
|
|
545
|
-
|
|
545
|
+
isStateful: false,
|
|
546
546
|
}, {}) as any
|
|
547
547
|
);
|
|
548
548
|
|
|
@@ -34,7 +34,7 @@ describe('Stateful parameter tests', () => {
|
|
|
34
34
|
desired: null,
|
|
35
35
|
current: [{ propZ: ['a', 'b', 'c'] }],
|
|
36
36
|
state: { propZ: ['a', 'b', 'c'] },
|
|
37
|
-
|
|
37
|
+
isStateful: true,
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
expect(plan.changeSet.operation).to.eq(ResourceOperation.DESTROY);
|
|
@@ -12,7 +12,7 @@ export function testPlan<T extends StringIndexedObject>(params: {
|
|
|
12
12
|
state?: Partial<T> | null;
|
|
13
13
|
core?: ResourceConfig;
|
|
14
14
|
settings?: ResourceSettings<T>;
|
|
15
|
-
|
|
15
|
+
isStateful?: boolean;
|
|
16
16
|
}) {
|
|
17
17
|
return Plan.calculate({
|
|
18
18
|
desiredParameters: params.desired ?? null,
|
|
@@ -22,7 +22,7 @@ export function testPlan<T extends StringIndexedObject>(params: {
|
|
|
22
22
|
settings: params.settings ?
|
|
23
23
|
new ParsedResourceSettings<T>(params.settings)
|
|
24
24
|
: new ParsedResourceSettings<T>({ id: 'type' }),
|
|
25
|
-
|
|
25
|
+
isStateful: params.isStateful ?? false,
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
28
|
|