@guardian/cdk 49.0.2-beta.1 → 49.0.3
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/lib/constructs/iam/policies/index.d.ts +0 -1
- package/lib/constructs/iam/policies/index.d.ts.map +1 -1
- package/lib/constructs/iam/policies/index.js +0 -1
- package/lib/constructs/iam/policies/index.js.map +1 -1
- package/lib/constructs/iam/roles/instance-role.d.ts.map +1 -1
- package/lib/constructs/iam/roles/instance-role.js +2 -1
- package/lib/constructs/iam/roles/instance-role.js.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/group-by.d.ts.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/group-by.js +11 -5
- package/lib/experimental/riff-raff-yaml-file/group-by.js.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/index.d.ts +7 -7
- package/lib/experimental/riff-raff-yaml-file/index.d.ts.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/index.js +44 -49
- package/lib/experimental/riff-raff-yaml-file/index.js.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/types.d.ts +2 -1
- package/lib/experimental/riff-raff-yaml-file/types.d.ts.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/types.js.map +1 -1
- package/package.json +4 -4
- package/lib/constructs/iam/policies/ssm.d.ts +0 -8
- package/lib/constructs/iam/policies/ssm.d.ts.map +0 -1
- package/lib/constructs/iam/policies/ssm.js +0 -37
- package/lib/constructs/iam/policies/ssm.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC"}
|
|
@@ -25,5 +25,4 @@ __exportStar(require("./parameter-store-read"), exports);
|
|
|
25
25
|
__exportStar(require("./s3-get-object"), exports);
|
|
26
26
|
__exportStar(require("./s3-put-object"), exports);
|
|
27
27
|
__exportStar(require("./ses"), exports);
|
|
28
|
-
__exportStar(require("./ssm"), exports);
|
|
29
28
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,+CAA6B;AAC7B,iDAA+B;AAC/B,6CAA2B;AAC3B,iDAA+B;AAC/B,yDAAuC;AACvC,kDAAgC;AAChC,kDAAgC;AAChC,wCAAsB
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,+CAA6B;AAC7B,iDAA+B;AAC/B,6CAA2B;AAC3B,iDAA+B;AAC/B,yDAAuC;AACvC,kDAAgC;AAChC,kDAAgC;AAChC,wCAAsB","sourcesContent":["export * from \"./anghammarad\";\nexport * from \"./assume-role\";\nexport * from \"./base-policy\";\nexport * from \"./cloudwatch\";\nexport * from \"./describe-ec2\";\nexport * from \"./dynamodb\";\nexport * from \"./log-shipping\";\nexport * from \"./parameter-store-read\";\nexport * from \"./s3-get-object\";\nexport * from \"./s3-put-object\";\nexport * from \"./ses\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance-role.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"instance-role.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAOvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC;CACjC;AAED,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG,WAAW,CAAC;;;;;;AAE3E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,SAAQ,mBAA2B;gBACjD,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,0BAA0B;CAwB9D"}
|
|
@@ -28,7 +28,6 @@ class GuInstanceRole extends (0, app_aware_construct_1.GuAppAwareConstruct)(role
|
|
|
28
28
|
...props,
|
|
29
29
|
});
|
|
30
30
|
const sharedPolicies = [
|
|
31
|
-
policies_1.GuSSMRunCommandPolicy.getInstance(scope),
|
|
32
31
|
policies_1.GuDescribeEC2Policy.getInstance(scope),
|
|
33
32
|
...(props.withoutLogShipping ? [] : [policies_1.GuLogShippingPolicy.getInstance(scope)]),
|
|
34
33
|
];
|
|
@@ -38,7 +37,9 @@ class GuInstanceRole extends (0, app_aware_construct_1.GuAppAwareConstruct)(role
|
|
|
38
37
|
new policies_1.GuParameterStoreReadPolicy(scope, props),
|
|
39
38
|
...(props.additionalPolicies ? props.additionalPolicies : []),
|
|
40
39
|
];
|
|
40
|
+
const managedPolicies = [aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")];
|
|
41
41
|
policies.forEach((p) => p.attachToRole(this));
|
|
42
|
+
managedPolicies.forEach((p) => this.addManagedPolicy(p));
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
exports.GuInstanceRole = GuInstanceRole;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance-role.js","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"instance-role.js","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":";;;AAAA,iDAAsE;AACtE,kFAA+E;AAE/E,0CAKqB;AAErB,mCAAiC;AAgBjC;;;;;;;;;;;;;;GAcG;AACH,MAAa,cAAe,SAAQ,IAAA,yCAAmB,EAAC,cAAM,CAAC;IAC7D,YAAY,KAAc,EAAE,KAAiC;QAC3D,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE;YAC3B,IAAI,EAAE,GAAG;YACT,SAAS,EAAE,IAAI,0BAAgB,CAAC,mBAAmB,CAAC;YACpD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG;YACrB,8BAAmB,CAAC,WAAW,CAAC,KAAK,CAAC;YACtC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,8BAAmB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;SAC9E,CAAC;QAEF,MAAM,QAAQ,GAAG;YACf,GAAG,cAAc;YACjB,IAAI,mCAAwB,CAAC,KAAK,EAAE,KAAK,CAAC;YAC1C,IAAI,qCAA0B,CAAC,KAAK,EAAE,KAAK,CAAC;YAC5C,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC;QAEF,MAAM,eAAe,GAAG,CAAC,uBAAa,CAAC,wBAAwB,CAAC,8BAA8B,CAAC,CAAC,CAAC;QAEjG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF;AAzBD,wCAyBC","sourcesContent":["import { ManagedPolicy, ServicePrincipal } from \"aws-cdk-lib/aws-iam\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { AppIdentity, GuStack } from \"../../core\";\nimport {\n GuDescribeEC2Policy,\n GuGetDistributablePolicy,\n GuLogShippingPolicy,\n GuParameterStoreReadPolicy,\n} from \"../policies\";\nimport type { GuPolicy } from \"../policies\";\nimport { GuRole } from \"./roles\";\n\nexport interface GuInstanceRoleProps {\n /**\n * By default, instances are given permissions to write to Kinesis. Set to\n * 'true' to prevent this. Note, disabling will prevent not just application\n * logs being shipped but also anything else - for example, automatic log\n * shipping of Cloud Init and other logs by the cdk-base role in your AMI.\n */\n withoutLogShipping?: boolean;\n\n additionalPolicies?: GuPolicy[];\n}\n\nexport type GuInstanceRolePropsWithApp = GuInstanceRoleProps & AppIdentity;\n\n/**\n * Creates an IAM role with common policies that are needed by most Guardian applications.\n *\n * More specifically:\n * 1. Allows for `ssh` access to an EC2 instance via [ssm-scala](https://github.com/guardian/ssm-scala) (instead of standard `ssh`).\n * 2. Allows EC2 instances to communicate with Wazuh, for security monitoring.\n * 3. Allows EC2 instances to download an artifact from AWS S3, for application deployment.\n * 4. Allows EC2 instances to download private configuration from AWS Parameter Store. See [[`GuParameterStoreReadPolicy`]]\n * for specific details.\n * 5. Allows EC2 instances to write logs into our central ELK stack via Kinesis.\n *\n * If additional IAM permissions are required, create custom policies and pass them in via the `additionalPolicies` prop.\n *\n * If log shipping is not required, opt out by setting the `withoutLogShipping` prop to `true`.\n */\nexport class GuInstanceRole extends GuAppAwareConstruct(GuRole) {\n constructor(scope: GuStack, props: GuInstanceRolePropsWithApp) {\n super(scope, \"InstanceRole\", {\n path: \"/\",\n assumedBy: new ServicePrincipal(\"ec2.amazonaws.com\"),\n ...props,\n });\n\n const sharedPolicies = [\n GuDescribeEC2Policy.getInstance(scope),\n ...(props.withoutLogShipping ? [] : [GuLogShippingPolicy.getInstance(scope)]),\n ];\n\n const policies = [\n ...sharedPolicies,\n new GuGetDistributablePolicy(scope, props),\n new GuParameterStoreReadPolicy(scope, props),\n ...(props.additionalPolicies ? props.additionalPolicies : []),\n ];\n\n const managedPolicies = [ManagedPolicy.fromAwsManagedPolicyName(\"AmazonSSMManagedInstanceCore\")];\n\n policies.forEach((p) => p.attachToRole(this));\n managedPolicies.forEach((p) => this.addManagedPolicy(p));\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-by.d.ts","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/group-by.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"group-by.d.ts","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/group-by.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAa,gBAAgB,EAA8B,MAAM,SAAS,CAAC;AAkBvF,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAoBvF"}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.groupByClassNameStackRegionStage = void 0;
|
|
4
4
|
const array_1 = require("../../utils/array");
|
|
5
|
+
function groupByClassName(cdkStacks) {
|
|
6
|
+
return (0, array_1.groupBy)(cdkStacks, (stack) => stack.constructor.name);
|
|
7
|
+
}
|
|
5
8
|
function groupByStackTag(cdkStacks) {
|
|
6
9
|
return (0, array_1.groupBy)(cdkStacks, ({ stack }) => stack);
|
|
7
10
|
}
|
|
@@ -12,11 +15,14 @@ function groupByRegion(cdkStacks) {
|
|
|
12
15
|
return (0, array_1.groupBy)(cdkStacks, ({ region }) => region);
|
|
13
16
|
}
|
|
14
17
|
function groupByClassNameStackRegionStage(cdkStacks) {
|
|
15
|
-
return Object.entries(
|
|
16
|
-
...
|
|
17
|
-
[
|
|
18
|
-
...
|
|
19
|
-
[
|
|
18
|
+
return Object.entries(groupByClassName(cdkStacks)).reduce((accClassName, [className, stacksGroupedByClassName]) => ({
|
|
19
|
+
...accClassName,
|
|
20
|
+
[className]: Object.entries(groupByStackTag(stacksGroupedByClassName)).reduce((accStackTag, [stackTag, stacksGroupedByStackTag]) => ({
|
|
21
|
+
...accStackTag,
|
|
22
|
+
[stackTag]: Object.entries(groupByRegion(stacksGroupedByStackTag)).reduce((accRegion, [region, stacksGroupedByRegion]) => ({
|
|
23
|
+
...accRegion,
|
|
24
|
+
[region]: groupByStageTag(stacksGroupedByRegion),
|
|
25
|
+
}), {}),
|
|
20
26
|
}), {}),
|
|
21
27
|
}), {});
|
|
22
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-by.js","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/group-by.ts"],"names":[],"mappings":";;;AACA,6CAA4C;AAG5C,SAAS,eAAe,CAAC,SAAoB;IAC3C,OAAO,IAAA,eAAO,EAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,eAAe,CAAC,SAAoB;IAC3C,OAAO,IAAA,eAAO,EAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,aAAa,CAAC,SAAoB;IACzC,OAAO,IAAA,eAAO,EAAC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,SAAgB,gCAAgC,CAAC,SAAoB;IACnE,OAAO,MAAM,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"group-by.js","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/group-by.ts"],"names":[],"mappings":";;;AACA,6CAA4C;AAG5C,SAAS,gBAAgB,CAAC,SAAoB;IAC5C,OAAO,IAAA,eAAO,EAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,eAAe,CAAC,SAAoB;IAC3C,OAAO,IAAA,eAAO,EAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,eAAe,CAAC,SAAoB;IAC3C,OAAO,IAAA,eAAO,EAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,aAAa,CAAC,SAAoB;IACzC,OAAO,IAAA,eAAO,EAAC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,SAAgB,gCAAgC,CAAC,SAAoB;IACnE,OAAO,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CACvD,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,wBAAwB,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,GAAG,YAAY;QACf,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAAC,CAAC,MAAM,CAC3E,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,uBAAuB,CAAC,EAAE,EAAE,CAAC,CAAC;YACrD,GAAG,WAAW;YACd,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC,CAAC,MAAM,CACvE,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/C,GAAG,SAAS;gBACZ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC,qBAAqB,CAAC;aACjD,CAAC,EACF,EAAE,CACH;SACF,CAAC,EACF,EAAE,CACH;KACF,CAAC,EACF,EAAE,CACH,CAAC;AACJ,CAAC;AApBD,4EAoBC","sourcesContent":["import type { GuStack } from \"../../constructs/core\";\nimport { groupBy } from \"../../utils/array\";\nimport type { ClassName, GroupedCdkStacks, Region, StackTag, StageTag } from \"./types\";\n\nfunction groupByClassName(cdkStacks: GuStack[]): Record<ClassName, GuStack[]> {\n return groupBy(cdkStacks, (stack) => stack.constructor.name);\n}\n\nfunction groupByStackTag(cdkStacks: GuStack[]): Record<StackTag, GuStack[]> {\n return groupBy(cdkStacks, ({ stack }) => stack);\n}\n\nfunction groupByStageTag(cdkStacks: GuStack[]): Record<StageTag, GuStack[]> {\n return groupBy(cdkStacks, ({ stage }) => stage);\n}\n\nfunction groupByRegion(cdkStacks: GuStack[]): Record<Region, GuStack[]> {\n return groupBy(cdkStacks, ({ region }) => region);\n}\n\nexport function groupByClassNameStackRegionStage(cdkStacks: GuStack[]): GroupedCdkStacks {\n return Object.entries(groupByClassName(cdkStacks)).reduce(\n (accClassName, [className, stacksGroupedByClassName]) => ({\n ...accClassName,\n [className]: Object.entries(groupByStackTag(stacksGroupedByClassName)).reduce(\n (accStackTag, [stackTag, stacksGroupedByStackTag]) => ({\n ...accStackTag,\n [stackTag]: Object.entries(groupByRegion(stacksGroupedByStackTag)).reduce(\n (accRegion, [region, stacksGroupedByRegion]) => ({\n ...accRegion,\n [region]: groupByStageTag(stacksGroupedByRegion),\n }),\n {}\n ),\n }),\n {}\n ),\n }),\n {}\n );\n}\n"]}
|
|
@@ -52,7 +52,7 @@ export declare class RiffRaffYamlFileExperimental {
|
|
|
52
52
|
private isCdkStackPresent;
|
|
53
53
|
/**
|
|
54
54
|
* Check there are the appropriate number of `GuStack`s.
|
|
55
|
-
* Expect to find an instance for each combination of `stack`,
|
|
55
|
+
* Expect to find an instance for each combination of `stack`, and `stage`.
|
|
56
56
|
*
|
|
57
57
|
* If not valid, a message is logged describing what is missing to aid debugging.
|
|
58
58
|
*
|
|
@@ -94,12 +94,12 @@ export declare class RiffRaffYamlFileExperimental {
|
|
|
94
94
|
* ```log
|
|
95
95
|
* Unable to produce a working riff-raff.yaml file; missing 1 definitions (details below)
|
|
96
96
|
*
|
|
97
|
-
*
|
|
98
|
-
* │ (index) │
|
|
99
|
-
*
|
|
100
|
-
* │ deploy │
|
|
101
|
-
* │ media-service │
|
|
102
|
-
*
|
|
97
|
+
* ┌───────────────┬──────┬──────┐
|
|
98
|
+
* │ (index) │ CODE │ PROD │
|
|
99
|
+
* ├───────────────┼──────┼──────┤
|
|
100
|
+
* │ deploy │ '✅' │ '✅' │
|
|
101
|
+
* │ media-service │ '❌' │ '✅' │
|
|
102
|
+
* └───────────────┴──────┴──────┘
|
|
103
103
|
* ```
|
|
104
104
|
*
|
|
105
105
|
* @private
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAqBvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAY;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IAEtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,iBAAiB;IASzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqDG;IACH,OAAO,CAAC,mBAAmB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAqBvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAY;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IAEtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,iBAAiB;IASzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqDG;IACH,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,6BAA6B;IAQrC,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,oBAAoB;gBAKhB,GAAG,EAAE,GAAG;IA8DpB;;;OAGG;IACH,MAAM,IAAI,MAAM;IAiBhB;;;OAGG;IACH,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -59,16 +59,16 @@ const group_by_1 = require("./group-by");
|
|
|
59
59
|
* @see https://riffraff.gutools.co.uk/docs/magenta-lib/types
|
|
60
60
|
*/
|
|
61
61
|
class RiffRaffYamlFileExperimental {
|
|
62
|
-
isCdkStackPresent(expectedStack,
|
|
62
|
+
isCdkStackPresent(expectedStack, expectedStage) {
|
|
63
63
|
const matches = this.allCdkStacks.find((cdkStack) => {
|
|
64
|
-
const { stack, stage
|
|
65
|
-
return stack === expectedStack && stage === expectedStage
|
|
64
|
+
const { stack, stage } = cdkStack;
|
|
65
|
+
return stack === expectedStack && stage === expectedStage;
|
|
66
66
|
});
|
|
67
67
|
return !!matches;
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Check there are the appropriate number of `GuStack`s.
|
|
71
|
-
* Expect to find an instance for each combination of `stack`,
|
|
71
|
+
* Expect to find an instance for each combination of `stack`, and `stage`.
|
|
72
72
|
*
|
|
73
73
|
* If not valid, a message is logged describing what is missing to aid debugging.
|
|
74
74
|
*
|
|
@@ -110,38 +110,31 @@ class RiffRaffYamlFileExperimental {
|
|
|
110
110
|
* ```log
|
|
111
111
|
* Unable to produce a working riff-raff.yaml file; missing 1 definitions (details below)
|
|
112
112
|
*
|
|
113
|
-
*
|
|
114
|
-
* │ (index) │
|
|
115
|
-
*
|
|
116
|
-
* │ deploy │
|
|
117
|
-
* │ media-service │
|
|
118
|
-
*
|
|
113
|
+
* ┌───────────────┬──────┬──────┐
|
|
114
|
+
* │ (index) │ CODE │ PROD │
|
|
115
|
+
* ├───────────────┼──────┼──────┤
|
|
116
|
+
* │ deploy │ '✅' │ '✅' │
|
|
117
|
+
* │ media-service │ '❌' │ '✅' │
|
|
118
|
+
* └───────────────┴──────┴──────┘
|
|
119
119
|
* ```
|
|
120
120
|
*
|
|
121
121
|
* @private
|
|
122
122
|
*/
|
|
123
123
|
validateStacksInApp() {
|
|
124
|
-
const { allStackTags, allStageTags
|
|
124
|
+
const { allStackTags, allStageTags } = this;
|
|
125
125
|
const checks = allStackTags.reduce((accStackTag, stackTag) => {
|
|
126
126
|
return {
|
|
127
127
|
...accStackTag,
|
|
128
|
-
[stackTag]:
|
|
128
|
+
[stackTag]: allStageTags.reduce((accStageTag, stageTag) => {
|
|
129
129
|
return {
|
|
130
|
-
...
|
|
131
|
-
[
|
|
132
|
-
return {
|
|
133
|
-
...accStageTag,
|
|
134
|
-
[stageTag]: this.isCdkStackPresent(stackTag, region, stageTag) ? "✅" : "❌",
|
|
135
|
-
};
|
|
136
|
-
}, {}),
|
|
130
|
+
...accStageTag,
|
|
131
|
+
[stageTag]: this.isCdkStackPresent(stackTag, stageTag) ? "✅" : "❌",
|
|
137
132
|
};
|
|
138
133
|
}, {}),
|
|
139
134
|
};
|
|
140
135
|
}, {});
|
|
141
|
-
const missingDefinitions = Object.values(checks).flatMap((
|
|
142
|
-
return Object.values(
|
|
143
|
-
return Object.values(groupedByStage).filter((_) => _ === "❌");
|
|
144
|
-
});
|
|
136
|
+
const missingDefinitions = Object.values(checks).flatMap((groupedByStackTag) => {
|
|
137
|
+
return Object.values(groupedByStackTag).filter((_) => _ === "❌");
|
|
145
138
|
});
|
|
146
139
|
if (missingDefinitions.length > 0) {
|
|
147
140
|
const message = `Unable to produce a working riff-raff.yaml file; missing ${missingDefinitions.length} definitions`;
|
|
@@ -174,32 +167,34 @@ class RiffRaffYamlFileExperimental {
|
|
|
174
167
|
this.outdir = app.outdir;
|
|
175
168
|
const deployments = new Map();
|
|
176
169
|
const groupedStacks = (0, group_by_1.groupByClassNameStackRegionStage)(this.allCdkStacks);
|
|
177
|
-
Object.values(groupedStacks).forEach((
|
|
178
|
-
Object.values(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
170
|
+
Object.values(groupedStacks).forEach((stackTagGroup) => {
|
|
171
|
+
Object.values(stackTagGroup).forEach((regionGroup) => {
|
|
172
|
+
Object.values(regionGroup).forEach((stageGroup) => {
|
|
173
|
+
const stacks = Object.values(stageGroup).flat();
|
|
174
|
+
if (stacks.length === 0) {
|
|
175
|
+
throw new Error("Unable to produce a working riff-raff.yaml file; there are no stacks!");
|
|
176
|
+
}
|
|
177
|
+
// The items in `stacks` only differ by stage, so we can just use the first item in the list.
|
|
178
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- length of `stacks` is checked above
|
|
179
|
+
const stack = stacks[0];
|
|
180
|
+
const lambdas = this.getLambdas(stack);
|
|
181
|
+
const autoscalingGroups = this.getAutoScalingGroups(stack);
|
|
182
|
+
const artifactUploads = [
|
|
183
|
+
lambdas.map(lambda_2.uploadLambdaArtifact),
|
|
184
|
+
autoscalingGroups.map(autoscaling_2.uploadAutoscalingArtifact),
|
|
185
|
+
].flat();
|
|
186
|
+
artifactUploads.forEach(({ name, props }) => deployments.set(name, props));
|
|
187
|
+
const cfnDeployment = (0, cloudformation_1.cloudFormationDeployment)(stacks, artifactUploads, this.outdir);
|
|
188
|
+
deployments.set(cfnDeployment.name, cfnDeployment.props);
|
|
189
|
+
lambdas.forEach((lambda) => {
|
|
190
|
+
const lambdaDeployment = (0, lambda_2.updateLambdaDeployment)(lambda, cfnDeployment);
|
|
191
|
+
deployments.set(lambdaDeployment.name, lambdaDeployment.props);
|
|
192
|
+
});
|
|
193
|
+
autoscalingGroups.forEach((asg) => {
|
|
194
|
+
const asgDeployment = (0, autoscaling_2.autoscalingDeployment)(asg, cfnDeployment);
|
|
195
|
+
deployments.set(asgDeployment.name, asgDeployment.props);
|
|
196
|
+
deployments.set(cfnDeployment.name, (0, cloudformation_1.addAmiParametersToCloudFormationDeployment)(cfnDeployment, asg));
|
|
197
|
+
});
|
|
203
198
|
});
|
|
204
199
|
});
|
|
205
200
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { writeFileSync } from \"fs\";\nimport path from \"path\";\nimport type { App } from \"aws-cdk-lib\";\nimport { Token } from \"aws-cdk-lib\";\nimport { dump } from \"js-yaml\";\nimport { GuAutoScalingGroup } from \"../../constructs/autoscaling\";\nimport { GuStack } from \"../../constructs/core\";\nimport { GuLambdaFunction } from \"../../constructs/lambda\";\nimport { autoscalingDeployment, uploadAutoscalingArtifact } from \"./deployments/autoscaling\";\nimport { addAmiParametersToCloudFormationDeployment, cloudFormationDeployment } from \"./deployments/cloudformation\";\nimport { updateLambdaDeployment, uploadLambdaArtifact } from \"./deployments/lambda\";\nimport { groupByClassNameStackRegionStage } from \"./group-by\";\nimport type {\n GroupedCdkStacks,\n Region,\n RiffRaffDeployment,\n RiffRaffDeploymentName,\n RiffRaffDeploymentProps,\n RiffRaffYaml,\n StackTag,\n StageTag,\n} from \"./types\";\n\n/**\n * A class that creates a `riff-raff.yaml` file.\n *\n * Rather than using this directly, prefer to use [[`GuRoot`]] instead.\n *\n * Supports:\n * - Multiple CloudFormation stacks\n * - Multiple regions\n * - Lambda applications\n * - EC2 (autoscaling) applications\n *\n * For lambda applications, 3 deployments will be defined:\n * 1. Lambda upload (`aws-lambda`, `action: [uploadLambda]`)\n * 2. CloudFormation deploy (`cloud-formation`)\n * 3. Lambda update (`aws-lambda`, `action: [updateLambda]`)\n *\n * For EC2 applications, 3 deployments will be defined:\n * 1. Artifact upload (`autoscaling`, `action: [uploadArtifacts]`)\n * 2. CloudFormation deploy (`cloud-formation`)\n * 3. Autoscaling deploy (`autoscaling`, `action: [deploy]`)\n *\n * It assumes a Riff-Raff bundle structure as follows:\n *\n * ```\n * .\n * ├── cdk.out\n * │ └── MyApplication.template.json\n * ├── my-application\n * │ └── my-application.deb\n * └── my-lambda\n * └── my-lambda.zip\n * ```\n *\n * That is, all CloudFormation templates are in a `cdk.out` directory, and there is a directory per app.\n * Application artifact(s) are in the app directory.\n *\n * NOTE: The file extension is decided by you, the above file tree is used for illustration purposes.\n *\n * NOTE: Resources will be looked up by tags (Stack, Stage, App). Ensure your CFN stack is tagged appropriately!\n *\n * @see https://riffraff.gutools.co.uk/docs/reference/riff-raff.yaml.md\n * @see https://riffraff.gutools.co.uk/docs/magenta-lib/types\n */\nexport class RiffRaffYamlFileExperimental {\n private readonly allCdkStacks: GuStack[];\n private readonly allStackTags: StackTag[];\n private readonly allStageTags: StageTag[];\n private readonly allRegions: Region[];\n\n private readonly riffRaffYaml: RiffRaffYaml;\n private readonly outdir: string;\n\n private isCdkStackPresent(expectedStack: StackTag, expectedRegion: Region, expectedStage: StageTag): boolean {\n const matches = this.allCdkStacks.find((cdkStack) => {\n const { stack, stage, region } = cdkStack;\n return stack === expectedStack && stage === expectedStage && region === expectedRegion;\n });\n\n return !!matches;\n }\n\n /**\n * Check there are the appropriate number of `GuStack`s.\n * Expect to find an instance for each combination of `stack`, `region`, and `stage`.\n *\n * If not valid, a message is logged describing what is missing to aid debugging.\n *\n * Given the following:\n *\n * ```ts\n * const app = new App();\n *\n * class MyApplicationStack extends GuStack { }\n *\n * new MyApplicationStack(app, \"App-CODE-deploy\", {\n * env: {\n * region: \"eu-west-1\",\n * },\n * stack: \"deploy\",\n * stage: \"CODE\"\n * });\n *\n * new MyApplicationStack(app, \"App-PROD-media-service\", {\n * env: {\n * region: \"eu-west-1\",\n * },\n * stack: \"media-service\",\n * stage: \"PROD\",\n * });\n *\n * new MyApplicationStack(app, \"App-PROD-deploy\", {\n * env: {\n * region: \"eu-west-1\",\n * },\n * stack: \"deploy\",\n * stage: \"PROD\"\n * });\n * ```\n *\n * This will log a message like this, where ❌ denotes something missing,\n * specifically there is no `CODE` template for `media-service`.\n *\n * ```log\n * Unable to produce a working riff-raff.yaml file; missing 1 definitions (details below)\n *\n * ┌───────────────┬────────────────────────────┐\n * │ (index) │ eu-west-1 │\n * ├───────────────┼────────────────────────────┤\n * │ deploy │ { CODE: '✅', PROD: '✅' } │\n * │ media-service │ { CODE: '❌', PROD: '✅' } │\n * └───────────────┴────────────────────────────┘\n * ```\n *\n * @private\n */\n private validateStacksInApp(): void {\n type Found = \"✅\";\n type NotFound = \"❌\";\n type AppValidation = Record<StackTag, Record<Region, Record<StageTag, Found | NotFound>>>;\n\n const { allStackTags, allStageTags, allRegions } = this;\n\n const checks: AppValidation = allStackTags.reduce((accStackTag, stackTag) => {\n return {\n ...accStackTag,\n [stackTag]: allRegions.reduce((accRegion, region) => {\n return {\n ...accRegion,\n [region]: allStageTags.reduce((accStageTag, stageTag) => {\n return {\n ...accStageTag,\n [stageTag]: this.isCdkStackPresent(stackTag, region, stageTag) ? \"✅\" : \"❌\",\n };\n }, {}),\n };\n }, {}),\n };\n }, {});\n\n const missingDefinitions = Object.values(checks).flatMap((groupedByRegion) => {\n return Object.values(groupedByRegion).flatMap((groupedByStage) => {\n return Object.values(groupedByStage).filter((_) => _ === \"❌\");\n });\n });\n\n if (missingDefinitions.length > 0) {\n const message = `Unable to produce a working riff-raff.yaml file; missing ${missingDefinitions.length} definitions`;\n\n console.log(`${message} (details below)`);\n console.table(checks);\n\n throw new Error(message);\n }\n }\n\n private validateAllRegionsAreResolved(): void {\n const unresolved = this.allRegions.filter((region) => Token.isUnresolved(region));\n\n if (unresolved.length !== 0) {\n throw new Error(`Unable to produce a working riff-raff.yaml file; all stacks must have an explicit region set`);\n }\n }\n\n private getLambdas(cdkStack: GuStack): GuLambdaFunction[] {\n return cdkStack.node.findAll().filter((_) => _ instanceof GuLambdaFunction) as GuLambdaFunction[];\n }\n\n private getAutoScalingGroups(cdkStack: GuStack): GuAutoScalingGroup[] {\n return cdkStack.node.findAll().filter((_) => _ instanceof GuAutoScalingGroup) as GuAutoScalingGroup[];\n }\n\n // eslint-disable-next-line custom-rules/valid-constructors -- this needs to sit above GuStack on the cdk tree\n constructor(app: App) {\n this.allCdkStacks = app.node.findAll().filter((_) => _ instanceof GuStack) as GuStack[];\n const allowedStages = new Set(this.allCdkStacks.map(({ stage }) => stage));\n this.allStageTags = Array.from(allowedStages);\n this.allStackTags = Array.from(new Set(this.allCdkStacks.map(({ stack }) => stack)));\n this.allRegions = Array.from(new Set(this.allCdkStacks.map(({ region }) => region)));\n\n this.validateStacksInApp();\n this.validateAllRegionsAreResolved();\n\n this.outdir = app.outdir;\n\n const deployments = new Map<RiffRaffDeploymentName, RiffRaffDeploymentProps>();\n\n const groupedStacks: GroupedCdkStacks = groupByClassNameStackRegionStage(this.allCdkStacks);\n\n Object.values(groupedStacks).forEach((regionGroup) => {\n Object.values(regionGroup).forEach((stageGroup) => {\n const stacks: GuStack[] = Object.values(stageGroup).flat();\n\n if (stacks.length === 0) {\n throw new Error(\"Unable to produce a working riff-raff.yaml file; there are no stacks!\");\n }\n\n // The items in `stacks` only differ by stage, so we can just use the first item in the list.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- length of `stacks` is checked above\n const stack = stacks[0]!;\n\n const lambdas = this.getLambdas(stack);\n const autoscalingGroups = this.getAutoScalingGroups(stack);\n\n const artifactUploads: RiffRaffDeployment[] = [\n lambdas.map(uploadLambdaArtifact),\n autoscalingGroups.map(uploadAutoscalingArtifact),\n ].flat();\n artifactUploads.forEach(({ name, props }) => deployments.set(name, props));\n\n const cfnDeployment = cloudFormationDeployment(stacks, artifactUploads, this.outdir);\n deployments.set(cfnDeployment.name, cfnDeployment.props);\n\n lambdas.forEach((lambda) => {\n const lambdaDeployment = updateLambdaDeployment(lambda, cfnDeployment);\n deployments.set(lambdaDeployment.name, lambdaDeployment.props);\n });\n\n autoscalingGroups.forEach((asg) => {\n const asgDeployment = autoscalingDeployment(asg, cfnDeployment);\n deployments.set(asgDeployment.name, asgDeployment.props);\n\n deployments.set(cfnDeployment.name, addAmiParametersToCloudFormationDeployment(cfnDeployment, asg));\n });\n });\n });\n\n this.riffRaffYaml = {\n allowedStages,\n deployments,\n };\n }\n\n /**\n * The `riff-raff.yaml` file as a string.\n * Useful for testing.\n */\n toYAML(): string {\n // Add support for ES6 Set and Map. See https://github.com/nodeca/js-yaml/issues/436.\n const replacer = (_key: string, value: unknown) => {\n if (value instanceof Set) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return -- this is how `js-yaml` is typed\n return Array.from(value);\n }\n if (value instanceof Map) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return -- this is how `js-yaml` is typed\n return Object.fromEntries(value);\n }\n return value;\n };\n\n return dump(this.riffRaffYaml, { replacer });\n }\n\n /**\n * Write the `riff-raff.yaml` file to disk.\n * It'll be located with the CFN JSON templates generated by `cdk synth`.\n */\n synth(): void {\n const outPath = path.join(this.outdir, \"riff-raff.yaml\");\n writeFileSync(outPath, this.toYAML());\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { writeFileSync } from \"fs\";\nimport path from \"path\";\nimport type { App } from \"aws-cdk-lib\";\nimport { Token } from \"aws-cdk-lib\";\nimport { dump } from \"js-yaml\";\nimport { GuAutoScalingGroup } from \"../../constructs/autoscaling\";\nimport { GuStack } from \"../../constructs/core\";\nimport { GuLambdaFunction } from \"../../constructs/lambda\";\nimport { autoscalingDeployment, uploadAutoscalingArtifact } from \"./deployments/autoscaling\";\nimport { addAmiParametersToCloudFormationDeployment, cloudFormationDeployment } from \"./deployments/cloudformation\";\nimport { updateLambdaDeployment, uploadLambdaArtifact } from \"./deployments/lambda\";\nimport { groupByClassNameStackRegionStage } from \"./group-by\";\nimport type {\n GroupedCdkStacks,\n Region,\n RiffRaffDeployment,\n RiffRaffDeploymentName,\n RiffRaffDeploymentProps,\n RiffRaffYaml,\n StackTag,\n StageTag,\n} from \"./types\";\n\n/**\n * A class that creates a `riff-raff.yaml` file.\n *\n * Rather than using this directly, prefer to use [[`GuRoot`]] instead.\n *\n * Supports:\n * - Multiple CloudFormation stacks\n * - Multiple regions\n * - Lambda applications\n * - EC2 (autoscaling) applications\n *\n * For lambda applications, 3 deployments will be defined:\n * 1. Lambda upload (`aws-lambda`, `action: [uploadLambda]`)\n * 2. CloudFormation deploy (`cloud-formation`)\n * 3. Lambda update (`aws-lambda`, `action: [updateLambda]`)\n *\n * For EC2 applications, 3 deployments will be defined:\n * 1. Artifact upload (`autoscaling`, `action: [uploadArtifacts]`)\n * 2. CloudFormation deploy (`cloud-formation`)\n * 3. Autoscaling deploy (`autoscaling`, `action: [deploy]`)\n *\n * It assumes a Riff-Raff bundle structure as follows:\n *\n * ```\n * .\n * ├── cdk.out\n * │ └── MyApplication.template.json\n * ├── my-application\n * │ └── my-application.deb\n * └── my-lambda\n * └── my-lambda.zip\n * ```\n *\n * That is, all CloudFormation templates are in a `cdk.out` directory, and there is a directory per app.\n * Application artifact(s) are in the app directory.\n *\n * NOTE: The file extension is decided by you, the above file tree is used for illustration purposes.\n *\n * NOTE: Resources will be looked up by tags (Stack, Stage, App). Ensure your CFN stack is tagged appropriately!\n *\n * @see https://riffraff.gutools.co.uk/docs/reference/riff-raff.yaml.md\n * @see https://riffraff.gutools.co.uk/docs/magenta-lib/types\n */\nexport class RiffRaffYamlFileExperimental {\n private readonly allCdkStacks: GuStack[];\n private readonly allStackTags: StackTag[];\n private readonly allStageTags: StageTag[];\n private readonly allRegions: Region[];\n\n private readonly riffRaffYaml: RiffRaffYaml;\n private readonly outdir: string;\n\n private isCdkStackPresent(expectedStack: StackTag, expectedStage: StageTag): boolean {\n const matches = this.allCdkStacks.find((cdkStack) => {\n const { stack, stage } = cdkStack;\n return stack === expectedStack && stage === expectedStage;\n });\n\n return !!matches;\n }\n\n /**\n * Check there are the appropriate number of `GuStack`s.\n * Expect to find an instance for each combination of `stack`, and `stage`.\n *\n * If not valid, a message is logged describing what is missing to aid debugging.\n *\n * Given the following:\n *\n * ```ts\n * const app = new App();\n *\n * class MyApplicationStack extends GuStack { }\n *\n * new MyApplicationStack(app, \"App-CODE-deploy\", {\n * env: {\n * region: \"eu-west-1\",\n * },\n * stack: \"deploy\",\n * stage: \"CODE\"\n * });\n *\n * new MyApplicationStack(app, \"App-PROD-media-service\", {\n * env: {\n * region: \"eu-west-1\",\n * },\n * stack: \"media-service\",\n * stage: \"PROD\",\n * });\n *\n * new MyApplicationStack(app, \"App-PROD-deploy\", {\n * env: {\n * region: \"eu-west-1\",\n * },\n * stack: \"deploy\",\n * stage: \"PROD\"\n * });\n * ```\n *\n * This will log a message like this, where ❌ denotes something missing,\n * specifically there is no `CODE` template for `media-service`.\n *\n * ```log\n * Unable to produce a working riff-raff.yaml file; missing 1 definitions (details below)\n *\n * ┌───────────────┬──────┬──────┐\n * │ (index) │ CODE │ PROD │\n * ├───────────────┼──────┼──────┤\n * │ deploy │ '✅' │ '✅' │\n * │ media-service │ '❌' │ '✅' │\n * └───────────────┴──────┴──────┘\n * ```\n *\n * @private\n */\n private validateStacksInApp(): void {\n type Found = \"✅\";\n type NotFound = \"❌\";\n type AppValidation = Record<StackTag, Record<StageTag, Found | NotFound>>;\n\n const { allStackTags, allStageTags } = this;\n\n const checks: AppValidation = allStackTags.reduce((accStackTag, stackTag) => {\n return {\n ...accStackTag,\n [stackTag]: allStageTags.reduce((accStageTag, stageTag) => {\n return {\n ...accStageTag,\n [stageTag]: this.isCdkStackPresent(stackTag, stageTag) ? \"✅\" : \"❌\",\n };\n }, {}),\n };\n }, {});\n\n const missingDefinitions: Array<Found | NotFound> = Object.values(checks).flatMap((groupedByStackTag) => {\n return Object.values(groupedByStackTag).filter((_) => _ === \"❌\");\n });\n\n if (missingDefinitions.length > 0) {\n const message = `Unable to produce a working riff-raff.yaml file; missing ${missingDefinitions.length} definitions`;\n\n console.log(`${message} (details below)`);\n console.table(checks);\n\n throw new Error(message);\n }\n }\n\n private validateAllRegionsAreResolved(): void {\n const unresolved = this.allRegions.filter((region) => Token.isUnresolved(region));\n\n if (unresolved.length !== 0) {\n throw new Error(`Unable to produce a working riff-raff.yaml file; all stacks must have an explicit region set`);\n }\n }\n\n private getLambdas(cdkStack: GuStack): GuLambdaFunction[] {\n return cdkStack.node.findAll().filter((_) => _ instanceof GuLambdaFunction) as GuLambdaFunction[];\n }\n\n private getAutoScalingGroups(cdkStack: GuStack): GuAutoScalingGroup[] {\n return cdkStack.node.findAll().filter((_) => _ instanceof GuAutoScalingGroup) as GuAutoScalingGroup[];\n }\n\n // eslint-disable-next-line custom-rules/valid-constructors -- this needs to sit above GuStack on the cdk tree\n constructor(app: App) {\n this.allCdkStacks = app.node.findAll().filter((_) => _ instanceof GuStack) as GuStack[];\n const allowedStages = new Set(this.allCdkStacks.map(({ stage }) => stage));\n this.allStageTags = Array.from(allowedStages);\n this.allStackTags = Array.from(new Set(this.allCdkStacks.map(({ stack }) => stack)));\n this.allRegions = Array.from(new Set(this.allCdkStacks.map(({ region }) => region)));\n\n this.validateStacksInApp();\n this.validateAllRegionsAreResolved();\n\n this.outdir = app.outdir;\n\n const deployments = new Map<RiffRaffDeploymentName, RiffRaffDeploymentProps>();\n\n const groupedStacks: GroupedCdkStacks = groupByClassNameStackRegionStage(this.allCdkStacks);\n\n Object.values(groupedStacks).forEach((stackTagGroup) => {\n Object.values(stackTagGroup).forEach((regionGroup) => {\n Object.values(regionGroup).forEach((stageGroup) => {\n const stacks: GuStack[] = Object.values(stageGroup).flat();\n\n if (stacks.length === 0) {\n throw new Error(\"Unable to produce a working riff-raff.yaml file; there are no stacks!\");\n }\n\n // The items in `stacks` only differ by stage, so we can just use the first item in the list.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- length of `stacks` is checked above\n const stack = stacks[0]!;\n\n const lambdas = this.getLambdas(stack);\n const autoscalingGroups = this.getAutoScalingGroups(stack);\n\n const artifactUploads: RiffRaffDeployment[] = [\n lambdas.map(uploadLambdaArtifact),\n autoscalingGroups.map(uploadAutoscalingArtifact),\n ].flat();\n artifactUploads.forEach(({ name, props }) => deployments.set(name, props));\n\n const cfnDeployment = cloudFormationDeployment(stacks, artifactUploads, this.outdir);\n deployments.set(cfnDeployment.name, cfnDeployment.props);\n\n lambdas.forEach((lambda) => {\n const lambdaDeployment = updateLambdaDeployment(lambda, cfnDeployment);\n deployments.set(lambdaDeployment.name, lambdaDeployment.props);\n });\n\n autoscalingGroups.forEach((asg) => {\n const asgDeployment = autoscalingDeployment(asg, cfnDeployment);\n deployments.set(asgDeployment.name, asgDeployment.props);\n\n deployments.set(cfnDeployment.name, addAmiParametersToCloudFormationDeployment(cfnDeployment, asg));\n });\n });\n });\n });\n\n this.riffRaffYaml = {\n allowedStages,\n deployments,\n };\n }\n\n /**\n * The `riff-raff.yaml` file as a string.\n * Useful for testing.\n */\n toYAML(): string {\n // Add support for ES6 Set and Map. See https://github.com/nodeca/js-yaml/issues/436.\n const replacer = (_key: string, value: unknown) => {\n if (value instanceof Set) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return -- this is how `js-yaml` is typed\n return Array.from(value);\n }\n if (value instanceof Map) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return -- this is how `js-yaml` is typed\n return Object.fromEntries(value);\n }\n return value;\n };\n\n return dump(this.riffRaffYaml, { replacer });\n }\n\n /**\n * Write the `riff-raff.yaml` file to disk.\n * It'll be located with the CFN JSON templates generated by `cdk synth`.\n */\n synth(): void {\n const outPath = path.join(this.outdir, \"riff-raff.yaml\");\n writeFileSync(outPath, this.toYAML());\n }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GuStack } from "../../constructs/core";
|
|
2
|
+
export type ClassName = string;
|
|
2
3
|
export type StackTag = string;
|
|
3
4
|
export type StageTag = string;
|
|
4
5
|
export type Region = string;
|
|
@@ -22,5 +23,5 @@ export interface RiffRaffDeployment {
|
|
|
22
23
|
name: RiffRaffDeploymentName;
|
|
23
24
|
props: RiffRaffDeploymentProps;
|
|
24
25
|
}
|
|
25
|
-
export type GroupedCdkStacks = Record<StackTag, Record<Region, Record<StageTag, CdkStacksDifferingOnlyByStage
|
|
26
|
+
export type GroupedCdkStacks = Record<ClassName, Record<StackTag, Record<Region, Record<StageTag, CdkStacksDifferingOnlyByStage>>>>;
|
|
26
27
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC9B,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC9B,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC;AAC5B,MAAM,MAAM,6BAA6B,GAAG,OAAO,EAAE,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,WAAW,EAAE,GAAG,CAAC,sBAAsB,EAAE,uBAAuB,CAAC,CAAC;CACnE;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,KAAK,EAAE,uBAAuB,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAC/B,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC9B,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC9B,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC;AAC5B,MAAM,MAAM,6BAA6B,GAAG,OAAO,EAAE,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,WAAW,EAAE,GAAG,CAAC,sBAAsB,EAAE,uBAAuB,CAAC,CAAC;CACnE;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,YAAY,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,KAAK,EAAE,uBAAuB,CAAC;CAChC;AASD,MAAM,MAAM,gBAAgB,GAAG,MAAM,CACnC,SAAS,EACT,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CAAC,CAAC,CAClF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/types.ts"],"names":[],"mappings":"","sourcesContent":["// type aliases to, hopefully, improve readability\nimport type { GuStack } from \"../../constructs/core\";\n\nexport type StackTag = string;\nexport type StageTag = string;\nexport type Region = string;\nexport type CdkStacksDifferingOnlyByStage = GuStack[];\n\nexport interface RiffRaffYaml {\n allowedStages: Set<StageTag>;\n deployments: Map<RiffRaffDeploymentName, RiffRaffDeploymentProps>;\n}\n\nexport type RiffRaffDeploymentName = string;\n\nexport interface RiffRaffDeploymentProps {\n type: string;\n regions: Set<Region>;\n stacks: Set<StackTag>;\n app: string;\n contentDirectory: string;\n parameters: Record<string, string | boolean | Record<string, string>>;\n dependencies?: RiffRaffDeploymentName[];\n actions?: string[];\n}\n\nexport interface RiffRaffDeployment {\n name: RiffRaffDeploymentName;\n props: RiffRaffDeploymentProps;\n}\n\n/*\n The aim here is to produce an identity of a `GuStack` as a composite of:\n - Stack tag\n - Region\n Finally, group by stage to help form the `templateStagePaths` property for the `cloud-formation` deployment type in `riff-raff.yaml`.\n */\nexport type GroupedCdkStacks = Record<StackTag, Record<Region, Record<StageTag, CdkStacksDifferingOnlyByStage
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/experimental/riff-raff-yaml-file/types.ts"],"names":[],"mappings":"","sourcesContent":["// type aliases to, hopefully, improve readability\nimport type { GuStack } from \"../../constructs/core\";\n\nexport type ClassName = string;\nexport type StackTag = string;\nexport type StageTag = string;\nexport type Region = string;\nexport type CdkStacksDifferingOnlyByStage = GuStack[];\n\nexport interface RiffRaffYaml {\n allowedStages: Set<StageTag>;\n deployments: Map<RiffRaffDeploymentName, RiffRaffDeploymentProps>;\n}\n\nexport type RiffRaffDeploymentName = string;\n\nexport interface RiffRaffDeploymentProps {\n type: string;\n regions: Set<Region>;\n stacks: Set<StackTag>;\n app: string;\n contentDirectory: string;\n parameters: Record<string, string | boolean | Record<string, string>>;\n dependencies?: RiffRaffDeploymentName[];\n actions?: string[];\n}\n\nexport interface RiffRaffDeployment {\n name: RiffRaffDeploymentName;\n props: RiffRaffDeploymentProps;\n}\n\n/*\n The aim here is to produce an identity of a `GuStack` as a composite of:\n - Class name\n - Stack tag\n - Region\n Finally, group by stage to help form the `templateStagePaths` property for the `cloud-formation` deployment type in `riff-raff.yaml`.\n */\nexport type GroupedCdkStacks = Record<\n ClassName,\n Record<StackTag, Record<Region, Record<StageTag, CdkStacksDifferingOnlyByStage>>>\n>;\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guardian/cdk",
|
|
3
3
|
"description": "Generic Guardian flavoured AWS CDK components",
|
|
4
|
-
"version": "49.0.
|
|
4
|
+
"version": "49.0.3",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"@types/yargs": "^17.0.19",
|
|
40
40
|
"aws-cdk": "2.59.0",
|
|
41
41
|
"cz-conventional-changelog": "^3.3.0",
|
|
42
|
-
"eslint": "^8.
|
|
42
|
+
"eslint": "^8.32.0",
|
|
43
43
|
"eslint-plugin-custom-rules": "file:tools/eslint",
|
|
44
|
-
"gh-pages": "^
|
|
44
|
+
"gh-pages": "^5.0.0",
|
|
45
45
|
"jest": "^29.3.1",
|
|
46
46
|
"prettier": "^2.8.3",
|
|
47
47
|
"semantic-release": "^19.0.5",
|
|
48
|
-
"serve": "^14.
|
|
48
|
+
"serve": "^14.2.0",
|
|
49
49
|
"ts-jest": "^29.0.5",
|
|
50
50
|
"ts-node": "^10.9.1",
|
|
51
51
|
"typedoc": "^0.23.24",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { GuStack } from "../../core";
|
|
2
|
-
import { GuAllowPolicy } from "./base-policy";
|
|
3
|
-
export declare class GuSSMRunCommandPolicy extends GuAllowPolicy {
|
|
4
|
-
private static instance;
|
|
5
|
-
private constructor();
|
|
6
|
-
static getInstance(stack: GuStack): GuSSMRunCommandPolicy;
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=ssm.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssm.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ssm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAoC;IAE3D,OAAO;WAuBO,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB;CAOjE"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GuSSMRunCommandPolicy = void 0;
|
|
4
|
-
const singleton_1 = require("../../../utils/singleton");
|
|
5
|
-
const base_policy_1 = require("./base-policy");
|
|
6
|
-
class GuSSMRunCommandPolicy extends base_policy_1.GuAllowPolicy {
|
|
7
|
-
constructor(scope) {
|
|
8
|
-
super(scope, "SSMRunCommandPolicy", {
|
|
9
|
-
policyName: "ssm-run-command-policy",
|
|
10
|
-
resources: ["*"],
|
|
11
|
-
actions: [
|
|
12
|
-
"ec2messages:AcknowledgeMessage",
|
|
13
|
-
"ec2messages:DeleteMessage",
|
|
14
|
-
"ec2messages:FailMessage",
|
|
15
|
-
"ec2messages:GetEndpoint",
|
|
16
|
-
"ec2messages:GetMessages",
|
|
17
|
-
"ec2messages:SendReply",
|
|
18
|
-
"ssm:UpdateInstanceInformation",
|
|
19
|
-
"ssm:ListInstanceAssociations",
|
|
20
|
-
"ssm:DescribeInstanceProperties",
|
|
21
|
-
"ssm:DescribeDocumentParameters",
|
|
22
|
-
"ssmmessages:CreateControlChannel",
|
|
23
|
-
"ssmmessages:CreateDataChannel",
|
|
24
|
-
"ssmmessages:OpenControlChannel",
|
|
25
|
-
"ssmmessages:OpenDataChannel",
|
|
26
|
-
],
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
static getInstance(stack) {
|
|
30
|
-
if (!this.instance || !(0, singleton_1.isSingletonPresentInStack)(stack, this.instance)) {
|
|
31
|
-
this.instance = new GuSSMRunCommandPolicy(stack);
|
|
32
|
-
}
|
|
33
|
-
return this.instance;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
exports.GuSSMRunCommandPolicy = GuSSMRunCommandPolicy;
|
|
37
|
-
//# sourceMappingURL=ssm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssm.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ssm.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,+CAA8C;AAE9C,MAAa,qBAAsB,SAAQ,2BAAa;IAGtD,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,qBAAqB,EAAE;YAClC,UAAU,EAAE,wBAAwB;YACpC,SAAS,EAAE,CAAC,GAAG,CAAC;YAChB,OAAO,EAAE;gBACP,gCAAgC;gBAChC,2BAA2B;gBAC3B,yBAAyB;gBACzB,yBAAyB;gBACzB,yBAAyB;gBACzB,uBAAuB;gBACvB,+BAA+B;gBAC/B,8BAA8B;gBAC9B,gCAAgC;gBAChC,gCAAgC;gBAChC,kCAAkC;gBAClC,+BAA+B;gBAC/B,gCAAgC;gBAChC,6BAA6B;aAC9B;SACF,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;SAClD;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAjCD,sDAiCC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\nexport class GuSSMRunCommandPolicy extends GuAllowPolicy {\n private static instance: GuSSMRunCommandPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"SSMRunCommandPolicy\", {\n policyName: \"ssm-run-command-policy\",\n resources: [\"*\"],\n actions: [\n \"ec2messages:AcknowledgeMessage\",\n \"ec2messages:DeleteMessage\",\n \"ec2messages:FailMessage\",\n \"ec2messages:GetEndpoint\",\n \"ec2messages:GetMessages\",\n \"ec2messages:SendReply\",\n \"ssm:UpdateInstanceInformation\",\n \"ssm:ListInstanceAssociations\",\n \"ssm:DescribeInstanceProperties\",\n \"ssm:DescribeDocumentParameters\",\n \"ssmmessages:CreateControlChannel\",\n \"ssmmessages:CreateDataChannel\",\n \"ssmmessages:OpenControlChannel\",\n \"ssmmessages:OpenDataChannel\",\n ],\n });\n }\n\n public static getInstance(stack: GuStack): GuSSMRunCommandPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuSSMRunCommandPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
|