awscfn 1.1.2 → 1.2.0
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/README.md +43 -0
- package/bin/awscfn +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/cfn/executeChangeSet.d.ts +9 -2
- package/dist/lib/cfn/executeChangeSet.d.ts.map +1 -1
- package/dist/lib/cfn/executeChangeSet.js +21 -6
- package/dist/lib/cfn/executeChangeSet.js.map +1 -1
- package/dist/lib/cfn/index.d.ts +1 -0
- package/dist/lib/cfn/index.d.ts.map +1 -1
- package/dist/lib/cfn/index.js +1 -0
- package/dist/lib/cfn/index.js.map +1 -1
- package/dist/lib/cfn/previewChangeSet.d.ts +7 -0
- package/dist/lib/cfn/previewChangeSet.d.ts.map +1 -0
- package/dist/lib/cfn/previewChangeSet.js +97 -0
- package/dist/lib/cfn/previewChangeSet.js.map +1 -0
- package/dist/lib/formatChangeSet.d.ts +10 -0
- package/dist/lib/formatChangeSet.d.ts.map +1 -0
- package/dist/lib/formatChangeSet.js +81 -0
- package/dist/lib/formatChangeSet.js.map +1 -0
- package/dist/lib/formatChangeSet.spec.d.ts +2 -0
- package/dist/lib/formatChangeSet.spec.d.ts.map +1 -0
- package/dist/lib/formatChangeSet.spec.js +72 -0
- package/dist/lib/formatChangeSet.spec.js.map +1 -0
- package/dist/previewStack.d.ts +6 -0
- package/dist/previewStack.d.ts.map +1 -0
- package/dist/previewStack.js +61 -0
- package/dist/previewStack.js.map +1 -0
- package/package.json +1 -1
- package/dist/lib/placeholder.spec.d.ts +0 -2
- package/dist/lib/placeholder.spec.d.ts.map +0 -1
- package/dist/lib/placeholder.spec.js +0 -8
- package/dist/lib/placeholder.spec.js.map +0 -1
package/README.md
CHANGED
|
@@ -133,6 +133,26 @@ If there are no changes to apply, the command succeeds gracefully:
|
|
|
133
133
|
✓ Stack my-stack is up to date (no changes)
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
+
### 👁️ preview-stack
|
|
137
|
+
|
|
138
|
+
Builds a change set (same capabilities as deploy), prints a **table of planned resource-level changes**, then **deletes** the change set without executing it. If the stack exists, uses an **UPDATE** change set; otherwise **CREATE**.
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
awscfn preview-stack -n <STACK_NAME> -t <TEMPLATE_FILE> -p <PARAMS_FILE>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
| Flag | Description |
|
|
145
|
+
|------|-------------|
|
|
146
|
+
| `--name`, `-n` | Stack name |
|
|
147
|
+
| `--template`, `-t` | CloudFormation template file |
|
|
148
|
+
| `--params`, `-p` | Parameters file (YAML) |
|
|
149
|
+
|
|
150
|
+
Use this to review Add / Modify / Remove actions (and replacement hints) before running **`create-stack`** or **`update-stack`**.
|
|
151
|
+
|
|
152
|
+
If the stack is **`ROLLBACK_COMPLETE`**, **`update-stack`** would delete and recreate it — **`preview-stack` cannot model that path** and exits with an error (delete the stack or run **`update-stack`** first).
|
|
153
|
+
|
|
154
|
+
Non-resource change-set entries (for example hooks) are counted and noted when they are not shown as table rows.
|
|
155
|
+
|
|
136
156
|
### ♻️ redeploy-stack
|
|
137
157
|
|
|
138
158
|
```bash
|
|
@@ -176,6 +196,10 @@ If the names don't match, the deletion will be aborted.
|
|
|
176
196
|
|
|
177
197
|
> ⚠️ Requires AWS credentials to be configured in your shell or environment. [Start here](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) if you haven't already.
|
|
178
198
|
|
|
199
|
+
### Nested stacks and IAM
|
|
200
|
+
|
|
201
|
+
Change sets request **`CAPABILITY_NAMED_IAM`** and **`CAPABILITY_AUTO_EXPAND`**, so stacks that define named IAM resources or **nested stacks** (including templates from [`aws cloudformation package`](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html)) work with **`create-stack`** / **`update-stack`** / **`preview-stack`** and the SDK `createStack` / `updateStack` / `previewChangeSet` helpers.
|
|
202
|
+
|
|
179
203
|
### 📋 `listStacks(): Promise<StackSummary[]>`
|
|
180
204
|
|
|
181
205
|
Returns all CloudFormation stacks in the current region (paginated). Excludes deleted stacks (`DELETE_COMPLETE`, `DELETE_IN_PROGRESS`) via `StackStatusFilter`. Each item is an AWS SDK `StackSummary` (e.g. `StackName`, `StackStatus`, `CreationTime`).
|
|
@@ -319,6 +343,25 @@ Reason: Resource handler returned message: "CannotPullContainerError: image not
|
|
|
319
343
|
|
|
320
344
|
> ✅ This function ensures safety by skipping updates for in-progress stacks and gracefully recovering from `ROLLBACK_COMPLETE` states.
|
|
321
345
|
|
|
346
|
+
### 👁️ `previewChangeSet(stackName, template, operation)` / `previewStack(...)`
|
|
347
|
+
|
|
348
|
+
**SDK:** Build a change set, print a colored table of planned resource changes (Add / Modify / Remove, replacement hints), then delete the change set — **without** executing it. Same capabilities as deploy (`CAPABILITY_NAMED_IAM`, `CAPABILITY_AUTO_EXPAND`).
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
import { initCloudFormationClient, previewChangeSet } from 'awscfn';
|
|
352
|
+
|
|
353
|
+
initCloudFormationClient();
|
|
354
|
+
|
|
355
|
+
await previewChangeSet('my-stack', {
|
|
356
|
+
body: templateString,
|
|
357
|
+
params: { Env: 'prod' },
|
|
358
|
+
}, 'UPDATE');
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**CLI:** Prefer `awscfn preview-stack -n … -t … -p …`, which picks **CREATE** vs **UPDATE** from whether the stack exists (same idea as deploy). Refuses **`ROLLBACK_COMPLETE`** stacks (same recovery path as **`update-stack`**: delete + create).
|
|
362
|
+
|
|
363
|
+
Table output lives in **`lib/formatChangeSet`** (shared formatting, not CLI-only).
|
|
364
|
+
|
|
322
365
|
## Contributing
|
|
323
366
|
|
|
324
367
|
- Open an [issue](https://github.com/mhweiner/awscfn/issues) for bugs or suggestions
|
package/bin/awscfn
CHANGED
|
@@ -7,6 +7,7 @@ const yargs = require('yargs');
|
|
|
7
7
|
const { createStack } = require('../dist/createStack');
|
|
8
8
|
const { deleteStack } = require('../dist/deleteStack');
|
|
9
9
|
const { listStacks } = require('../dist/listStacks');
|
|
10
|
+
const { previewStack } = require('../dist/previewStack');
|
|
10
11
|
const { redeployStack } = require('../dist/redeployStack');
|
|
11
12
|
const { updateStack } = require('../dist/updateStack');
|
|
12
13
|
const { getOutputConfig, setOutputConfig } = require('../dist/lib/output');
|
|
@@ -160,6 +161,14 @@ yargs
|
|
|
160
161
|
runCommand(() => updateStack(name, template, params));
|
|
161
162
|
}
|
|
162
163
|
)
|
|
164
|
+
.command(
|
|
165
|
+
'preview-stack',
|
|
166
|
+
'Preview changes without deploying (change set only)',
|
|
167
|
+
(cmd) => cmd.options({ ...nameOpt, ...templateOpt, ...paramsOpt }),
|
|
168
|
+
({ name, template, params }) => {
|
|
169
|
+
runCommand(() => previewStack(name, template, params));
|
|
170
|
+
}
|
|
171
|
+
)
|
|
163
172
|
.completion(
|
|
164
173
|
'completion',
|
|
165
174
|
'Generate shell completion script',
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.previewStack = void 0;
|
|
17
18
|
__exportStar(require("./lib/cfn"), exports);
|
|
18
19
|
__exportStar(require("./lib/output"), exports);
|
|
20
|
+
var previewStack_1 = require("./previewStack");
|
|
21
|
+
Object.defineProperty(exports, "previewStack", { enumerable: true, get: function () { return previewStack_1.previewStack; } });
|
|
19
22
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,+CAA6B;AAC7B,+CAA4C;AAApC,4GAAA,YAAY,OAAA"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { Template, TemplateParams } from './index';
|
|
2
|
-
type ChangeSetOperation = 'UPDATE' | 'CREATE';
|
|
2
|
+
export type ChangeSetOperation = 'UPDATE' | 'CREATE';
|
|
3
|
+
/**
|
|
4
|
+
* Create a change set and return its ARN/id (does not wait).
|
|
5
|
+
*/
|
|
6
|
+
export declare function submitChangeSetRequest<P extends TemplateParams>(stackName: string, template: Template<P>, operation: ChangeSetOperation): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Wait until the change set finishes building ({@link waitUntilChangeSetCreateComplete}) with spinner.
|
|
9
|
+
*/
|
|
10
|
+
export declare function waitForChangeSetBuild(changeSetId: string): Promise<void>;
|
|
3
11
|
export declare function createAndExecChangeSet<P extends TemplateParams>(stackName: string, template: Template<P>, operation: ChangeSetOperation): Promise<string>;
|
|
4
|
-
export {};
|
|
5
12
|
//# sourceMappingURL=executeChangeSet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeChangeSet.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/executeChangeSet.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAG9D,
|
|
1
|
+
{"version":3,"file":"executeChangeSet.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/executeChangeSet.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAG9D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAoBrD;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,SAAS,cAAc,EACjE,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,SAAS,EAAE,kBAAkB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB9E;AAiBD,wBAAsB,sBAAsB,CAAC,CAAC,SAAS,cAAc,EACjE,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,SAAS,EAAE,kBAAkB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAejB"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.submitChangeSetRequest = submitChangeSetRequest;
|
|
4
|
+
exports.waitForChangeSetBuild = waitForChangeSetBuild;
|
|
3
5
|
exports.createAndExecChangeSet = createAndExecChangeSet;
|
|
4
6
|
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
5
7
|
const index_1 = require("./index");
|
|
@@ -16,8 +18,10 @@ function toCfnParameters(params) {
|
|
|
16
18
|
ParameterValue: String(value),
|
|
17
19
|
}));
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Create a change set and return its ARN/id (does not wait).
|
|
23
|
+
*/
|
|
24
|
+
async function submitChangeSetRequest(stackName, template, operation) {
|
|
21
25
|
const cf = (0, index_1.getCfClient)();
|
|
22
26
|
const changeSetName = `${stackName}-rev-${Date.now()}`;
|
|
23
27
|
const templateBody = typeof template === 'string' ? template : template.body;
|
|
@@ -30,27 +34,38 @@ async function createChangeSet(stackName, template, operation) {
|
|
|
30
34
|
ChangeSetName: changeSetName,
|
|
31
35
|
ChangeSetType: operation,
|
|
32
36
|
Parameters: parameters,
|
|
33
|
-
Capabilities: ['CAPABILITY_NAMED_IAM'],
|
|
37
|
+
Capabilities: ['CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND'],
|
|
34
38
|
}));
|
|
39
|
+
return changeset.Id;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Wait until the change set finishes building ({@link waitUntilChangeSetCreateComplete}) with spinner.
|
|
43
|
+
*/
|
|
44
|
+
async function waitForChangeSetBuild(changeSetId) {
|
|
45
|
+
const cf = (0, index_1.getCfClient)();
|
|
35
46
|
const cfg = (0, output_1.getOutputConfig)();
|
|
36
47
|
const stopSpinner = cfg.ci ? null : (0, output_1.startSpinner)();
|
|
37
48
|
if (cfg.ci)
|
|
38
49
|
(0, output_1.dim)(` ${output_1.symbols.ellipsis} Waiting for changeset to be ready...`);
|
|
39
50
|
try {
|
|
40
51
|
await (0, client_cloudformation_1.waitUntilChangeSetCreateComplete)({ client: cf, maxWaitTime: 120 }, {
|
|
41
|
-
ChangeSetName:
|
|
52
|
+
ChangeSetName: changeSetId,
|
|
42
53
|
});
|
|
43
54
|
}
|
|
44
55
|
finally {
|
|
45
56
|
if (stopSpinner)
|
|
46
57
|
stopSpinner();
|
|
47
58
|
}
|
|
48
|
-
|
|
59
|
+
}
|
|
60
|
+
async function createChangeSetAndWait(stackName, template, operation) {
|
|
61
|
+
const changeSetId = await submitChangeSetRequest(stackName, template, operation);
|
|
62
|
+
await waitForChangeSetBuild(changeSetId);
|
|
63
|
+
return changeSetId;
|
|
49
64
|
}
|
|
50
65
|
async function createAndExecChangeSet(stackName, template, operation) {
|
|
51
66
|
(0, output_1.dim)(` ${output_1.symbols.bullet} Creating changeset ${(0, output_1.gray)(`(${operation.toLowerCase()})`)}`);
|
|
52
67
|
const cf = (0, index_1.getCfClient)();
|
|
53
|
-
const changeSetId = await
|
|
68
|
+
const changeSetId = await createChangeSetAndWait(stackName, template, operation);
|
|
54
69
|
(0, output_1.dim)(` ${output_1.symbols.bullet} Executing changeset...`);
|
|
55
70
|
await cf.send(new client_cloudformation_1.ExecuteChangeSetCommand({
|
|
56
71
|
ChangeSetName: changeSetId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeChangeSet.js","sourceRoot":"","sources":["../../../src/lib/cfn/executeChangeSet.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"executeChangeSet.js","sourceRoot":"","sources":["../../../src/lib/cfn/executeChangeSet.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/cfn/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare function getCfClient(): CloudFormationClient;
|
|
|
9
9
|
export * from './createStack';
|
|
10
10
|
export * from './getStackByName';
|
|
11
11
|
export * from './listStacks';
|
|
12
|
+
export * from './previewChangeSet';
|
|
12
13
|
export * from './updateStack';
|
|
13
14
|
export * from './deleteStack';
|
|
14
15
|
export * from './validateTemplate';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,gCAAgC,CAAC;AAEpE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACjD,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,cAAc,IAAI;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,CAAA;CACZ,GAAG,MAAM,CAAC;AAIX,wBAAgB,wBAAwB,IAAI,IAAI,CAI/C;AAED,wBAAgB,WAAW,IAAI,oBAAoB,CAMlD;AAED,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,gCAAgC,CAAC;AAEpE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACjD,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,cAAc,IAAI;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,CAAC,CAAA;CACZ,GAAG,MAAM,CAAC;AAIX,wBAAgB,wBAAwB,IAAI,IAAI,CAI/C;AAED,wBAAgB,WAAW,IAAI,oBAAoB,CAMlD;AAED,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
package/dist/lib/cfn/index.js
CHANGED
|
@@ -29,6 +29,7 @@ function getCfClient() {
|
|
|
29
29
|
__exportStar(require("./createStack"), exports);
|
|
30
30
|
__exportStar(require("./getStackByName"), exports);
|
|
31
31
|
__exportStar(require("./listStacks"), exports);
|
|
32
|
+
__exportStar(require("./previewChangeSet"), exports);
|
|
32
33
|
__exportStar(require("./updateStack"), exports);
|
|
33
34
|
__exportStar(require("./deleteStack"), exports);
|
|
34
35
|
__exportStar(require("./validateTemplate"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAUA,4DAIC;AAED,kCAMC;AAtBD,0EAAoE;AAQpE,IAAI,EAAkC,CAAC;AAEvC,SAAgB,wBAAwB;IAEpC,EAAE,GAAG,IAAI,4CAAoB,EAAE,CAAC;AAEpC,CAAC;AAED,SAAgB,WAAW;IAEvB,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAElE,OAAO,EAAE,CAAC;AAEd,CAAC;AAED,gDAA8B;AAC9B,mDAAiC;AACjC,+CAA6B;AAC7B,gDAA8B;AAC9B,gDAA8B;AAC9B,qDAAmC;AACnC,sDAAoC;AACpC,oDAAkC;AAClC,2DAAyC;AACzC,sDAAoC;AACpC,sDAAoC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/cfn/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAUA,4DAIC;AAED,kCAMC;AAtBD,0EAAoE;AAQpE,IAAI,EAAkC,CAAC;AAEvC,SAAgB,wBAAwB;IAEpC,EAAE,GAAG,IAAI,4CAAoB,EAAE,CAAC;AAEpC,CAAC;AAED,SAAgB,WAAW;IAEvB,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAElE,OAAO,EAAE,CAAC;AAEd,CAAC;AAED,gDAA8B;AAC9B,mDAAiC;AACjC,+CAA6B;AAC7B,qDAAmC;AACnC,gDAA8B;AAC9B,gDAA8B;AAC9B,qDAAmC;AACnC,sDAAoC;AACpC,oDAAkC;AAClC,2DAAyC;AACzC,sDAAoC;AACpC,sDAAoC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ChangeSetOperation } from './executeChangeSet';
|
|
2
|
+
import { Template, TemplateParams } from './index';
|
|
3
|
+
/**
|
|
4
|
+
* Build a change set, print planned resource changes (without executing), then delete the change set.
|
|
5
|
+
*/
|
|
6
|
+
export declare function previewChangeSet<P extends TemplateParams>(stackName: string, template: Template<P>, operation: ChangeSetOperation): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=previewChangeSet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"previewChangeSet.d.ts","sourceRoot":"","sources":["../../../src/lib/cfn/previewChangeSet.ts"],"names":[],"mappings":"AAOA,OAAO,EAGH,KAAK,kBAAkB,EAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AA2G9D;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,cAAc,EAC3D,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,SAAS,EAAE,kBAAkB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.previewChangeSet = previewChangeSet;
|
|
4
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
5
|
+
const formatChangeSet_1 = require("../formatChangeSet");
|
|
6
|
+
const executeChangeSet_1 = require("./executeChangeSet");
|
|
7
|
+
const index_1 = require("./index");
|
|
8
|
+
const output_1 = require("../output");
|
|
9
|
+
function isNoChangesOutcome(desc) {
|
|
10
|
+
const reason = desc.StatusReason ?? '';
|
|
11
|
+
return Boolean(desc.Status === 'FAILED'
|
|
12
|
+
&& (reason.includes('didn\'t contain changes')
|
|
13
|
+
|| reason.includes('No updates are to be performed')));
|
|
14
|
+
}
|
|
15
|
+
/** Merge paginated {@link DescribeChangeSetCommand} results so large change lists are complete. */
|
|
16
|
+
async function describeChangeSetPaginated(changeSetId) {
|
|
17
|
+
const cf = (0, index_1.getCfClient)();
|
|
18
|
+
let nextToken;
|
|
19
|
+
let first;
|
|
20
|
+
const allChanges = [];
|
|
21
|
+
do {
|
|
22
|
+
const page = await cf.send(new client_cloudformation_1.DescribeChangeSetCommand({
|
|
23
|
+
ChangeSetName: changeSetId,
|
|
24
|
+
NextToken: nextToken,
|
|
25
|
+
}));
|
|
26
|
+
if (!first) {
|
|
27
|
+
first = page;
|
|
28
|
+
}
|
|
29
|
+
allChanges.push(...(page.Changes ?? []));
|
|
30
|
+
nextToken = page.NextToken;
|
|
31
|
+
} while (nextToken);
|
|
32
|
+
return { ...(first ?? {}), Changes: allChanges };
|
|
33
|
+
}
|
|
34
|
+
async function deleteChangeSetQuiet(changeSetId) {
|
|
35
|
+
const cf = (0, index_1.getCfClient)();
|
|
36
|
+
try {
|
|
37
|
+
await cf.send(new client_cloudformation_1.DeleteChangeSetCommand({
|
|
38
|
+
ChangeSetName: changeSetId,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Best-effort cleanup after preview
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function printPlannedTable(stackName, desc) {
|
|
46
|
+
console.log('');
|
|
47
|
+
(0, output_1.info)(`${output_1.symbols.arrow} Planned resource changes for ${(0, output_1.cyan)(stackName)}`);
|
|
48
|
+
const lines = (0, formatChangeSet_1.formatChangeSetPreviewLines)(desc.Changes ?? []);
|
|
49
|
+
for (const line of lines)
|
|
50
|
+
console.log(line);
|
|
51
|
+
console.log('');
|
|
52
|
+
const statusNote = ` ${output_1.symbols.info} Change set status: ${desc.Status ?? 'unknown'}${desc.ExecutionStatus ? ` · execution: ${desc.ExecutionStatus}` : ''}`;
|
|
53
|
+
(0, output_1.dim)(statusNote);
|
|
54
|
+
(0, output_1.success)(`${output_1.symbols.check} Preview complete — change set was not executed`);
|
|
55
|
+
}
|
|
56
|
+
/** Fetch full change list after the SDK waiter finished building the change set (waiter polls status only). */
|
|
57
|
+
async function runPreviewFromBuiltChangeSet(stackName, changeSetId) {
|
|
58
|
+
const desc = await describeChangeSetPaginated(changeSetId);
|
|
59
|
+
if (isNoChangesOutcome(desc)) {
|
|
60
|
+
(0, output_1.success)(`${output_1.symbols.check} Stack ${(0, output_1.cyan)(stackName)} — no changes to apply`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (desc.Status !== 'CREATE_COMPLETE') {
|
|
64
|
+
throw new Error(desc.StatusReason ?? `Change set status: ${desc.Status ?? 'unknown'}`);
|
|
65
|
+
}
|
|
66
|
+
printPlannedTable(stackName, desc);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build a change set, print planned resource changes (without executing), then delete the change set.
|
|
70
|
+
*/
|
|
71
|
+
async function previewChangeSet(stackName, template, operation) {
|
|
72
|
+
(0, output_1.dim)(` ${output_1.symbols.bullet} Building change set ${(0, output_1.gray)(`(${operation.toLowerCase()} preview)`)}`);
|
|
73
|
+
const changeSetId = await (0, executeChangeSet_1.submitChangeSetRequest)(stackName, template, operation);
|
|
74
|
+
try {
|
|
75
|
+
try {
|
|
76
|
+
await (0, executeChangeSet_1.waitForChangeSetBuild)(changeSetId);
|
|
77
|
+
}
|
|
78
|
+
catch (waitErr) {
|
|
79
|
+
const descEarly = await describeChangeSetPaginated(changeSetId);
|
|
80
|
+
if (isNoChangesOutcome(descEarly)) {
|
|
81
|
+
(0, output_1.success)(`${output_1.symbols.check} Stack ${(0, output_1.cyan)(stackName)} — no changes to apply`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const detail = descEarly.StatusReason ?? 'Change set did not complete successfully';
|
|
85
|
+
if (waitErr instanceof Error) {
|
|
86
|
+
waitErr.message = `${detail} — ${waitErr.message}`;
|
|
87
|
+
throw waitErr;
|
|
88
|
+
}
|
|
89
|
+
throw new Error(detail, { cause: waitErr });
|
|
90
|
+
}
|
|
91
|
+
await runPreviewFromBuiltChangeSet(stackName, changeSetId);
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
await deleteChangeSetQuiet(changeSetId);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=previewChangeSet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"previewChangeSet.js","sourceRoot":"","sources":["../../../src/lib/cfn/previewChangeSet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Change } from '@aws-sdk/client-cloudformation';
|
|
2
|
+
/**
|
|
3
|
+
* Printable rows for a CloudFormation change set's {@link Change} list (resource-level rows).
|
|
4
|
+
* Sorts by logical resource id for stable output.
|
|
5
|
+
* Non-resource entries (e.g. hooks) are counted but not tabulated.
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatChangeSetPreviewLines(changes: Change[], opts?: {
|
|
8
|
+
color?: boolean;
|
|
9
|
+
}): string[];
|
|
10
|
+
//# sourceMappingURL=formatChangeSet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatChangeSet.d.ts","sourceRoot":"","sources":["../../src/lib/formatChangeSet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAiB,MAAM,gCAAgC,CAAC;AAyE3E;;;;GAIG;AACH,wBAAgB,2BAA2B,CACvC,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,CAAC,EAAE;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,GACzB,MAAM,EAAE,CA2CV"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatChangeSetPreviewLines = formatChangeSetPreviewLines;
|
|
4
|
+
const output_1 = require("./output");
|
|
5
|
+
const colors = {
|
|
6
|
+
dim: '\x1b[2m',
|
|
7
|
+
gray: '\x1b[90m',
|
|
8
|
+
};
|
|
9
|
+
function pickActionStyle(action) {
|
|
10
|
+
if (action === 'Add')
|
|
11
|
+
return output_1.green;
|
|
12
|
+
if (action === 'Remove')
|
|
13
|
+
return output_1.red;
|
|
14
|
+
if (action === 'Modify')
|
|
15
|
+
return output_1.yellow;
|
|
16
|
+
if (action === 'Import')
|
|
17
|
+
return output_1.cyan;
|
|
18
|
+
return (t) => t;
|
|
19
|
+
}
|
|
20
|
+
function padRight(s, width) {
|
|
21
|
+
return s.length >= width ? s : s + ' '.repeat(width - s.length);
|
|
22
|
+
}
|
|
23
|
+
/** Entries such as hooks or future types that do not carry {@link ResourceChange}. */
|
|
24
|
+
function countNonResourceEntries(changes) {
|
|
25
|
+
return changes.filter((c) => !c.ResourceChange).length;
|
|
26
|
+
}
|
|
27
|
+
function resourceRows(resourceChanges, maxLogical, maxType, configColor) {
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const r of resourceChanges) {
|
|
30
|
+
const logical = padRight(r.LogicalResourceId ?? '—', maxLogical);
|
|
31
|
+
const resType = padRight(r.ResourceType ?? '—', maxType);
|
|
32
|
+
const replacement = r.Replacement ?? '—';
|
|
33
|
+
const style = pickActionStyle(r.Action);
|
|
34
|
+
const rawAction = r.Action ?? '—';
|
|
35
|
+
const actionCell = configColor
|
|
36
|
+
? style(rawAction) + ' '.repeat(Math.max(0, 10 - rawAction.length))
|
|
37
|
+
: rawAction.padEnd(10);
|
|
38
|
+
out.push(` ${actionCell} ${logical} ${resType} ${replacement}`);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
function sortedResourceChanges(changes) {
|
|
43
|
+
const resourceChanges = changes
|
|
44
|
+
.map((c) => c.ResourceChange)
|
|
45
|
+
.filter((rc) => Boolean(rc));
|
|
46
|
+
resourceChanges.sort((a, b) => (a.LogicalResourceId ?? '').localeCompare(b.LogicalResourceId ?? ''));
|
|
47
|
+
return resourceChanges;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Printable rows for a CloudFormation change set's {@link Change} list (resource-level rows).
|
|
51
|
+
* Sorts by logical resource id for stable output.
|
|
52
|
+
* Non-resource entries (e.g. hooks) are counted but not tabulated.
|
|
53
|
+
*/
|
|
54
|
+
function formatChangeSetPreviewLines(changes, opts) {
|
|
55
|
+
const configColor = opts?.color ?? (0, output_1.getOutputConfig)().color;
|
|
56
|
+
const resourceChanges = sortedResourceChanges(changes);
|
|
57
|
+
const nonResourceCount = countNonResourceEntries(changes);
|
|
58
|
+
if (resourceChanges.length === 0) {
|
|
59
|
+
if (nonResourceCount > 0) {
|
|
60
|
+
const msg = ` (no resource-level rows — ${nonResourceCount} other change entr${nonResourceCount === 1 ? 'y' : 'ies'}, e.g. hooks)`;
|
|
61
|
+
return [configColor ? (0, output_1.gray)(msg) : msg];
|
|
62
|
+
}
|
|
63
|
+
return [' (no resource-level changes in this change set)'];
|
|
64
|
+
}
|
|
65
|
+
const maxLogical = Math.max(14, ...resourceChanges.map((r) => (r.LogicalResourceId ?? '').length));
|
|
66
|
+
const maxType = Math.max(12, ...resourceChanges.map((r) => (r.ResourceType ?? '').length));
|
|
67
|
+
const headerLine = `${padRight('ACTION', 10)} ${padRight('LOGICAL ID', maxLogical)} `
|
|
68
|
+
+ `${padRight('RESOURCE TYPE', maxType)} REPLACE`;
|
|
69
|
+
const divider = '-'.repeat(headerLine.length);
|
|
70
|
+
const lines = [
|
|
71
|
+
configColor ? (0, output_1.colorize)(headerLine, colors.dim) : headerLine,
|
|
72
|
+
configColor ? (0, output_1.colorize)(divider, colors.gray) : divider,
|
|
73
|
+
...resourceRows(resourceChanges, maxLogical, maxType, configColor),
|
|
74
|
+
];
|
|
75
|
+
if (nonResourceCount > 0) {
|
|
76
|
+
const note = ` (${nonResourceCount} non-resource change${nonResourceCount === 1 ? '' : 's'} omitted from table — e.g. hooks)`;
|
|
77
|
+
lines.push(configColor ? (0, output_1.gray)(note) : note);
|
|
78
|
+
}
|
|
79
|
+
return lines;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=formatChangeSet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatChangeSet.js","sourceRoot":"","sources":["../../src/lib/formatChangeSet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatChangeSet.spec.d.ts","sourceRoot":"","sources":["../../src/lib/formatChangeSet.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const kizu_1 = require("kizu");
|
|
4
|
+
const formatChangeSet_1 = require("./formatChangeSet");
|
|
5
|
+
(0, kizu_1.test)('formatChangeSetPreviewLines sorts by logical id and prints columns', (assert) => {
|
|
6
|
+
const changes = [
|
|
7
|
+
{
|
|
8
|
+
Type: 'Resource',
|
|
9
|
+
ResourceChange: {
|
|
10
|
+
Action: 'Modify',
|
|
11
|
+
LogicalResourceId: 'B',
|
|
12
|
+
ResourceType: 'AWS::S3::Bucket',
|
|
13
|
+
Replacement: 'False',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
Type: 'Resource',
|
|
18
|
+
ResourceChange: {
|
|
19
|
+
Action: 'Add',
|
|
20
|
+
LogicalResourceId: 'A',
|
|
21
|
+
ResourceType: 'AWS::IAM::Role',
|
|
22
|
+
Replacement: 'False',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
const lines = (0, formatChangeSet_1.formatChangeSetPreviewLines)(changes, { color: false });
|
|
27
|
+
const text = lines.join('\n');
|
|
28
|
+
assert.equal(text.includes('LOGICAL ID'), true);
|
|
29
|
+
assert.equal(text.includes('RESOURCE TYPE'), true);
|
|
30
|
+
assert.equal(text.includes('AWS::IAM::Role'), true);
|
|
31
|
+
assert.equal(text.includes('AWS::S3::Bucket'), true);
|
|
32
|
+
const dataLines = lines.filter((l) => l.includes('Add') && l.includes('A'));
|
|
33
|
+
assert.equal(dataLines.length >= 1, true);
|
|
34
|
+
});
|
|
35
|
+
(0, kizu_1.test)('formatChangeSetPreviewLines empty changes', (assert) => {
|
|
36
|
+
const lines = (0, formatChangeSet_1.formatChangeSetPreviewLines)([], { color: false });
|
|
37
|
+
assert.equal(lines.length, 1);
|
|
38
|
+
assert.equal(lines[0].includes('no resource-level'), true);
|
|
39
|
+
});
|
|
40
|
+
(0, kizu_1.test)('formatChangeSetPreviewLines counts non-resource-only changes', (assert) => {
|
|
41
|
+
const changes = [
|
|
42
|
+
{
|
|
43
|
+
Type: 'Resource',
|
|
44
|
+
HookInvocationCount: 1,
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
const lines = (0, formatChangeSet_1.formatChangeSetPreviewLines)(changes, { color: false });
|
|
48
|
+
assert.equal(lines.length, 1);
|
|
49
|
+
assert.equal(lines[0].includes('other change'), true);
|
|
50
|
+
});
|
|
51
|
+
(0, kizu_1.test)('formatChangeSetPreviewLines footer when mixed resource and non-resource', (assert) => {
|
|
52
|
+
const changes = [
|
|
53
|
+
{
|
|
54
|
+
Type: 'Resource',
|
|
55
|
+
ResourceChange: {
|
|
56
|
+
Action: 'Add',
|
|
57
|
+
LogicalResourceId: 'R',
|
|
58
|
+
ResourceType: 'AWS::SNS::Topic',
|
|
59
|
+
Replacement: 'False',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
Type: 'Resource',
|
|
64
|
+
HookInvocationCount: 2,
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
const lines = (0, formatChangeSet_1.formatChangeSetPreviewLines)(changes, { color: false });
|
|
68
|
+
const text = lines.join('\n');
|
|
69
|
+
assert.equal(text.includes('AWS::SNS::Topic'), true);
|
|
70
|
+
assert.equal(text.includes('non-resource'), true);
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=formatChangeSet.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatChangeSet.spec.js","sourceRoot":"","sources":["../../src/lib/formatChangeSet.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI: preview stack changes without executing (build change set, print table, delete change set).
|
|
3
|
+
* CREATE vs UPDATE matches whether the stack already exists.
|
|
4
|
+
*/
|
|
5
|
+
export declare function previewStack(stackName: string, templatePath: string, paramsPath?: string): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=previewStack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"previewStack.d.ts","sourceRoot":"","sources":["../src/previewStack.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAsB,YAAY,CAC9B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.previewStack = previewStack;
|
|
37
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
38
|
+
const cfn = __importStar(require("./lib/cfn"));
|
|
39
|
+
const loadTemplateAndParams_1 = require("./cli/loadTemplateAndParams");
|
|
40
|
+
const validateTemplate_1 = require("./cli/validateTemplate");
|
|
41
|
+
const output_1 = require("./lib/output");
|
|
42
|
+
/**
|
|
43
|
+
* CLI: preview stack changes without executing (build change set, print table, delete change set).
|
|
44
|
+
* CREATE vs UPDATE matches whether the stack already exists.
|
|
45
|
+
*/
|
|
46
|
+
async function previewStack(stackName, templatePath, paramsPath) {
|
|
47
|
+
cfn.initCloudFormationClient();
|
|
48
|
+
const { template, params } = await (0, loadTemplateAndParams_1.loadTemplateAndParams)(templatePath, paramsPath);
|
|
49
|
+
const existing = await cfn.getStackByName(stackName);
|
|
50
|
+
if (existing?.StackStatus === client_cloudformation_1.StackStatus.ROLLBACK_COMPLETE) {
|
|
51
|
+
(0, output_1.warn)(`Stack ${stackName} is in ROLLBACK_COMPLETE; update-stack would delete and recreate it. `
|
|
52
|
+
+ 'Preview cannot model that flow.');
|
|
53
|
+
throw new Error('cannot preview: stack is ROLLBACK_COMPLETE — delete the stack or run update-stack (delete + create) first.');
|
|
54
|
+
}
|
|
55
|
+
console.log('validating template...');
|
|
56
|
+
await (0, validateTemplate_1.validateTemplateOrExit)(template);
|
|
57
|
+
const operation = existing ? 'UPDATE' : 'CREATE';
|
|
58
|
+
(0, output_1.info)(`${output_1.symbols.arrow} Preview ${(0, output_1.cyan)(operation)} for stack ${(0, output_1.cyan)(stackName)}`);
|
|
59
|
+
await cfn.previewChangeSet(stackName, { body: template, params }, operation);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=previewStack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"previewStack.js","sourceRoot":"","sources":["../src/previewStack.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,oCAiCC;AA3CD,0EAA2D;AAC3D,+CAAiC;AACjC,uEAAkE;AAClE,6DAA8D;AAC9D,yCAAuD;AAEvD;;;GAGG;AACI,KAAK,UAAU,YAAY,CAC9B,SAAiB,EACjB,YAAoB,EACpB,UAAmB;IAGnB,GAAG,CAAC,wBAAwB,EAAE,CAAC;IAE/B,MAAM,EAAC,QAAQ,EAAE,MAAM,EAAC,GAAG,MAAM,IAAA,6CAAqB,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAErD,IAAI,QAAQ,EAAE,WAAW,KAAK,mCAAW,CAAC,iBAAiB,EAAE,CAAC;QAE1D,IAAA,aAAI,EACA,SAAS,SAAS,uEAAuE;cACvF,iCAAiC,CACtC,CAAC;QAEF,MAAM,IAAI,KAAK,CACX,4GAA4G,CAC/G,CAAC;IAEN,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,MAAM,IAAA,yCAAsB,EAAC,QAAQ,CAAC,CAAC;IAEvC,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEjD,IAAA,aAAI,EAAC,GAAG,gBAAO,CAAC,KAAK,YAAY,IAAA,aAAI,EAAC,SAAS,CAAC,cAAc,IAAA,aAAI,EAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAEjF,MAAM,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAC,EAAE,SAAS,CAAC,CAAC;AAE/E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"placeholder.spec.d.ts","sourceRoot":"","sources":["../../src/lib/placeholder.spec.ts"],"names":[],"mappings":""}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const kizu_1 = require("kizu");
|
|
4
|
-
(0, kizu_1.test)('awscfn test suite placeholder', (assert) => {
|
|
5
|
-
// No tests yet; remove this file when adding real specs.
|
|
6
|
-
assert.equal(1, 1);
|
|
7
|
-
});
|
|
8
|
-
//# sourceMappingURL=placeholder.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"placeholder.spec.js","sourceRoot":"","sources":["../../src/lib/placeholder.spec.ts"],"names":[],"mappings":";;AAAA,+BAA0B;AAE1B,IAAA,WAAI,EAAC,+BAA+B,EAAE,CAAC,MAAM,EAAE,EAAE;IAE7C,yDAAyD;IACzD,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEvB,CAAC,CAAC,CAAC"}
|