@fjall/components-infrastructure 0.88.3 → 0.89.2

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.
Files changed (152) hide show
  1. package/LICENSE +21 -0
  2. package/dist/lib/app.d.ts +33 -10
  3. package/dist/lib/app.js +79 -36
  4. package/dist/lib/aspects/index.d.ts +1 -0
  5. package/dist/lib/aspects/index.js +6 -0
  6. package/dist/lib/config/aws/accountAuditRole.d.ts +20 -0
  7. package/dist/lib/config/aws/accountAuditRole.js +38 -0
  8. package/dist/lib/config/aws/accountMonitoringRole.d.ts +22 -0
  9. package/dist/lib/config/aws/accountMonitoringRole.js +133 -0
  10. package/dist/lib/config/aws/cloudTrail.d.ts +0 -3
  11. package/dist/lib/config/aws/cloudTrail.js +2 -2
  12. package/dist/lib/config/aws/disasterRecovery.js +53 -20
  13. package/dist/lib/config/aws/ecrDefaultImage.js +4 -3
  14. package/dist/lib/config/aws/index.d.ts +4 -0
  15. package/dist/lib/config/aws/index.js +5 -1
  16. package/dist/lib/config/aws/oidcConnector.d.ts +8 -0
  17. package/dist/lib/config/aws/oidcConnector.js +46 -0
  18. package/dist/lib/config/aws/platform.d.ts +2 -0
  19. package/dist/lib/config/aws/platform.js +6 -0
  20. package/dist/lib/config/index.d.ts +2 -0
  21. package/dist/lib/config/index.js +21 -0
  22. package/dist/lib/patterns/aws/account.js +22 -10
  23. package/dist/lib/patterns/aws/cdn.d.ts +19 -40
  24. package/dist/lib/patterns/aws/cdn.js +21 -17
  25. package/dist/lib/patterns/aws/compute.d.ts +9 -720
  26. package/dist/lib/patterns/aws/compute.js +27 -432
  27. package/dist/lib/patterns/aws/computeEc2.d.ts +67 -0
  28. package/dist/lib/patterns/aws/computeEc2.js +46 -0
  29. package/dist/lib/patterns/aws/computeEcs.d.ts +446 -0
  30. package/dist/lib/patterns/aws/computeEcs.js +246 -0
  31. package/dist/lib/patterns/aws/computeLambda.d.ts +220 -0
  32. package/dist/lib/patterns/aws/computeLambda.js +147 -0
  33. package/dist/lib/patterns/aws/database.d.ts +7 -87
  34. package/dist/lib/patterns/aws/database.js +15 -38
  35. package/dist/lib/patterns/aws/domainDelegation.d.ts +8 -0
  36. package/dist/lib/patterns/aws/domainDelegation.js +54 -0
  37. package/dist/lib/patterns/aws/domainFactory.d.ts +8 -0
  38. package/dist/lib/patterns/aws/domainFactory.js +23 -0
  39. package/dist/lib/patterns/aws/index.d.ts +4 -1
  40. package/dist/lib/patterns/aws/index.js +6 -2
  41. package/dist/lib/patterns/aws/interfaces/cdn.d.ts +26 -0
  42. package/dist/lib/patterns/aws/interfaces/cdn.js +14 -0
  43. package/dist/lib/patterns/aws/interfaces/connector.d.ts +4 -181
  44. package/dist/lib/patterns/aws/interfaces/connector.js +16 -113
  45. package/dist/lib/patterns/aws/interfaces/domain.d.ts +2 -0
  46. package/dist/lib/patterns/aws/interfaces/domain.js +6 -0
  47. package/dist/lib/patterns/aws/interfaces/index.d.ts +2 -0
  48. package/dist/lib/patterns/aws/interfaces/index.js +5 -2
  49. package/dist/lib/patterns/aws/interfaces/pattern.d.ts +9 -6
  50. package/dist/lib/patterns/aws/interfaces/pattern.js +1 -1
  51. package/dist/lib/patterns/aws/network.js +6 -9
  52. package/dist/lib/patterns/aws/organisation.d.ts +4 -2
  53. package/dist/lib/patterns/aws/organisation.js +21 -8
  54. package/dist/lib/patterns/aws/payload.js +21 -12
  55. package/dist/lib/patterns/aws/storage.d.ts +3 -2
  56. package/dist/lib/patterns/aws/storage.js +1 -1
  57. package/dist/lib/resources/aws/audit/auditRole.js +4 -4
  58. package/dist/lib/resources/aws/audit/index.d.ts +1 -0
  59. package/dist/lib/resources/aws/audit/index.js +6 -0
  60. package/dist/lib/resources/aws/backup/backupPlan.js +3 -2
  61. package/dist/lib/resources/aws/backup/backupVault.js +5 -3
  62. package/dist/lib/resources/aws/base/awsStack.d.ts +4 -2
  63. package/dist/lib/resources/aws/base/awsStack.js +8 -2
  64. package/dist/lib/resources/aws/cdn/cloudFront.d.ts +14 -0
  65. package/dist/lib/resources/aws/cdn/cloudFront.js +52 -18
  66. package/dist/lib/resources/aws/compute/ec2.js +18 -22
  67. package/dist/lib/resources/aws/compute/ecs.d.ts +23 -10
  68. package/dist/lib/resources/aws/compute/ecs.js +121 -64
  69. package/dist/lib/resources/aws/compute/index.d.ts +1 -0
  70. package/dist/lib/resources/aws/compute/index.js +2 -1
  71. package/dist/lib/resources/aws/compute/lambda.d.ts +0 -2
  72. package/dist/lib/resources/aws/compute/lambda.js +12 -27
  73. package/dist/lib/resources/aws/database/dynamodb.js +3 -13
  74. package/dist/lib/resources/aws/database/index.d.ts +8 -2
  75. package/dist/lib/resources/aws/database/index.js +19 -3
  76. package/dist/lib/resources/aws/database/rdsAurora.d.ts +2 -3
  77. package/dist/lib/resources/aws/database/rdsAurora.js +32 -68
  78. package/dist/lib/resources/aws/database/rdsAuroraGlobal.d.ts +6 -6
  79. package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +25 -29
  80. package/dist/lib/resources/aws/database/rdsDefaults.d.ts +11 -0
  81. package/dist/lib/resources/aws/database/rdsDefaults.js +15 -0
  82. package/dist/lib/resources/aws/database/rdsHelpers.d.ts +39 -0
  83. package/dist/lib/resources/aws/database/rdsHelpers.js +75 -0
  84. package/dist/lib/resources/aws/database/rdsInstance.d.ts +7 -8
  85. package/dist/lib/resources/aws/database/rdsInstance.js +40 -84
  86. package/dist/lib/resources/aws/database/rdsProxyOutput.d.ts +7 -0
  87. package/dist/lib/resources/aws/database/rdsProxyOutput.js +18 -0
  88. package/dist/lib/resources/aws/iam/index.d.ts +0 -1
  89. package/dist/lib/resources/aws/iam/index.js +1 -2
  90. package/dist/lib/resources/aws/index.d.ts +0 -1
  91. package/dist/lib/resources/aws/index.js +1 -2
  92. package/dist/lib/resources/aws/logging/cloudTrail.js +13 -3
  93. package/dist/lib/resources/aws/logging/index.d.ts +2 -0
  94. package/dist/lib/resources/aws/logging/index.js +19 -0
  95. package/dist/lib/resources/aws/messaging/index.d.ts +3 -2
  96. package/dist/lib/resources/aws/messaging/index.js +4 -3
  97. package/dist/lib/resources/aws/messaging/sqs.js +14 -11
  98. package/dist/lib/resources/aws/messaging/utils.d.ts +1 -2
  99. package/dist/lib/resources/aws/messaging/utils.js +3 -4
  100. package/dist/lib/resources/aws/monitoring/index.d.ts +0 -1
  101. package/dist/lib/resources/aws/monitoring/index.js +4 -17
  102. package/dist/lib/resources/aws/networking/domain.d.ts +13 -0
  103. package/dist/lib/resources/aws/networking/domain.js +102 -0
  104. package/dist/lib/resources/aws/networking/domainCertificate.d.ts +13 -0
  105. package/dist/lib/resources/aws/networking/domainCertificate.js +28 -0
  106. package/dist/lib/resources/aws/networking/hostedZone.d.ts +28 -0
  107. package/dist/lib/resources/aws/networking/hostedZone.js +150 -0
  108. package/dist/lib/resources/aws/networking/index.d.ts +4 -0
  109. package/dist/lib/resources/aws/networking/index.js +5 -1
  110. package/dist/lib/resources/aws/networking/ipamPool.js +57 -31
  111. package/dist/lib/resources/aws/networking/securityGroup.d.ts +5 -0
  112. package/dist/lib/resources/aws/networking/securityGroup.js +14 -0
  113. package/dist/lib/resources/aws/networking/vpc.js +9 -4
  114. package/dist/lib/resources/aws/organisation/costAllocationTagActivator.d.ts +17 -0
  115. package/dist/lib/resources/aws/organisation/costAllocationTagActivator.js +66 -0
  116. package/dist/lib/resources/aws/organisation/index.d.ts +1 -0
  117. package/dist/lib/resources/aws/organisation/index.js +4 -2
  118. package/dist/lib/resources/aws/secrets/index.d.ts +0 -1
  119. package/dist/lib/resources/aws/secrets/index.js +1 -2
  120. package/dist/lib/resources/aws/storage/ecr.d.ts +0 -1
  121. package/dist/lib/resources/aws/storage/ecr.js +5 -5
  122. package/dist/lib/resources/aws/storage/s3.d.ts +3 -3
  123. package/dist/lib/resources/aws/storage/s3.js +1 -1
  124. package/dist/lib/resources/aws/utilities/index.d.ts +5 -0
  125. package/dist/lib/resources/aws/utilities/index.js +22 -0
  126. package/dist/lib/utils/backupTierMapping.d.ts +11 -0
  127. package/dist/lib/utils/backupTierMapping.js +17 -0
  128. package/dist/lib/utils/capitaliseString.d.ts +1 -12
  129. package/dist/lib/utils/capitaliseString.js +8 -28
  130. package/dist/lib/utils/connections.d.ts +46 -0
  131. package/dist/lib/utils/connections.js +159 -0
  132. package/dist/lib/utils/connector.d.ts +183 -0
  133. package/dist/lib/utils/connector.js +117 -0
  134. package/dist/lib/utils/databaseTypes.d.ts +85 -0
  135. package/dist/lib/utils/databaseTypes.js +34 -0
  136. package/dist/lib/utils/dnsRecords.d.ts +4 -0
  137. package/dist/lib/utils/dnsRecords.js +108 -0
  138. package/dist/lib/utils/domainTypes.d.ts +37 -0
  139. package/dist/lib/utils/domainTypes.js +10 -0
  140. package/dist/lib/utils/env.d.ts +42 -0
  141. package/dist/lib/utils/env.js +122 -0
  142. package/dist/lib/utils/getConfig.d.ts +0 -5
  143. package/dist/lib/utils/getConfig.js +42 -19
  144. package/dist/lib/utils/index.d.ts +7 -0
  145. package/dist/lib/utils/index.js +8 -1
  146. package/dist/lib/utils/removalPolicy.d.ts +2 -0
  147. package/dist/lib/utils/removalPolicy.js +16 -0
  148. package/dist/lib/utils/standardTagsAspect.d.ts +4 -0
  149. package/dist/lib/utils/standardTagsAspect.js +8 -8
  150. package/dist/lib/utils/vpcUtils.d.ts +14 -0
  151. package/dist/lib/utils/vpcUtils.js +28 -0
  152. package/package.json +7 -6
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HostedZone = exports.HostedZoneFactory = void 0;
4
+ const constructs_1 = require("constructs");
5
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
6
+ const capitaliseString_1 = require("../../../utils/capitaliseString");
7
+ const iam_1 = require("../iam");
8
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
9
+ const aws_route53_1 = require("aws-cdk-lib/aws-route53");
10
+ class HostedZoneFactory {
11
+ static import(stack, hostedZoneId, zoneName) {
12
+ const safeZoneName = (0, capitaliseString_1.getSafeZoneName)(zoneName);
13
+ return new HostedZone(stack.getStack(), `${safeZoneName}HostedZone`, {
14
+ hostedZoneId: hostedZoneId,
15
+ zoneName: zoneName
16
+ });
17
+ }
18
+ }
19
+ exports.HostedZoneFactory = HostedZoneFactory;
20
+ class HostedZone extends constructs_1.Construct {
21
+ constructor(scope, id, props) {
22
+ super(scope, id);
23
+ this.scope = scope;
24
+ this.zoneName = props.zoneName;
25
+ // If a hostedZoneId is provided import it, unless create a new hosted zone
26
+ if (!props.hostedZoneId) {
27
+ this.addHostedZone(props.zoneName);
28
+ this.hostedZoneId = this.hostedZone.hostedZoneId;
29
+ this.delegateHostedZone();
30
+ }
31
+ else {
32
+ this.hostedZoneId = props.hostedZoneId;
33
+ this.importHostedZone(props.zoneName);
34
+ }
35
+ }
36
+ getInternalHostedZone() {
37
+ return this.hostedZone || this.importedHostedZone;
38
+ }
39
+ safeZoneName() {
40
+ return (0, capitaliseString_1.getSafeZoneName)(this.zoneName);
41
+ }
42
+ addHostedZone(zoneName) {
43
+ this.hostedZone = new aws_route53_1.HostedZone(this, `${this.safeZoneName()}HostedZone`, {
44
+ zoneName: zoneName,
45
+ comment: `Hosted Zone for ${zoneName}`
46
+ });
47
+ }
48
+ importHostedZone(zoneName) {
49
+ this.importedHostedZone = aws_route53_1.HostedZone.fromHostedZoneAttributes(
50
+ // HostedZone.fromHostedZoneAttributes explicitly must be passed a stack as parent scope
51
+ this.scope,
52
+ // Use safeZoneName in the id so we can theoretically
53
+ // import multiple hosted zones in a single app
54
+ `${this.safeZoneName()}ImportedHostedZone`, {
55
+ hostedZoneId: this.hostedZoneId,
56
+ zoneName: zoneName
57
+ });
58
+ aws_cdk_lib_1.Tags.of(this.importedHostedZone).add("fjall:costAllocation:environment", "management");
59
+ aws_cdk_lib_1.Tags.of(this.importedHostedZone).add("fjall:costAllocation:service", "hostedZone");
60
+ aws_cdk_lib_1.Tags.of(this.importedHostedZone).add("fjall:costAllocation:domain", zoneName);
61
+ // Make export name unique by including the stack name to avoid conflicts
62
+ // when multiple stacks import the same hosted zone
63
+ const stack = aws_cdk_lib_1.Stack.of(this);
64
+ const stackName = stack.stackName;
65
+ const exportName = `${stackName}${this.safeZoneName()}HostedZoneId`;
66
+ const safeKey = (0, capitaliseString_1.toPascalCase)(this.safeZoneName());
67
+ new aws_cdk_lib_1.CfnOutput(this, `${safeKey}HostedZoneId`, {
68
+ key: `${safeKey}HostedZoneId`,
69
+ value: this.hostedZoneId,
70
+ exportName: exportName
71
+ });
72
+ }
73
+ delegateHostedZone() {
74
+ const domainLabel = this.hostedZone.zoneName.split(".")[0] ?? "default";
75
+ const safeDomainLabel = (0, capitaliseString_1.toPascalCase)(domainLabel);
76
+ const role = new iam_1.Role(this, `${safeDomainLabel}DelegateHostedZoneRole`, {
77
+ assumedBy: new aws_iam_1.OrganizationPrincipal(aws_cdk_lib_1.Fn.importValue("OrganisationId")),
78
+ roleName: `${domainLabel}DelegateHostedZoneRole`,
79
+ inlinePolicies: {
80
+ ["listHostedZones"]: new aws_iam_1.PolicyDocument({
81
+ statements: [
82
+ new aws_iam_1.PolicyStatement({
83
+ actions: ["route53:ListHostedZonesByName"],
84
+ resources: ["*"]
85
+ })
86
+ ]
87
+ }),
88
+ ["changeResourceRecordSets"]: new aws_iam_1.PolicyDocument({
89
+ statements: [
90
+ new aws_iam_1.PolicyStatement({
91
+ actions: ["route53:ChangeResourceRecordSets"],
92
+ resources: [
93
+ `arn:aws:route53:::hostedzone/${this.hostedZone.hostedZoneId}`
94
+ ]
95
+ })
96
+ ]
97
+ })
98
+ }
99
+ });
100
+ this.hostedZone.grantDelegation(role);
101
+ new aws_cdk_lib_1.CfnOutput(this, "DelegateHostedZoneRoleArn", {
102
+ key: `${safeDomainLabel}DelegateHostedZoneRoleArn`,
103
+ value: role.roleArn,
104
+ exportName: `${domainLabel}DelegateHostedZoneRoleArn`
105
+ });
106
+ }
107
+ addARecord(props) {
108
+ new aws_route53_1.ARecord(this, "ARecord", {
109
+ zone: this.importedHostedZone,
110
+ recordName: props.recordName,
111
+ comment: props.comment || `A Record for ${this.importedHostedZone.zoneName}`,
112
+ target: props.target,
113
+ ttl: props.ttl
114
+ });
115
+ }
116
+ addCname(props) {
117
+ new aws_route53_1.CnameRecord(this, "CnameRecord", {
118
+ domainName: props.domainName,
119
+ zone: this.importedHostedZone,
120
+ comment: props.comment || `CNAME Record for ${this.importedHostedZone.zoneName}`,
121
+ ttl: props.ttl
122
+ });
123
+ }
124
+ addMx(props) {
125
+ new aws_route53_1.MxRecord(this, "MxRecord", {
126
+ zone: this.importedHostedZone,
127
+ comment: props.comment || `MX Record for ${this.importedHostedZone.zoneName}`,
128
+ values: props.values,
129
+ ttl: props.ttl
130
+ });
131
+ }
132
+ addNS(props) {
133
+ new aws_route53_1.NsRecord(this, "NsRecord", {
134
+ zone: this.importedHostedZone,
135
+ comment: props.comment || `NS Record for ${this.importedHostedZone.zoneName}`,
136
+ values: props.values,
137
+ ttl: props.ttl
138
+ });
139
+ }
140
+ addTxt(props) {
141
+ new aws_route53_1.TxtRecord(this, "TxtRecord", {
142
+ zone: this.importedHostedZone,
143
+ comment: props.comment || `TXT Record for ${this.importedHostedZone.zoneName}`,
144
+ values: props.values,
145
+ ttl: props.ttl
146
+ });
147
+ }
148
+ }
149
+ exports.HostedZone = HostedZone;
150
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG9zdGVkWm9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9yZXNvdXJjZXMvYXdzL25ldHdvcmtpbmcvaG9zdGVkWm9uZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFDdkMsNkNBQXlEO0FBQ3pELHNFQUFnRjtBQUNoRixnQ0FBOEI7QUFDOUIsaURBSTZCO0FBQzdCLHlEQWFpQztBQVNqQyxNQUFhLGlCQUFpQjtJQUM1QixNQUFNLENBQUMsTUFBTSxDQUFDLEtBQWUsRUFBRSxZQUFvQixFQUFFLFFBQWdCO1FBQ25FLE1BQU0sWUFBWSxHQUFHLElBQUEsa0NBQWUsRUFBQyxRQUFRLENBQUMsQ0FBQztRQUUvQyxPQUFPLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsRUFBRSxHQUFHLFlBQVksWUFBWSxFQUFFO1lBQ25FLFlBQVksRUFBRSxZQUFZO1lBQzFCLFFBQVEsRUFBRSxRQUFRO1NBQ25CLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQVRELDhDQVNDO0FBRUQsTUFBYSxVQUFXLFNBQVEsc0JBQVM7SUFRdkMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFzQjtRQUM5RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztRQUUvQiwyRUFBMkU7UUFDM0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDO1lBQ2pELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzVCLENBQUM7YUFB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QUFRLEVBQUU7WUFDdkUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO1lBQ3BCLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRztTQUNmLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTVLRCxnQ0E0S0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgQ2ZuT3V0cHV0LCBGbiwgU3RhY2ssIFRhZ3MgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IHRvUGFzY2FsQ2FzZSwgZ2V0U2FmZVpvbmVOYW1lIH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2NhcGl0YWxpc2VTdHJpbmdcIjtcbmltcG9ydCB7IFJvbGUgfSBmcm9tIFwiLi4vaWFtXCI7XG5pbXBvcnQge1xuICBPcmdhbml6YXRpb25QcmluY2lwYWwsXG4gIFBvbGljeURvY3VtZW50LFxuICBQb2xpY3lTdGF0ZW1lbnRcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7XG4gIEFSZWNvcmQsXG4gIHR5cGUgQVJlY29yZFByb3BzLFxuICBDbmFtZVJlY29yZCxcbiAgdHlwZSBDbmFtZVJlY29yZFByb3BzLFxuICBIb3N0ZWRab25lIGFzIEFXU0hvc3RlZFpvbmUsXG4gIHR5cGUgSUhvc3RlZFpvbmUsXG4gIE14UmVjb3JkLFxuICB0eXBlIE14UmVjb3JkUHJvcHMsXG4gIE5zUmVjb3JkLFxuICB0eXBlIE5zUmVjb3JkUHJvcHMsXG4gIFR4dFJlY29yZCxcbiAgdHlwZSBUeHRSZWNvcmRQcm9wc1xufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXJvdXRlNTNcIjtcblxuaW1wb3J0IHsgdHlwZSBBd3NTdGFjayB9IGZyb20gXCIuLi9iYXNlL2F3c1N0YWNrXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSG9zdGVkWm9uZVByb3BzIHtcbiAgem9uZU5hbWU6IHN0cmluZztcbiAgaG9zdGVkWm9uZUlkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgSG9zdGVkWm9uZUZhY3Rvcnkge1xuICBzdGF0aWMgaW1wb3J0KHN0YWNrOiBBd3NTdGFjaywgaG9zdGVkWm9uZUlkOiBzdHJpbmcsIHpvbmVOYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBzYWZlWm9uZU5hbWUgPSBnZXRTYWZlWm9uZU5hbWUoem9uZU5hbWUpO1xuXG4gICAgcmV0dXJuIG5ldyBIb3N0ZWRab25lKHN0YWNrLmdldFN0YWNrKCksIGAke3NhZmVab25lTmFtZX1Ib3N0ZWRab25lYCwge1xuICAgICAgaG9zdGVkWm9uZUlkOiBob3N0ZWRab25lSWQsXG4gICAgICB6b25lTmFtZTogem9uZU5hbWVcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSG9zdGVkWm9uZSBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHByaXZhdGUgaG9zdGVkWm9uZSE6IEFXU0hvc3RlZFpvbmU7XG4gIHByaXZhdGUgaG9zdGVkWm9uZUlkITogc3RyaW5nO1xuICBwcml2YXRlIGltcG9ydGVkSG9zdGVkWm9uZSE6IElIb3N0ZWRab25lO1xuICBwcml2YXRlIHpvbmVOYW1lOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBzY29wZTogQ29uc3RydWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBIb3N0ZWRab25lUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuICAgIHRoaXMuem9uZU5hbWUgPSBwcm9wcy56b25lTmFtZTtcblxuICAgIC8vIElmIGEgaG9zdGVkWm9uZUlkIGlzIHByb3ZpZGVkIGltcG9ydCBpdCwgdW5sZXNzIGNyZWF0ZSBhIG5ldyBob3N0ZWQgem9uZVxuICAgIGlmICghcHJvcHMuaG9zdGVkWm9uZUlkKSB7XG4gICAgICB0aGlzLmFkZEhvc3RlZFpvbmUocHJvcHMuem9uZU5hbWUpO1xuICAgICAgdGhpcy5ob3N0ZWRab25lSWQgPSB0aGlzLmhvc3RlZFpvbmUuaG9zdGVkWm9uZUlkO1xuICAgICAgdGhpcy5kZWxlZ2F0ZUhvc3RlZFpvbmUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ob3N0ZWRab25lSWQgPSBwcm9wcy5ob3N0ZWRab25lSWQ7XG4gICAgICB0aGlzLmltcG9ydEhvc3RlZFpvbmUocHJvcHMuem9uZU5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGdldEludGVybmFsSG9zdGVkWm9uZSgpIHtcbiAgICByZXR1cm4gdGhpcy5ob3N0ZWRab25lIHx8IHRoaXMuaW1wb3J0ZWRIb3N0ZWRab25lO1xuICB9XG5cbiAgc2FmZVpvbmVOYW1lKCkge1xuICAgIHJldHVybiBnZXRTYWZlWm9uZU5hbWUodGhpcy56b25lTmFtZSk7XG4gIH1cblxuICBwcml2YXRlIGFkZEhvc3RlZFpvbmUoem9uZU5hbWU6IHN0cmluZykge1xuICAgIHRoaXMuaG9zdGVkWm9uZSA9IG5ldyBBV1NIb3N0ZWRab25lKFxuICAgICAgdGhpcyxcbiAgICAgIGAke3RoaXMuc2FmZVpvbmVOYW1lKCl9SG9zdGVkWm9uZWAsXG4gICAgICB7XG4gICAgICAgIHpvbmVOYW1lOiB6b25lTmFtZSxcbiAgICAgICAgY29tbWVudDogYEhvc3RlZCBab25lIGZvciAke3pvbmVOYW1lfWBcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBpbXBvcnRIb3N0ZWRab25lKHpvbmVOYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLmltcG9ydGVkSG9zdGVkWm9uZSA9IEFXU0hvc3RlZFpvbmUuZnJvbUhvc3RlZFpvbmVBdHRyaWJ1dGVzKFxuICAgICAgLy8gSG9zdGVkWm9uZS5mcm9tSG9zdGVkWm9uZUF0dHJpYnV0ZXMgZXhwbGljaXRseSBtdXN0IGJlIHBhc3NlZCBhIHN0YWNrIGFzIHBhcmVudCBzY29wZVxuICAgICAgdGhpcy5zY29wZSxcblxuICAgICAgLy8gVXNlIHNhZmVab25lTmFtZSBpbiB0aGUgaWQgc28gd2UgY2FuIHRoZW9yZXRpY2FsbHlcbiAgICAgIC8vICBpbXBvcnQgbXVsdGlwbGUgaG9zdGVkIHpvbmVzIGluIGEgc2luZ2xlIGFwcFxuICAgICAgYCR7dGhpcy5zYWZlWm9uZU5hbWUoKX1JbXBvcnRlZEhvc3RlZFpvbmVgLFxuICAgICAge1xuICAgICAgICBob3N0ZWRab25lSWQ6IHRoaXMuaG9zdGVkWm9uZUlkLFxuICAgICAgICB6b25lTmFtZTogem9uZU5hbWVcbiAgICAgIH1cbiAgICApO1xuXG4gICAgVGFncy5vZih0aGlzLmltcG9ydGVkSG9zdGVkWm9uZSkuYWRkKFxuICAgICAgXCJmamFsbDpjb3N0QWxsb2NhdGlvbjplbnZpcm9ubWVudFwiLFxuICAgICAgXCJtYW5hZ2VtZW50XCJcbiAgICApO1xuICAgIFRhZ3Mub2YodGhpcy5pbXBvcnRlZEhvc3RlZFpvbmUpLmFkZChcbiAgICAgIFwiZmphbGw6Y29zdEFsbG9jYXRpb246c2VydmljZVwiLFxuICAgICAgXCJob3N0ZWRab25lXCJcbiAgICApO1xuICAgIFRhZ3Mub2YodGhpcy5pbXBvcnRlZEhvc3RlZFpvbmUpLmFkZChcbiAgICAgIFwiZmphbGw6Y29zdEFsbG9jYXRpb246ZG9tYWluXCIsXG4gICAgICB6b25lTmFtZVxuICAgICk7XG5cbiAgICAvLyBNYWtlIGV4cG9ydCBuYW1lIHVuaXF1ZSBieSBpbmNsdWRpbmcgdGhlIHN0YWNrIG5hbWUgdG8gYXZvaWQgY29uZmxpY3RzXG4gICAgLy8gd2hlbiBtdWx0aXBsZSBzdGFja3MgaW1wb3J0IHRoZSBzYW1lIGhvc3RlZCB6b25lXG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICBjb25zdCBzdGFja05hbWUgPSBzdGFjay5zdGFja05hbWU7XG4gICAgY29uc3QgZXhwb3J0TmFtZSA9IGAke3N0YWNrTmFtZX0ke3RoaXMuc2FmZVpvbmVOYW1lKCl9SG9zdGVkWm9uZUlkYDtcblxuICAgIGNvbnN0IHNhZmVLZXkgPSB0b1Bhc2NhbENhc2UodGhpcy5zYWZlWm9uZU5hbWUoKSk7XG4gICAgbmV3IENmbk91dHB1dCh0aGlzLCBgJHtzYWZlS2V5fUhvc3RlZFpvbmVJZGAsIHtcbiAgICAgIGtleTogYCR7c2FmZUtleX1Ib3N0ZWRab25lSWRgLFxuICAgICAgdmFsdWU6IHRoaXMuaG9zdGVkWm9uZUlkLFxuICAgICAgZXhwb3J0TmFtZTogZXhwb3J0TmFtZVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBkZWxlZ2F0ZUhvc3RlZFpvbmUoKSB7XG4gICAgY29uc3QgZG9tYWluTGFiZWwgPSB0aGlzLmhvc3RlZFpvbmUuem9uZU5hbWUuc3BsaXQoXCIuXCIpWzBdID8/IFwiZGVmYXVsdFwiO1xuICAgIGNvbnN0IHNhZmVEb21haW5MYWJlbCA9IHRvUGFzY2FsQ2FzZShkb21haW5MYWJlbCk7XG4gICAgY29uc3Qgcm9sZSA9IG5ldyBSb2xlKHRoaXMsIGAke3NhZmVEb21haW5MYWJlbH1EZWxlZ2F0ZUhvc3RlZFpvbmVSb2xlYCwge1xuICAgICAgYXNzdW1lZEJ5OiBuZXcgT3JnYW5pemF0aW9uUHJpbmNpcGFsKEZuLmltcG9ydFZhbHVlKFwiT3JnYW5pc2F0aW9uSWRcIikpLFxuICAgICAgcm9sZU5hbWU6IGAke2RvbWFpbkxhYmVsfURlbGVnYXRlSG9zdGVkWm9uZVJvbGVgLFxuICAgICAgaW5saW5lUG9saWNpZXM6IHtcbiAgICAgICAgW1wibGlzdEhvc3RlZFpvbmVzXCJdOiBuZXcgUG9saWN5RG9jdW1lbnQoe1xuICAgICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICBhY3Rpb25zOiBbXCJyb3V0ZTUzOkxpc3RIb3N0ZWRab25lc0J5TmFtZVwiXSxcbiAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIF1cbiAgICAgICAgfSksXG4gICAgICAgIFtcImNoYW5nZVJlc291cmNlUmVjb3JkU2V0c1wiXTogbmV3IFBvbGljeURvY3VtZW50KHtcbiAgICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgICAgYWN0aW9uczogW1wicm91dGU1MzpDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHNcIl0sXG4gICAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICAgIGBhcm46YXdzOnJvdXRlNTM6Ojpob3N0ZWR6b25lLyR7dGhpcy5ob3N0ZWRab25lLmhvc3RlZFpvbmVJZH1gXG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgXVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5ob3N0ZWRab25lLmdyYW50RGVsZWdhdGlvbihyb2xlKTtcblxuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgXCJEZWxlZ2F0ZUhvc3RlZFpvbmVSb2xlQXJuXCIsIHtcbiAgICAgIGtleTogYCR7c2FmZURvbWFpbkxhYmVsfURlbGVnYXRlSG9zdGVkWm9uZVJvbGVBcm5gLFxuICAgICAgdmFsdWU6IHJvbGUucm9sZUFybixcbiAgICAgIGV4cG9ydE5hbWU6IGAke2RvbWFpbkxhYmVsfURlbGVnYXRlSG9zdGVkWm9uZVJvbGVBcm5gXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYWRkQVJlY29yZChwcm9wczogT21pdDxBUmVjb3JkUHJvcHMsIFwiem9uZVwiPikge1xuICAgIG5ldyBBUmVjb3JkKHRoaXMsIFwiQVJlY29yZFwiLCB7XG4gICAgICB6b25lOiB0aGlzLmltcG9ydGVkSG9zdGVkWm9uZSxcbiAgICAgIHJlY29yZE5hbWU6IHByb3BzLnJlY29yZE5hbWUsXG4gICAgICBjb21tZW50OlxuICAgICAgICBwcm9wcy5jb21tZW50IHx8IGBBIFJlY29yZCBmb3IgJHt0aGlzLmltcG9ydGVkSG9zdGVkWm9uZS56b25lTmFtZX1gLFxuICAgICAgdGFyZ2V0OiBwcm9wcy50YXJnZXQsXG4gICAgICB0dGw6IHByb3BzLnR0bFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFkZENuYW1lKHByb3BzOiBPbWl0PENuYW1lUmVjb3JkUHJvcHMsIFwiem9uZVwiPikge1xuICAgIG5ldyBDbmFtZVJlY29yZCh0aGlzLCBcIkNuYW1lUmVjb3JkXCIsIHtcbiAgICAgIGRvbWFpbk5hbWU6IHByb3BzLmRvbWFpbk5hbWUsXG4gICAgICB6b25lOiB0aGlzLmltcG9ydGVkSG9zdGVkWm9uZSxcbiAgICAgIGNvbW1lbnQ6XG4gICAgICAgIHByb3BzLmNvbW1lbnQgfHwgYENOQU1FIFJlY29yZCBmb3IgJHt0aGlzLmltcG9ydGVkSG9zdGVkWm9uZS56b25lTmFtZX1gLFxuICAgICAgdHRsOiBwcm9wcy50dGxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRNeChwcm9wczogT21pdDxNeFJlY29yZFByb3BzLCBcInpvbmVcIj4pIHtcbiAgICBuZXcgTXhSZWNvcmQodGhpcywgXCJNeFJlY29yZFwiLCB7XG4gICAgICB6b25lOiB0aGlzLmltcG9ydGVkSG9zdGVkWm9uZSxcbiAgICAgIGNvbW1lbnQ6XG4gICAgICAgIHByb3BzLmNvbW1lbnQgfHwgYE1YIFJlY29yZCBmb3IgJHt0aGlzLmltcG9ydGVkSG9zdGVkWm9uZS56b25lTmFtZX1gLFxuICAgICAgdmFsdWVzOiBwcm9wcy52YWx1ZXMsXG4gICAgICB0dGw6IHByb3BzLnR0bFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFkZE5TKHByb3BzOiBPbWl0PE5zUmVjb3JkUHJvcHMsIFwiem9uZVwiPikge1xuICAgIG5ldyBOc1JlY29yZCh0aGlzLCBcIk5zUmVjb3JkXCIsIHtcbiAgICAgIHpvbmU6IHRoaXMuaW1wb3J0ZWRIb3N0ZWRab25lLFxuICAgICAgY29tbWVudDpcbiAgICAgICAgcHJvcHMuY29tbWVudCB8fCBgTlMgUmVjb3JkIGZvciAke3RoaXMuaW1wb3J0ZWRIb3N0ZWRab25lLnpvbmVOYW1lfWAsXG4gICAgICB2YWx1ZXM6IHByb3BzLnZhbHVlcyxcbiAgICAgIHR0bDogcHJvcHMudHRsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYWRkVHh0KHByb3BzOiBPbWl0PFR4dFJlY29yZFByb3BzLCBcInpvbmVcIj4pIHtcbiAgICBuZXcgVHh0UmVjb3JkKHRoaXMsIFwiVHh0UmVjb3JkXCIsIHtcbiAgICAgIHpvbmU6IHRoaXMuaW1wb3J0ZWRIb3N0ZWRab25lLFxuICAgICAgY29tbWVudDpcbiAgICAgICAgcHJvcHMuY29tbWVudCB8fCBgVFhUIFJlY29yZCBmb3IgJHt0aGlzLmltcG9ydGVkSG9zdGVkWm9uZS56b25lTmFtZX1gLFxuICAgICAgdmFsdWVzOiBwcm9wcy52YWx1ZXMsXG4gICAgICB0dGw6IHByb3BzLnR0bFxuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -1,3 +1,7 @@
1
+ export * from "./domain";
2
+ export * from "./domainCertificate";
3
+ export * from "./hostedZone";
1
4
  export * from "./ipam";
2
5
  export * from "./ipamPool";
6
+ export * from "./securityGroup";
3
7
  export * from "./vpc";
@@ -14,7 +14,11 @@ 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
+ __exportStar(require("./domain"), exports);
18
+ __exportStar(require("./domainCertificate"), exports);
19
+ __exportStar(require("./hostedZone"), exports);
17
20
  __exportStar(require("./ipam"), exports);
18
21
  __exportStar(require("./ipamPool"), exports);
22
+ __exportStar(require("./securityGroup"), exports);
19
23
  __exportStar(require("./vpc"), exports);
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWIvcmVzb3VyY2VzL2F3cy9uZXR3b3JraW5nL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx5Q0FBdUI7QUFDdkIsNkNBQTJCO0FBQzNCLHdDQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL2lwYW1cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2lwYW1Qb29sXCI7XG5leHBvcnQgKiBmcm9tIFwiLi92cGNcIjtcbiJdfQ==
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWIvcmVzb3VyY2VzL2F3cy9uZXR3b3JraW5nL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBeUI7QUFDekIsc0RBQW9DO0FBQ3BDLCtDQUE2QjtBQUM3Qix5Q0FBdUI7QUFDdkIsNkNBQTJCO0FBQzNCLGtEQUFnQztBQUNoQyx3Q0FBc0IiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9kb21haW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2RvbWFpbkNlcnRpZmljYXRlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9ob3N0ZWRab25lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pcGFtXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pcGFtUG9vbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vc2VjdXJpdHlHcm91cFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdnBjXCI7XG4iXX0=
@@ -10,6 +10,17 @@ const resourceShare_1 = require("../utilities/resourceShare");
10
10
  const customResource_1 = require("../utilities/customResource");
11
11
  const getAccountId_1 = require("../../../utils/getAccountId");
12
12
  const validationLogger_1 = require("../../../utils/validationLogger");
13
+ // IPAM enforces a low concurrent-mutation limit (not publicly documented).
14
+ // Account pools are serialised WITHIN each region (they mutate the same regional
15
+ // pool parent). Across regions, account pools run in parallel because they mutate
16
+ // DIFFERENT regional pool parents — this keeps effective concurrency at 2 (one
17
+ // per region), well within observed AWS limits (~2-3).
18
+ const IPAM_POOL_BATCH_SIZE = 1;
19
+ const IPAM_TAGS = {
20
+ OPERATIONS_POOL: "fjall:operations:pool",
21
+ COST_ALLOCATION_ENVIRONMENT: "fjall:costAllocation:environment",
22
+ COST_ALLOCATION_ACCOUNT_NAME: "fjall:costAllocation:accountName"
23
+ };
13
24
  class IpamPool extends constructs_1.Construct {
14
25
  constructor(scope, id, props) {
15
26
  super(scope, id);
@@ -49,16 +60,20 @@ class IpamPool extends constructs_1.Construct {
49
60
  autoImport: true,
50
61
  tags: [
51
62
  {
52
- key: "fjall:operations:pool",
63
+ key: IPAM_TAGS.OPERATIONS_POOL,
53
64
  value: "top-level"
54
65
  },
55
66
  {
56
- key: "fjall:costAllocation:environment",
67
+ key: IPAM_TAGS.COST_ALLOCATION_ENVIRONMENT,
57
68
  value: "management"
58
69
  }
59
70
  ]
60
71
  });
61
- // Create regional pools as children of the root pool
72
+ // Create regional pools as children of the root pool.
73
+ // Serialised to avoid EC2 IPAM "too many concurrent mutations" errors —
74
+ // each regional pool + CIDR mutates the parent root pool resource, and
75
+ // IPAM rejects parallel mutations on the same parent.
76
+ let previousRegionalCidr;
62
77
  for (const region of regions) {
63
78
  const regionSuffix = region.replace(/-/g, "");
64
79
  // Create a regional pool for this specific region
@@ -71,25 +86,34 @@ class IpamPool extends constructs_1.Construct {
71
86
  autoImport: true,
72
87
  tags: [
73
88
  {
74
- key: "fjall:operations:pool",
89
+ key: IPAM_TAGS.OPERATIONS_POOL,
75
90
  value: `regional-${region}`
76
91
  },
77
92
  {
78
- key: "fjall:costAllocation:environment",
93
+ key: IPAM_TAGS.COST_ALLOCATION_ENVIRONMENT,
79
94
  value: "management"
80
95
  }
81
96
  ]
82
97
  });
98
+ // Chain: each regional pool waits for the previous region's CIDR to complete.
99
+ // This serialises regional pool creation, preventing concurrent mutations
100
+ // on the root pool resource.
101
+ if (previousRegionalCidr) {
102
+ regionalPool.addDependency(previousRegionalCidr);
103
+ }
83
104
  const regionalCidrAllocation = new aws_ec2_1.CfnIPAMPoolCidr(this, `RegionalPoolCidr${regionSuffix}`, {
84
105
  ipamPoolId: regionalPool.attrIpamPoolId,
85
106
  netmaskLength: 10 // Each region gets a /10 (4,194,304 IPs)
86
107
  });
87
- // Create account pools under each regional pool.
88
- // IPAM enforces a low concurrent-mutation limit (not publicly documented).
89
- // Batch account pools so each batch depends on the previous batch
90
- // completing, limiting concurrent IPAM pool mutations.
91
- const IPAM_CONCURRENCY_LIMIT = 2;
92
- const batches = [];
108
+ previousRegionalCidr = regionalCidrAllocation;
109
+ // Serialised account pool creation within each region.
110
+ // Account pools within a region all mutate the same regional pool parent,
111
+ // so they must be serialised. Account pools in DIFFERENT regions mutate
112
+ // different regional pool parents, so they can safely run in parallel.
113
+ //
114
+ // Uses CfnResource.addDependency() (not node.addDependency) for
115
+ // guaranteed CloudFormation DependsOn generation between L1 constructs.
116
+ let previousWaveAnchorCidr;
93
117
  for (let i = 0; i < organisationAccounts.length; i++) {
94
118
  const account = organisationAccounts[i];
95
119
  const accountId = (0, getAccountId_1.default)(account);
@@ -102,40 +126,38 @@ class IpamPool extends constructs_1.Construct {
102
126
  allocationDefaultNetmaskLength: defaultNetmaskLength,
103
127
  allocationResourceTags: [
104
128
  {
105
- key: "fjall:operations:pool",
129
+ key: IPAM_TAGS.OPERATIONS_POOL,
106
130
  value: `${accountId}-${region}`
107
131
  }
108
132
  ],
109
133
  autoImport: true,
110
134
  tags: [
111
135
  {
112
- key: "fjall:operations:pool",
136
+ key: IPAM_TAGS.OPERATIONS_POOL,
113
137
  value: `${accountId}-${region}`
114
138
  },
115
139
  {
116
- key: "fjall:costAllocation:accountName",
140
+ key: IPAM_TAGS.COST_ALLOCATION_ACCOUNT_NAME,
117
141
  value: account
118
142
  }
119
143
  ]
120
144
  });
121
145
  // Ensure the account pool is created after the regional CIDR allocation
122
- ipamPool.node.addDependency(regionalCidrAllocation);
123
- // Each batch of IPAM_CONCURRENCY_LIMIT pools depends on ALL pools
124
- // from the previous batch, so the next batch only starts once the
125
- // entire previous batch has completed.
126
- const batchIndex = Math.floor(i / IPAM_CONCURRENCY_LIMIT);
127
- if (batchIndex > 0) {
128
- for (const previousPool of batches[batchIndex - 1]) {
129
- ipamPool.node.addDependency(previousPool);
130
- }
146
+ ipamPool.addDependency(regionalCidrAllocation);
147
+ // Wave boundary: pools in wave N+1 depend on the last CIDR from wave N
148
+ if (previousWaveAnchorCidr) {
149
+ ipamPool.addDependency(previousWaveAnchorCidr);
131
150
  }
132
- if (!batches[batchIndex])
133
- batches[batchIndex] = [];
134
- batches[batchIndex].push(ipamPool);
135
151
  const cidrAllocation = new aws_ec2_1.CfnIPAMPoolCidr(this, `${account}PoolCidr${provisionedNetmaskLength}${regionSuffix}`, {
136
152
  ipamPoolId: ipamPool.attrIpamPoolId,
137
153
  netmaskLength: provisionedNetmaskLength
138
154
  });
155
+ // The last pool in each wave anchors the next wave's dependency
156
+ const isLastInWave = (i + 1) % IPAM_POOL_BATCH_SIZE === 0 ||
157
+ i === organisationAccounts.length - 1;
158
+ if (isLastInWave) {
159
+ previousWaveAnchorCidr = cidrAllocation;
160
+ }
139
161
  // On stack deletion, VPC allocations (not managed by CloudFormation)
140
162
  // block CIDR deprovisioning. This custom resource releases them first.
141
163
  const allocationCleanup = new customResource_1.CustomResource(this, `${account}IpamCleanup${regionSuffix}`, {
@@ -143,7 +165,8 @@ class IpamPool extends constructs_1.Construct {
143
165
  timeout: aws_cdk_lib_1.Duration.minutes(5),
144
166
  lambdaDescription: `${account} IPAM pool allocation cleanup - ${region}`,
145
167
  properties: {
146
- IpamPoolId: ipamPool.attrIpamPoolId
168
+ IpamPoolId: ipamPool.attrIpamPoolId,
169
+ PoolRegion: region
147
170
  },
148
171
  inlinePolicy: [
149
172
  new aws_iam_1.PolicyStatement({
@@ -164,7 +187,8 @@ exports.handler = async (event) => {
164
187
  return { PhysicalResourceId: physicalResourceId };
165
188
  }
166
189
  const poolId = event.ResourceProperties.IpamPoolId;
167
- const ec2 = new EC2Client({});
190
+ const poolRegion = event.ResourceProperties.PoolRegion;
191
+ const ec2 = new EC2Client({ region: poolRegion });
168
192
  let nextToken;
169
193
  do {
170
194
  const res = await ec2.send(new GetIpamPoolAllocationsCommand({
@@ -194,8 +218,8 @@ exports.handler = async (event) => {
194
218
  resourceArns: [ipamPool.attrArn],
195
219
  tags: [
196
220
  {
197
- key: "fjall:costAllocation:environment",
198
- value: `management`
221
+ key: IPAM_TAGS.COST_ALLOCATION_ENVIRONMENT,
222
+ value: "management"
199
223
  }
200
224
  ]
201
225
  });
@@ -213,6 +237,8 @@ exports.handler = async (event) => {
213
237
  exportName: `IpamPoolArn${accountId}${regionSuffix}`
214
238
  });
215
239
  }
240
+ // No cross-region chaining needed: account pools in different regions
241
+ // mutate different parent resources and can safely run in parallel.
216
242
  }
217
243
  }
218
244
  }
@@ -227,4 +253,4 @@ class IpamPoolStack extends aws_cdk_lib_1.Stack {
227
253
  }
228
254
  }
229
255
  exports.IpamPoolStack = IpamPoolStack;
230
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBhbVBvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWIvcmVzb3VyY2VzL2F3cy9uZXR3b3JraW5nL2lwYW1Qb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUE4RTtBQUM5RSwyQ0FBdUM7QUFDdkMsaURBRzZCO0FBQzdCLHVEQUFpRDtBQUNqRCxpREFBOEQ7QUFDOUQsOERBQTJEO0FBQzNELGdFQUE2RDtBQUM3RCw4REFBdUQ7QUFDdkQsc0VBQThEO0FBeUI5RCxNQUFhLFFBQVMsU0FBUSxzQkFBUztJQUNyQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW9CO1FBQzVELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsMERBQTBEO1FBQzFELE1BQU0seUJBQXlCLEdBQzdCLEtBQUssQ0FBQyxTQUFTLElBQUksZ0JBQUUsQ0FBQyxXQUFXLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUVqRSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQzlCLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksS0FBSyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUVELE1BQU0sb0JBQW9CLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUM3RCxPQUFPLENBQUMsV0FBVyxFQUFFLENBQ3RCLENBQUM7UUFFRix1REFBdUQ7UUFDdkQsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLENBQUMsOEJBQThCLElBQUksRUFBRSxDQUFDO1FBQ3hFLE1BQU0sd0JBQXdCLEdBQUcsS0FBSyxDQUFDLHdCQUF3QixJQUFJLEVBQUUsQ0FBQztRQUV0RSxrRkFBa0Y7UUFDbEYsSUFBSSxvQkFBb0IsR0FBRyxFQUFFLElBQUksb0JB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QUNqRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDN0IsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO1lBQzlCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztTQUN2QixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFURCxzQ0FTQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENmbk91dHB1dCwgRHVyYXRpb24sIEZuLCB0eXBlIFN0YWNrUHJvcHMsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHtcbiAgQ2ZuSVBBTVBvb2wgYXMgSXBhbVBvb2xDbGFzcyxcbiAgQ2ZuSVBBTVBvb2xDaWRyXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWMyXCI7XG5pbXBvcnQgeyBSdW50aW1lIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIjtcbmltcG9ydCB7IEVmZmVjdCwgUG9saWN5U3RhdGVtZW50IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IFJlc291cmNlU2hhcmUgfSBmcm9tIFwiLi4vdXRpbGl0aWVzL3Jlc291cmNlU2hhcmVcIjtcbmltcG9ydCB7IEN1c3RvbVJlc291cmNlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9jdXN0b21SZXNvdXJjZVwiO1xuaW1wb3J0IGdldEFjY291bnRJZCBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvZ2V0QWNjb3VudElkXCI7XG5pbXBvcnQgeyBGamFsbExvZ2dlciB9IGZyb20gXCIuLi8uLi8uLi91dGlscy92YWxpZGF0aW9uTG9nZ2VyXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSXBhbVBvb2xQcm9wcyBleHRlbmRzIFN0YWNrUHJvcHMge1xuICBvcmdBY2NvdW50czogc3RyaW5nW107XG4gIGlwYW1TY29wZT86IHN0cmluZztcbiAgcmVnaW9uczogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgbmV0bWFzayBsZW5ndGggKC9DSURSKSBlYWNoIGNoaWxkIElQQU0gcG9vbCBzaG91bGQgcmVjZWl2ZS5cbiAgICogQ29udHJvbHMgdGhlIHNpemUgb2YgQ0lEUiBibG9ja3MgYXV0b21hdGljYWxseSBhbGxvY2F0ZWQgdG8gVlBDcyBmcm9tIHRoZSBwb29sLlxuICAgKiBBY2NlcHRlZCByYW5nZTogLzE2ICg2NSw1MzYgSVBzKSDigJMgLzI4ICgxNiBJUHMpLiBEZWZhdWx0cyB0byAvMjAgKDQsMDk2IElQcykuXG4gICAqL1xuICBhbGxvY2F0aW9uRGVmYXVsdE5ldG1hc2tMZW5ndGg/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbmV0bWFzayBsZW5ndGggKC9DSURSKSBwcm92aXNpb25lZCBpbnRvIGVhY2ggY2hpbGQgSVBBTSBwb29sIG9uIGNyZWF0aW9uLlxuICAgKiBEZXRlcm1pbmVzIHRoZSB0b3RhbCBhZGRyZXNzIHNwYWNlIGF2YWlsYWJsZSBmb3IgVlBDIGFsbG9jYXRpb25zIGluIHRoYXQgYWNjb3VudC5cbiAgICogQWNjZXB0ZWQgcmFuZ2U6IC8xMyAoNTI0LDI4OCBJUHMpIOKAkyAvMTYgKDY1LDUzNiBJUHMpLiBEZWZhdWx0cyB0byAvMTQuXG4gICAqL1xuICBwcm92aXNpb25lZE5ldG1hc2tMZW5ndGg/OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBJcGFtUG9vbFN0YWNrUHJvcHMgZXh0ZW5kcyBTdGFja1Byb3BzIHtcbiAgb3JnQWNjb3VudHM6IHN0cmluZ1tdO1xuICByZWdpb25zOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNsYXNzIElwYW1Qb29sIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElwYW1Qb29sUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gR2V0IHRoZSBkZWZhdWx0IElQQU0gc2NvcGUgSUQgZnJvbSBwcm9wcywgb3IgQ0ZOIGltcG9ydFxuICAgIGNvbnN0IElwYW1Qcml2YXRlRGVmYXVsdFNjb3BlSWQgPVxuICAgICAgcHJvcHMuaXBhbVNjb3BlIHx8IEZuLmltcG9ydFZhbHVlKFwiSXBhbVByaXZhdGVEZWZhdWx0U2NvcGVJZFwiKTtcblxuICAgIGNvbnN0IHJlZ2lvbnMgPSBwcm9wcy5yZWdpb25zO1xuICAgIGlmICghcmVnaW9ucyB8fCByZWdpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXQgbGVhc3Qgb25lIHJlZ2lvbiBtdXN0IGJlIHNwZWNpZmllZCBmb3IgSVBBTSBwb29sc1wiKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcmdhbmlzYXRpb25BY2NvdW50cyA9IHByb3BzLm9yZ0FjY291bnRzLm1hcCgoYWNjb3VudCkgPT5cbiAgICAgIGFjY291bnQudG9Mb3dlckNhc2UoKVxuICAgICk7XG5cbiAgICAvLyBEZXRlcm1pbmUgdGhlIGNoaWxkLXBvb2wgQ0lEUiBzaXplIChkZWZhdWx0cyB0byAvMjApXG4gICAgY29uc3QgZGVmYXVsdE5ldG1hc2tMZW5ndGggPSBwcm9wcy5hbGxvY2F0aW9uRGVmYXVsdE5ldG1hc2tMZW5ndGggPz8gMjA7XG4gICAgY29uc3QgcHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RoID0gcHJvcHMucHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RoID8/IDE0O1xuXG4gICAgLy8gQmFzaWMgdmFsaWRhdGlvbiDigJMgLzE2IHRvIC8yOCBpbmNsdXNpdmUgYXJlIGNvbnNpZGVyZWQgc2FmZSBmb3IgVlBDIGFsbG9jYXRpb25zXG4gICAgaWYgKGRlZmF1bHROZXRtYXNrTGVuZ3RoIDwgMTYgfHwgZGVmYXVsdE5ldG1hc2tMZW5ndGggPiAyOCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgYWxsb2NhdGlvbkRlZmF1bHROZXRtYXNrTGVuZ3RoIG11c3QgYmUgYmV0d2VlbiAxNiBhbmQgMjggKGluY2x1c2l2ZSkuIFJlY2VpdmVkOiAke2RlZmF1bHROZXRtYXNrTGVuZ3RofWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgcHJvdmlzaW9uZWQgYmxvY2sgc2l6ZSAoLzEzIHRvIC8xNilcbiAgICBpZiAocHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RoIDwgMTMgfHwgcHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RoID4gMTYpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYHByb3Zpc2lvbmVkTmV0bWFza0xlbmd0aCBtdXN0IGJlIGJldHdlZW4gMTMgYW5kIDE2IChpbmNsdXNpdmUpLiBSZWNlaXZlZDogJHtwcm92aXNpb25lZE5ldG1hc2tMZW5ndGh9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBXYXJuIGlmIHVzZXIgcmVxdWVzdHMgVlBDIGFsbG9jYXRpb25zIGxhcmdlciB0aGFuIHRoZSBwcm92aXNpb25lZCBwb29sXG4gICAgaWYgKGRlZmF1bHROZXRtYXNrTGVuZ3RoIDwgcHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RoKSB7XG4gICAgICBGamFsbExvZ2dlci53YXJuKFxuICAgICAgICBgJ2FsbG9jYXRpb25EZWZhdWx0TmV0bWFza0xlbmd0aCcgKC8ke2RlZmF1bHROZXRtYXNrTGVuZ3RofSkgaXMgbGFyZ2VyIHRoYW4gJ3Byb3Zpc2lvbmVkTmV0bWFza0xlbmd0aCcgKC8ke3Byb3Zpc2lvbmVkTmV0bWFza0xlbmd0aH0pLiBgICtcbiAgICAgICAgICBgVlBDIGFsbG9jYXRpb24gbWF5IGZhaWwgaWYgdGhlIHBvb2wgY2Fubm90IHNhdGlzZnkgdGhlIHJlcXVlc3QuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBUb3AgTGV2ZWwgUG9vbFxuICAgIGNvbnN0IHJvb3RQb29sID0gbmV3IElwYW1Qb29sQ2xhc3ModGhpcywgXCJUb3BMZXZlbElwYW1Qb29sXCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBgUm9vdCBJUEFNIHBvb2wgKEdsb2JhbClgLFxuICAgICAgYWRkcmVzc0ZhbWlseTogXCJpcHY0XCIsXG4gICAgICBpcGFtU2NvcGVJZDogSXBhbVByaXZhdGVEZWZhdWx0U2NvcGVJZCxcbiAgICAgIHByb3Zpc2lvbmVkQ2lkcnM6IFtcbiAgICAgICAgeyBjaWRyOiBcIjEwLjAuMC4wLzhcIiB9LFxuICAgICAgICB7IGNpZHI6IFwiMTcyLjE2LjAuMC8xMlwiIH0sXG4gICAgICAgIHsgY2lkcjogXCIxOTIuMTY4LjAuMC8xNlwiIH1cbiAgICAgIF0sXG4gICAgICBhdXRvSW1wb3J0OiB0cnVlLFxuICAgICAgdGFnczogW1xuICAgICAgICB7XG4gICAgICAgICAga2V5OiBcImZqYWxsOm9wZXJhdGlvbnM6cG9vbFwiLFxuICAgICAgICAgIHZhbHVlOiBcInRvcC1sZXZlbFwiXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBrZXk6IFwiZmphbGw6Y29zdEFsbG9jYXRpb246ZW52aXJvbm1lbnRcIixcbiAgICAgICAgICB2YWx1ZTogXCJtYW5hZ2VtZW50XCJcbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0pO1xuXG4gICAgLy8gQ3JlYXRlIHJlZ2lvbmFsIHBvb2xzIGFzIGNoaWxkcmVuIG9mIHRoZSByb290IHBvb2xcbiAgICBmb3IgKGNvbnN0IHJlZ2lvbiBvZiByZWdpb25zKSB7XG4gICAgICBjb25zdCByZWdpb25TdWZmaXggPSByZWdpb24ucmVwbGFjZSgvLS9nLCBcIlwiKTtcblxuICAgICAgLy8gQ3JlYXRlIGEgcmVnaW9uYWwgcG9vbCBmb3IgdGhpcyBzcGVjaWZpYyByZWdpb25cbiAgICAgIGNvbnN0IHJlZ2lvbmFsUG9vbCA9IG5ldyBJcGFtUG9vbENsYXNzKFxuICAgICAgICB0aGlzLFxuICAgICAgICBgUmVnaW9uYWxQb29sJHtyZWdpb25TdWZmaXh9YCxcbiAgICAgICAge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgUmVnaW9uYWwgSVBBTSBwb29sIC0gJHtyZWdpb259YCxcbiAgICAgICAgICBhZGRyZXNzRmFtaWx5OiBcImlwdjRcIixcbiAgICAgICAgICBpcGFtU2NvcGVJZDogSXBhbVByaXZhdGVEZWZhdWx0U2NvcGVJZCxcbiAgICAgICAgICBsb2NhbGU6IHJlZ2lvbixcbiAgICAgICAgICBzb3VyY2VJcGFtUG9vbElkOiByb290UG9vbC5hdHRySXBhbVBvb2xJZCxcbiAgICAgICAgICBhdXRvSW1wb3J0OiB0cnVlLFxuICAgICAgICAgIHRhZ3M6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAga2V5OiBcImZqYWxsOm9wZXJhdGlvbnM6cG9vbFwiLFxuICAgICAgICAgICAgICB2YWx1ZTogYHJlZ2lvbmFsLSR7cmVnaW9ufWBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGtleTogXCJmamFsbDpjb3N0QWxsb2NhdGlvbjplbnZpcm9ubWVudFwiLFxuICAgICAgICAgICAgICB2YWx1ZTogXCJtYW5hZ2VtZW50XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHJlZ2lvbmFsQ2lkckFsbG9jYXRpb24gPSBuZXcgQ2ZuSVBBTVBvb2xDaWRyKFxuICAgICAgICB0aGlzLFxuICAgICAgICBgUmVnaW9uYWxQb29sQ2lkciR7cmVnaW9uU3VmZml4fWAsXG4gICAgICAgIHtcbiAgICAgICAgICBpcGFtUG9vbElkOiByZWdpb25hbFBvb2wuYXR0cklwYW1Qb29sSWQsXG4gICAgICAgICAgbmV0bWFza0xlbmd0aDogMTAgLy8gRWFjaCByZWdpb24gZ2V0cyBhIC8xMCAoNCwxOTQsMzA0IElQcylcbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgLy8gQ3JlYXRlIGFjY291bnQgcG9vbHMgdW5kZXIgZWFjaCByZWdpb25hbCBwb29sLlxuICAgICAgLy8gSVBBTSBlbmZvcmNlcyBhIGxvdyBjb25jdXJyZW50LW11dGF0aW9uIGxpbWl0IChub3QgcHVibGljbHkgZG9jdW1lbnRlZCkuXG4gICAgICAvLyBCYXRjaCBhY2NvdW50IHBvb2xzIHNvIGVhY2ggYmF0Y2ggZGVwZW5kcyBvbiB0aGUgcHJldmlvdXMgYmF0Y2hcbiAgICAgIC8vIGNvbXBsZXRpbmcsIGxpbWl0aW5nIGNvbmN1cnJlbnQgSVBBTSBwb29sIG11dGF0aW9ucy5cbiAgICAgIGNvbnN0IElQQU1fQ09OQ1VSUkVOQ1lfTElNSVQgPSAyO1xuICAgICAgY29uc3QgYmF0Y2hlczogSXBhbVBvb2xDbGFzc1tdW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JnYW5pc2F0aW9uQWNjb3VudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgYWNjb3VudCA9IG9yZ2FuaXNhdGlvbkFjY291bnRzW2ldO1xuICAgICAgICBjb25zdCBhY2NvdW50SWQgPSBnZXRBY2NvdW50SWQoYWNjb3VudCk7XG5cbiAgICAgICAgY29uc3QgaXBhbVBvb2wgPSBuZXcgSXBhbVBvb2xDbGFzcyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGAke2FjY291bnR9SXBhbVBvb2wke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHthY2NvdW50fSAtIElQQU0gcG9vbCAtICR7cmVnaW9ufWAsXG4gICAgICAgICAgICBhZGRyZXNzRmFtaWx5OiBcImlwdjRcIixcbiAgICAgICAgICAgIGlwYW1TY29wZUlkOiBJcGFtUHJpdmF0ZURlZmF1bHRTY29wZUlkLFxuICAgICAgICAgICAgbG9jYWxlOiByZWdpb24sXG4gICAgICAgICAgICBzb3VyY2VJcGFtUG9vbElkOiByZWdpb25hbFBvb2wuYXR0cklwYW1Qb29sSWQsXG4gICAgICAgICAgICBhbGxvY2F0aW9uRGVmYXVsdE5ldG1hc2tMZW5ndGg6IGRlZmF1bHROZXRtYXNrTGVuZ3RoLFxuICAgICAgICAgICAgYWxsb2NhdGlvblJlc291cmNlVGFnczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2V5OiBcImZqYWxsOm9wZXJhdGlvbnM6cG9vbFwiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBgJHthY2NvdW50SWR9LSR7cmVnaW9ufWBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGF1dG9JbXBvcnQ6IHRydWUsXG4gICAgICAgICAgICB0YWdzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBrZXk6IFwiZmphbGw6b3BlcmF0aW9uczpwb29sXCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGAke2FjY291bnRJZH0tJHtyZWdpb259YFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2V5OiBcImZqYWxsOmNvc3RBbGxvY2F0aW9uOmFjY291bnROYW1lXCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGFjY291bnRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICAvLyBFbnN1cmUgdGhlIGFjY291bnQgcG9vbCBpcyBjcmVhdGVkIGFmdGVyIHRoZSByZWdpb25hbCBDSURSIGFsbG9jYXRpb25cbiAgICAgICAgaXBhbVBvb2wubm9kZS5hZGREZXBlbmRlbmN5KHJlZ2lvbmFsQ2lkckFsbG9jYXRpb24pO1xuXG4gICAgICAgIC8vIEVhY2ggYmF0Y2ggb2YgSVBBTV9DT05DVVJSRU5DWV9MSU1JVCBwb29scyBkZXBlbmRzIG9uIEFMTCBwb29sc1xuICAgICAgICAvLyBmcm9tIHRoZSBwcmV2aW91cyBiYXRjaCwgc28gdGhlIG5leHQgYmF0Y2ggb25seSBzdGFydHMgb25jZSB0aGVcbiAgICAgICAgLy8gZW50aXJlIHByZXZpb3VzIGJhdGNoIGhhcyBjb21wbGV0ZWQuXG4gICAgICAgIGNvbnN0IGJhdGNoSW5kZXggPSBNYXRoLmZsb29yKGkgLyBJUEFNX0NPTkNVUlJFTkNZX0xJTUlUKTtcbiAgICAgICAgaWYgKGJhdGNoSW5kZXggPiAwKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBwcmV2aW91c1Bvb2wgb2YgYmF0Y2hlc1tiYXRjaEluZGV4IC0gMV0pIHtcbiAgICAgICAgICAgIGlwYW1Qb29sLm5vZGUuYWRkRGVwZW5kZW5jeShwcmV2aW91c1Bvb2wpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWJhdGNoZXNbYmF0Y2hJbmRleF0pIGJhdGNoZXNbYmF0Y2hJbmRleF0gPSBbXTtcbiAgICAgICAgYmF0Y2hlc1tiYXRjaEluZGV4XS5wdXNoKGlwYW1Qb29sKTtcblxuICAgICAgICBjb25zdCBjaWRyQWxsb2NhdGlvbiA9IG5ldyBDZm5JUEFNUG9vbENpZHIoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBgJHthY2NvdW50fVBvb2xDaWRyJHtwcm92aXNpb25lZE5ldG1hc2tMZW5ndGh9JHtyZWdpb25TdWZmaXh9YCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpcGFtUG9vbElkOiBpcGFtUG9vbC5hdHRySXBhbVBvb2xJZCxcbiAgICAgICAgICAgIG5ldG1hc2tMZW5ndGg6IHByb3Zpc2lvbmVkTmV0bWFza0xlbmd0aFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICAvLyBPbiBzdGFjayBkZWxldGlvbiwgVlBDIGFsbG9jYXRpb25zIChub3QgbWFuYWdlZCBieSBDbG91ZEZvcm1hdGlvbilcbiAgICAgICAgLy8gYmxvY2sgQ0lEUiBkZXByb3Zpc2lvbmluZy4gVGhpcyBjdXN0b20gcmVzb3VyY2UgcmVsZWFzZXMgdGhlbSBmaXJzdC5cbiAgICAgICAgY29uc3QgYWxsb2NhdGlvbkNsZWFudXAgPSBuZXcgQ3VzdG9tUmVzb3VyY2UoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBgJHthY2NvdW50fUlwYW1DbGVhbnVwJHtyZWdpb25TdWZmaXh9YCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICAgIGxhbWJkYURlc2NyaXB0aW9uOiBgJHthY2NvdW50fSBJUEFNIHBvb2wgYWxsb2NhdGlvbiBjbGVhbnVwIC0gJHtyZWdpb259YCxcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgSXBhbVBvb2xJZDogaXBhbVBvb2wuYXR0cklwYW1Qb29sSWRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbmxpbmVQb2xpY3k6IFtcbiAgICAgICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAgICAgXCJlYzI6R2V0SXBhbVBvb2xBbGxvY2F0aW9uc1wiLFxuICAgICAgICAgICAgICAgICAgXCJlYzI6UmVsZWFzZUlwYW1Qb29sQWxsb2NhdGlvblwiXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl1cbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBpbmxpbmVDb2RlOiBgXG5jb25zdCB7IEVDMkNsaWVudCwgR2V0SXBhbVBvb2xBbGxvY2F0aW9uc0NvbW1hbmQsIFJlbGVhc2VJcGFtUG9vbEFsbG9jYXRpb25Db21tYW5kIH0gPSByZXF1aXJlKCdAYXdzLXNkay9jbGllbnQtZWMyJyk7XG5cbmV4cG9ydHMuaGFuZGxlciA9IGFzeW5jIChldmVudCkgPT4ge1xuICBjb25zdCBwaHlzaWNhbFJlc291cmNlSWQgPSBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgfHwgZXZlbnQuTG9naWNhbFJlc291cmNlSWQgfHwgJ2lwYW0tcG9vbC1jbGVhbnVwJztcbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlICE9PSAnRGVsZXRlJykge1xuICAgIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkIH07XG4gIH1cbiAgY29uc3QgcG9vbElkID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLklwYW1Qb29sSWQ7XG4gIGNvbnN0IGVjMiA9IG5ldyBFQzJDbGllbnQoe30pO1xuICBsZXQgbmV4dFRva2VuO1xuICBkbyB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZWMyLnNlbmQobmV3IEdldElwYW1Qb29sQWxsb2NhdGlvbnNDb21tYW5kKHtcbiAgICAgIElwYW1Qb29sSWQ6IHBvb2xJZCwgLi4uKG5leHRUb2tlbiAmJiB7IE5leHRUb2tlbjogbmV4dFRva2VuIH0pXG4gICAgfSkpO1xuICAgIGZvciAoY29uc3QgYWxsb2Mgb2YgKHJlcy5JcGFtUG9vbEFsbG9jYXRpb25zIHx8IFtdKSkge1xuICAgICAgaWYgKGFsbG9jLlJlc291cmNlVHlwZSA9PT0gJ2lwYW0tcG9vbCcpIGNvbnRpbnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZWMyLnNlbmQobmV3IFJlbGVhc2VJcGFtUG9vbEFsbG9jYXRpb25Db21tYW5kKHtcbiAgICAgICAgICBJcGFtUG9vbElkOiBwb29sSWQsXG4gICAgICAgICAgQ2lkcjogYWxsb2MuQ2lkcixcbiAgICAgICAgICBJcGFtUG9vbEFsbG9jYXRpb25JZDogYWxsb2MuSXBhbVBvb2xBbGxvY2F0aW9uSWRcbiAgICAgICAgfSkpO1xuICAgICAgfSBjYXRjaCAoZSkgeyBjb25zb2xlLmxvZygnUmVsZWFzZSBmYWlsZWQgKG1heSBhbHJlYWR5IGJlIHJlbGVhc2VkKTonLCBlLm1lc3NhZ2UpOyB9XG4gICAgfVxuICAgIG5leHRUb2tlbiA9IHJlcy5OZXh0VG9rZW47XG4gIH0gd2hpbGUgKG5leHRUb2tlbik7XG4gIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkIH07XG59O2BcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIGFsbG9jYXRpb25DbGVhbnVwLm5vZGUuYWRkRGVwZW5kZW5jeShjaWRyQWxsb2NhdGlvbik7XG5cbiAgICAgICAgLy8gU2hhcmUgdGhlIHBvb2wgd2l0aCB0aGUgdGFyZ2V0IGFjY291bnQgc28gdGhhdCBWUENzIGNhbiBhbGxvY2F0ZVxuICAgICAgICBjb25zdCBzaGFyZSA9IG5ldyBSZXNvdXJjZVNoYXJlKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgYCR7YWNjb3VudH1JcGFtUmVzb3VyY2VTaGFyZSR7cmVnaW9uU3VmZml4fWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYCR7YWNjb3VudH1JcGFtUmVzb3VyY2VTaGFyZS4ke3JlZ2lvbn1gLFxuICAgICAgICAgICAgYWxsb3dFeHRlcm5hbFByaW5jaXBhbHM6IGZhbHNlLFxuICAgICAgICAgICAgcHJpbmNpcGFsczogW2FjY291bnRJZF0sXG4gICAgICAgICAgICByZXNvdXJjZUFybnM6IFtpcGFtUG9vbC5hdHRyQXJuXSxcbiAgICAgICAgICAgIHRhZ3M6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGtleTogXCJmamFsbDpjb3N0QWxsb2NhdGlvbjplbnZpcm9ubWVudFwiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBgbWFuYWdlbWVudGBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICAvLyBEZWxldGUgb3JkZXI6IHNoYXJlIOKGkiBjbGVhbnVwIChyZWxlYXNlcyBWUEMgYWxsb2NhdGlvbnMpIOKGkiBjaWRyQWxsb2NhdGlvbiDihpIgcG9vbFxuICAgICAgICBzaGFyZS5ub2RlLmFkZERlcGVuZGVuY3koYWxsb2NhdGlvbkNsZWFudXAucmVzb3VyY2UpO1xuXG4gICAgICAgIC8vIEV4cG9zZSB0aGUgcG9vbCBJRCBmb3IgY3Jvc3Mtc3RhY2sgdXNhZ2UgKGUuZy4gVlBDIGFsbG9jYXRpb25zKVxuICAgICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIGBJcGFtUG9vbElkJHthY2NvdW50SWR9JHtyZWdpb25TdWZmaXh9YCwge1xuICAgICAgICAgIGtleTogYElwYW1Qb29sSWQke2FjY291bnRJZH0ke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICAgIHZhbHVlOiBpcGFtUG9vbC5hdHRySXBhbVBvb2xJZCxcbiAgICAgICAgICBleHBvcnROYW1lOiBgSXBhbVBvb2xJZCR7YWNjb3VudElkfSR7cmVnaW9uU3VmZml4fWBcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCBgSXBhbVBvb2xBcm4ke2FjY291bnRJZH0ke3JlZ2lvblN1ZmZpeH1gLCB7XG4gICAgICAgICAga2V5OiBgSXBhbVBvb2xBcm4ke2FjY291bnRJZH0ke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICAgIHZhbHVlOiBpcGFtUG9vbC5hdHRyQXJuLFxuICAgICAgICAgIGV4cG9ydE5hbWU6IGBJcGFtUG9vbEFybiR7YWNjb3VudElkfSR7cmVnaW9uU3VmZml4fWBcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJcGFtUG9vbFN0YWNrIGV4dGVuZHMgU3RhY2sge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogSXBhbVBvb2xTdGFja1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIG5ldyBJcGFtUG9vbCh0aGlzLCBcIklwYW1Qb29sXCIsIHtcbiAgICAgIG9yZ0FjY291bnRzOiBwcm9wcy5vcmdBY2NvdW50cyxcbiAgICAgIHJlZ2lvbnM6IHByb3BzLnJlZ2lvbnNcbiAgICB9KTtcbiAgfVxufVxuIl19
256
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBhbVBvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWIvcmVzb3VyY2VzL2F3cy9uZXR3b3JraW5nL2lwYW1Qb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUE4RTtBQUM5RSwyQ0FBdUM7QUFDdkMsaURBRzZCO0FBQzdCLHVEQUFpRDtBQUNqRCxpREFBOEQ7QUFDOUQsOERBQTJEO0FBQzNELGdFQUE2RDtBQUM3RCw4REFBdUQ7QUFDdkQsc0VBQThEO0FBRTlELDJFQUEyRTtBQUMzRSxpRkFBaUY7QUFDakYsa0ZBQWtGO0FBQ2xGLCtFQUErRTtBQUMvRSx1REFBdUQ7QUFDdkQsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFFL0IsTUFBTSxTQUFTLEdBQUc7SUFDaEIsZUFBZSxFQUFFLHVCQUF1QjtJQUN4QywyQkFBMkIsRUFBRSxrQ0FBa0M7SUFDL0QsNEJBQTRCLEVBQUUsa0NBQWtDO0NBQ3hELENBQUM7QUF5QlgsTUFBYSxRQUFTLFNBQVEsc0JBQVM7SUFDckMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFvQjtRQUM1RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLDBEQUEwRDtRQUMxRCxNQUFNLHlCQUF5QixHQUM3QixLQUFLLENBQUMsU0FBUyxJQUFJLGdCQUFFLENBQUMsV0FBVyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFFakUsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM5QixJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckMsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFFRCxNQUFNLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDN0Qs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O29CQUM5QixVQUFVLEVBQUUsYUFBYSxTQUFTLEdBQUcsWUFBWSxFQUFFO2lCQUNwRCxDQUFDLENBQUM7Z0JBRUgsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxjQUFjLFNBQVMsR0FBRyxZQUFZLEVBQUUsRUFBRTtvQkFDNUQsR0FBRyxFQUFFLGNBQWMsU0FBUyxHQUFHLFlBQVksRUFBRTtvQkFDN0MsS0FBSyxFQUFFLFFBQVEsQ0FBQyxPQUFPO29CQUN2QixVQUFVLEVBQUUsY0FBYyxTQUFTLEdBQUcsWUFBWSxFQUFFO2lCQUNyRCxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsc0VBQXNFO1lBQ3RFLG9FQUFvRTtRQUN0RSxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBMVJELDRCQTBSQztBQUVELE1BQWEsYUFBYyxTQUFRLG1CQUFLO0lBQ3RDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBeUI7UUFDakUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQzdCLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztZQUM5QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87U0FDdkIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBVEQsc0NBU0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZm5PdXRwdXQsIER1cmF0aW9uLCBGbiwgdHlwZSBTdGFja1Byb3BzLCBTdGFjayB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7XG4gIENmbklQQU1Qb29sIGFzIElwYW1Qb29sQ2xhc3MsXG4gIENmbklQQU1Qb29sQ2lkclxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiO1xuaW1wb3J0IHsgUnVudGltZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQgeyBFZmZlY3QsIFBvbGljeVN0YXRlbWVudCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgeyBSZXNvdXJjZVNoYXJlIH0gZnJvbSBcIi4uL3V0aWxpdGllcy9yZXNvdXJjZVNoYXJlXCI7XG5pbXBvcnQgeyBDdXN0b21SZXNvdXJjZSB9IGZyb20gXCIuLi91dGlsaXRpZXMvY3VzdG9tUmVzb3VyY2VcIjtcbmltcG9ydCBnZXRBY2NvdW50SWQgZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2dldEFjY291bnRJZFwiO1xuaW1wb3J0IHsgRmphbGxMb2dnZXIgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvdmFsaWRhdGlvbkxvZ2dlclwiO1xuXG4vLyBJUEFNIGVuZm9yY2VzIGEgbG93IGNvbmN1cnJlbnQtbXV0YXRpb24gbGltaXQgKG5vdCBwdWJsaWNseSBkb2N1bWVudGVkKS5cbi8vIEFjY291bnQgcG9vbHMgYXJlIHNlcmlhbGlzZWQgV0lUSElOIGVhY2ggcmVnaW9uICh0aGV5IG11dGF0ZSB0aGUgc2FtZSByZWdpb25hbFxuLy8gcG9vbCBwYXJlbnQpLiBBY3Jvc3MgcmVnaW9ucywgYWNjb3VudCBwb29scyBydW4gaW4gcGFyYWxsZWwgYmVjYXVzZSB0aGV5IG11dGF0ZVxuLy8gRElGRkVSRU5UIHJlZ2lvbmFsIHBvb2wgcGFyZW50cyDigJQgdGhpcyBrZWVwcyBlZmZlY3RpdmUgY29uY3VycmVuY3kgYXQgMiAob25lXG4vLyBwZXIgcmVnaW9uKSwgd2VsbCB3aXRoaW4gb2JzZXJ2ZWQgQVdTIGxpbWl0cyAofjItMykuXG5jb25zdCBJUEFNX1BPT0xfQkFUQ0hfU0laRSA9IDE7XG5cbmNvbnN0IElQQU1fVEFHUyA9IHtcbiAgT1BFUkFUSU9OU19QT09MOiBcImZqYWxsOm9wZXJhdGlvbnM6cG9vbFwiLFxuICBDT1NUX0FMTE9DQVRJT05fRU5WSVJPTk1FTlQ6IFwiZmphbGw6Y29zdEFsbG9jYXRpb246ZW52aXJvbm1lbnRcIixcbiAgQ09TVF9BTExPQ0FUSU9OX0FDQ09VTlRfTkFNRTogXCJmamFsbDpjb3N0QWxsb2NhdGlvbjphY2NvdW50TmFtZVwiXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgaW50ZXJmYWNlIElwYW1Qb29sUHJvcHMgZXh0ZW5kcyBTdGFja1Byb3BzIHtcbiAgb3JnQWNjb3VudHM6IHN0cmluZ1tdO1xuICBpcGFtU2NvcGU/OiBzdHJpbmc7XG4gIHJlZ2lvbnM6IHN0cmluZ1tdO1xuICAvKipcbiAgICogVGhlIG5ldG1hc2sgbGVuZ3RoICgvQ0lEUikgZWFjaCBjaGlsZCBJUEFNIHBvb2wgc2hvdWxkIHJlY2VpdmUuXG4gICAqIENvbnRyb2xzIHRoZSBzaXplIG9mIENJRFIgYmxvY2tzIGF1dG9tYXRpY2FsbHkgYWxsb2NhdGVkIHRvIFZQQ3MgZnJvbSB0aGUgcG9vbC5cbiAgICogQWNjZXB0ZWQgcmFuZ2U6IC8xNiAoNjUsNTM2IElQcykg4oCTIC8yOCAoMTYgSVBzKS4gRGVmYXVsdHMgdG8gLzIwICg0LDA5NiBJUHMpLlxuICAgKi9cbiAgYWxsb2NhdGlvbkRlZmF1bHROZXRtYXNrTGVuZ3RoPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG5ldG1hc2sgbGVuZ3RoICgvQ0lEUikgcHJvdmlzaW9uZWQgaW50byBlYWNoIGNoaWxkIElQQU0gcG9vbCBvbiBjcmVhdGlvbi5cbiAgICogRGV0ZXJtaW5lcyB0aGUgdG90YWwgYWRkcmVzcyBzcGFjZSBhdmFpbGFibGUgZm9yIFZQQyBhbGxvY2F0aW9ucyBpbiB0aGF0IGFjY291bnQuXG4gICAqIEFjY2VwdGVkIHJhbmdlOiAvMTMgKDUyNCwyODggSVBzKSDigJMgLzE2ICg2NSw1MzYgSVBzKS4gRGVmYXVsdHMgdG8gLzE0LlxuICAgKi9cbiAgcHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RoPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgSXBhbVBvb2xTdGFja1Byb3BzIGV4dGVuZHMgU3RhY2tQcm9wcyB7XG4gIG9yZ0FjY291bnRzOiBzdHJpbmdbXTtcbiAgcmVnaW9uczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBjbGFzcyBJcGFtUG9vbCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBJcGFtUG9vbFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIC8vIEdldCB0aGUgZGVmYXVsdCBJUEFNIHNjb3BlIElEIGZyb20gcHJvcHMsIG9yIENGTiBpbXBvcnRcbiAgICBjb25zdCBJcGFtUHJpdmF0ZURlZmF1bHRTY29wZUlkID1cbiAgICAgIHByb3BzLmlwYW1TY29wZSB8fCBGbi5pbXBvcnRWYWx1ZShcIklwYW1Qcml2YXRlRGVmYXVsdFNjb3BlSWRcIik7XG5cbiAgICBjb25zdCByZWdpb25zID0gcHJvcHMucmVnaW9ucztcbiAgICBpZiAoIXJlZ2lvbnMgfHwgcmVnaW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkF0IGxlYXN0IG9uZSByZWdpb24gbXVzdCBiZSBzcGVjaWZpZWQgZm9yIElQQU0gcG9vbHNcIik7XG4gICAgfVxuXG4gICAgY29uc3Qgb3JnYW5pc2F0aW9uQWNjb3VudHMgPSBwcm9wcy5vcmdBY2NvdW50cy5tYXAoKGFjY291bnQpID0+XG4gICAgICBhY2NvdW50LnRvTG93ZXJDYXNlKClcbiAgICApO1xuXG4gICAgLy8gRGV0ZXJtaW5lIHRoZSBjaGlsZC1wb29sIENJRFIgc2l6ZSAoZGVmYXVsdHMgdG8gLzIwKVxuICAgIGNvbnN0IGRlZmF1bHROZXRtYXNrTGVuZ3RoID0gcHJvcHMuYWxsb2NhdGlvbkRlZmF1bHROZXRtYXNrTGVuZ3RoID8/IDIwO1xuICAgIGNvbnN0IHByb3Zpc2lvbmVkTmV0bWFza0xlbmd0aCA9IHByb3BzLnByb3Zpc2lvbmVkTmV0bWFza0xlbmd0aCA/PyAxNDtcblxuICAgIC8vIEJhc2ljIHZhbGlkYXRpb24g4oCTIC8xNiB0byAvMjggaW5jbHVzaXZlIGFyZSBjb25zaWRlcmVkIHNhZmUgZm9yIFZQQyBhbGxvY2F0aW9uc1xuICAgIGlmIChkZWZhdWx0TmV0bWFza0xlbmd0aCA8IDE2IHx8IGRlZmF1bHROZXRtYXNrTGVuZ3RoID4gMjgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYGFsbG9jYXRpb25EZWZhdWx0TmV0bWFza0xlbmd0aCBtdXN0IGJlIGJldHdlZW4gMTYgYW5kIDI4IChpbmNsdXNpdmUpLiBSZWNlaXZlZDogJHtkZWZhdWx0TmV0bWFza0xlbmd0aH1gXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIHByb3Zpc2lvbmVkIGJsb2NrIHNpemUgKC8xMyB0byAvMTYpXG4gICAgaWYgKHByb3Zpc2lvbmVkTmV0bWFza0xlbmd0aCA8IDEzIHx8IHByb3Zpc2lvbmVkTmV0bWFza0xlbmd0aCA+IDE2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBwcm92aXNpb25lZE5ldG1hc2tMZW5ndGggbXVzdCBiZSBiZXR3ZWVuIDEzIGFuZCAxNiAoaW5jbHVzaXZlKS4gUmVjZWl2ZWQ6ICR7cHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RofWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gV2FybiBpZiB1c2VyIHJlcXVlc3RzIFZQQyBhbGxvY2F0aW9ucyBsYXJnZXIgdGhhbiB0aGUgcHJvdmlzaW9uZWQgcG9vbFxuICAgIGlmIChkZWZhdWx0TmV0bWFza0xlbmd0aCA8IHByb3Zpc2lvbmVkTmV0bWFza0xlbmd0aCkge1xuICAgICAgRmphbGxMb2dnZXIud2FybihcbiAgICAgICAgYCdhbGxvY2F0aW9uRGVmYXVsdE5ldG1hc2tMZW5ndGgnICgvJHtkZWZhdWx0TmV0bWFza0xlbmd0aH0pIGlzIGxhcmdlciB0aGFuICdwcm92aXNpb25lZE5ldG1hc2tMZW5ndGgnICgvJHtwcm92aXNpb25lZE5ldG1hc2tMZW5ndGh9KS4gYCArXG4gICAgICAgICAgYFZQQyBhbGxvY2F0aW9uIG1heSBmYWlsIGlmIHRoZSBwb29sIGNhbm5vdCBzYXRpc2Z5IHRoZSByZXF1ZXN0LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gVG9wIExldmVsIFBvb2xcbiAgICBjb25zdCByb290UG9vbCA9IG5ldyBJcGFtUG9vbENsYXNzKHRoaXMsIFwiVG9wTGV2ZWxJcGFtUG9vbFwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogYFJvb3QgSVBBTSBwb29sIChHbG9iYWwpYCxcbiAgICAgIGFkZHJlc3NGYW1pbHk6IFwiaXB2NFwiLFxuICAgICAgaXBhbVNjb3BlSWQ6IElwYW1Qcml2YXRlRGVmYXVsdFNjb3BlSWQsXG4gICAgICBwcm92aXNpb25lZENpZHJzOiBbXG4gICAgICAgIHsgY2lkcjogXCIxMC4wLjAuMC84XCIgfSxcbiAgICAgICAgeyBjaWRyOiBcIjE3Mi4xNi4wLjAvMTJcIiB9LFxuICAgICAgICB7IGNpZHI6IFwiMTkyLjE2OC4wLjAvMTZcIiB9XG4gICAgICBdLFxuICAgICAgYXV0b0ltcG9ydDogdHJ1ZSxcbiAgICAgIHRhZ3M6IFtcbiAgICAgICAge1xuICAgICAgICAgIGtleTogSVBBTV9UQUdTLk9QRVJBVElPTlNfUE9PTCxcbiAgICAgICAgICB2YWx1ZTogXCJ0b3AtbGV2ZWxcIlxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAga2V5OiBJUEFNX1RBR1MuQ09TVF9BTExPQ0FUSU9OX0VOVklST05NRU5ULFxuICAgICAgICAgIHZhbHVlOiBcIm1hbmFnZW1lbnRcIlxuICAgICAgICB9XG4gICAgICBdXG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgcmVnaW9uYWwgcG9vbHMgYXMgY2hpbGRyZW4gb2YgdGhlIHJvb3QgcG9vbC5cbiAgICAvLyBTZXJpYWxpc2VkIHRvIGF2b2lkIEVDMiBJUEFNIFwidG9vIG1hbnkgY29uY3VycmVudCBtdXRhdGlvbnNcIiBlcnJvcnMg4oCUXG4gICAgLy8gZWFjaCByZWdpb25hbCBwb29sICsgQ0lEUiBtdXRhdGVzIHRoZSBwYXJlbnQgcm9vdCBwb29sIHJlc291cmNlLCBhbmRcbiAgICAvLyBJUEFNIHJlamVjdHMgcGFyYWxsZWwgbXV0YXRpb25zIG9uIHRoZSBzYW1lIHBhcmVudC5cbiAgICBsZXQgcHJldmlvdXNSZWdpb25hbENpZHI6IENmbklQQU1Qb29sQ2lkciB8IHVuZGVmaW5lZDtcblxuICAgIGZvciAoY29uc3QgcmVnaW9uIG9mIHJlZ2lvbnMpIHtcbiAgICAgIGNvbnN0IHJlZ2lvblN1ZmZpeCA9IHJlZ2lvbi5yZXBsYWNlKC8tL2csIFwiXCIpO1xuXG4gICAgICAvLyBDcmVhdGUgYSByZWdpb25hbCBwb29sIGZvciB0aGlzIHNwZWNpZmljIHJlZ2lvblxuICAgICAgY29uc3QgcmVnaW9uYWxQb29sID0gbmV3IElwYW1Qb29sQ2xhc3MoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIGBSZWdpb25hbFBvb2wke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBSZWdpb25hbCBJUEFNIHBvb2wgLSAke3JlZ2lvbn1gLFxuICAgICAgICAgIGFkZHJlc3NGYW1pbHk6IFwiaXB2NFwiLFxuICAgICAgICAgIGlwYW1TY29wZUlkOiBJcGFtUHJpdmF0ZURlZmF1bHRTY29wZUlkLFxuICAgICAgICAgIGxvY2FsZTogcmVnaW9uLFxuICAgICAgICAgIHNvdXJjZUlwYW1Qb29sSWQ6IHJvb3RQb29sLmF0dHJJcGFtUG9vbElkLFxuICAgICAgICAgIGF1dG9JbXBvcnQ6IHRydWUsXG4gICAgICAgICAgdGFnczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBrZXk6IElQQU1fVEFHUy5PUEVSQVRJT05TX1BPT0wsXG4gICAgICAgICAgICAgIHZhbHVlOiBgcmVnaW9uYWwtJHtyZWdpb259YFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAga2V5OiBJUEFNX1RBR1MuQ09TVF9BTExPQ0FUSU9OX0VOVklST05NRU5ULFxuICAgICAgICAgICAgICB2YWx1ZTogXCJtYW5hZ2VtZW50XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIC8vIENoYWluOiBlYWNoIHJlZ2lvbmFsIHBvb2wgd2FpdHMgZm9yIHRoZSBwcmV2aW91cyByZWdpb24ncyBDSURSIHRvIGNvbXBsZXRlLlxuICAgICAgLy8gVGhpcyBzZXJpYWxpc2VzIHJlZ2lvbmFsIHBvb2wgY3JlYXRpb24sIHByZXZlbnRpbmcgY29uY3VycmVudCBtdXRhdGlvbnNcbiAgICAgIC8vIG9uIHRoZSByb290IHBvb2wgcmVzb3VyY2UuXG4gICAgICBpZiAocHJldmlvdXNSZWdpb25hbENpZHIpIHtcbiAgICAgICAgcmVnaW9uYWxQb29sLmFkZERlcGVuZGVuY3kocHJldmlvdXNSZWdpb25hbENpZHIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWdpb25hbENpZHJBbGxvY2F0aW9uID0gbmV3IENmbklQQU1Qb29sQ2lkcihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgYFJlZ2lvbmFsUG9vbENpZHIke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICB7XG4gICAgICAgICAgaXBhbVBvb2xJZDogcmVnaW9uYWxQb29sLmF0dHJJcGFtUG9vbElkLFxuICAgICAgICAgIG5ldG1hc2tMZW5ndGg6IDEwIC8vIEVhY2ggcmVnaW9uIGdldHMgYSAvMTAgKDQsMTk0LDMwNCBJUHMpXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIHByZXZpb3VzUmVnaW9uYWxDaWRyID0gcmVnaW9uYWxDaWRyQWxsb2NhdGlvbjtcblxuICAgICAgLy8gU2VyaWFsaXNlZCBhY2NvdW50IHBvb2wgY3JlYXRpb24gd2l0aGluIGVhY2ggcmVnaW9uLlxuICAgICAgLy8gQWNjb3VudCBwb29scyB3aXRoaW4gYSByZWdpb24gYWxsIG11dGF0ZSB0aGUgc2FtZSByZWdpb25hbCBwb29sIHBhcmVudCxcbiAgICAgIC8vIHNvIHRoZXkgbXVzdCBiZSBzZXJpYWxpc2VkLiBBY2NvdW50IHBvb2xzIGluIERJRkZFUkVOVCByZWdpb25zIG11dGF0ZVxuICAgICAgLy8gZGlmZmVyZW50IHJlZ2lvbmFsIHBvb2wgcGFyZW50cywgc28gdGhleSBjYW4gc2FmZWx5IHJ1biBpbiBwYXJhbGxlbC5cbiAgICAgIC8vXG4gICAgICAvLyBVc2VzIENmblJlc291cmNlLmFkZERlcGVuZGVuY3koKSAobm90IG5vZGUuYWRkRGVwZW5kZW5jeSkgZm9yXG4gICAgICAvLyBndWFyYW50ZWVkIENsb3VkRm9ybWF0aW9uIERlcGVuZHNPbiBnZW5lcmF0aW9uIGJldHdlZW4gTDEgY29uc3RydWN0cy5cbiAgICAgIGxldCBwcmV2aW91c1dhdmVBbmNob3JDaWRyOiBDZm5JUEFNUG9vbENpZHIgfCB1bmRlZmluZWQ7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JnYW5pc2F0aW9uQWNjb3VudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgYWNjb3VudCA9IG9yZ2FuaXNhdGlvbkFjY291bnRzW2ldO1xuICAgICAgICBjb25zdCBhY2NvdW50SWQgPSBnZXRBY2NvdW50SWQoYWNjb3VudCk7XG5cbiAgICAgICAgY29uc3QgaXBhbVBvb2wgPSBuZXcgSXBhbVBvb2xDbGFzcyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGAke2FjY291bnR9SXBhbVBvb2wke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHthY2NvdW50fSAtIElQQU0gcG9vbCAtICR7cmVnaW9ufWAsXG4gICAgICAgICAgICBhZGRyZXNzRmFtaWx5OiBcImlwdjRcIixcbiAgICAgICAgICAgIGlwYW1TY29wZUlkOiBJcGFtUHJpdmF0ZURlZmF1bHRTY29wZUlkLFxuICAgICAgICAgICAgbG9jYWxlOiByZWdpb24sXG4gICAgICAgICAgICBzb3VyY2VJcGFtUG9vbElkOiByZWdpb25hbFBvb2wuYXR0cklwYW1Qb29sSWQsXG4gICAgICAgICAgICBhbGxvY2F0aW9uRGVmYXVsdE5ldG1hc2tMZW5ndGg6IGRlZmF1bHROZXRtYXNrTGVuZ3RoLFxuICAgICAgICAgICAgYWxsb2NhdGlvblJlc291cmNlVGFnczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2V5OiBJUEFNX1RBR1MuT1BFUkFUSU9OU19QT09MLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBgJHthY2NvdW50SWR9LSR7cmVnaW9ufWBcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGF1dG9JbXBvcnQ6IHRydWUsXG4gICAgICAgICAgICB0YWdzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBrZXk6IElQQU1fVEFHUy5PUEVSQVRJT05TX1BPT0wsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGAke2FjY291bnRJZH0tJHtyZWdpb259YFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2V5OiBJUEFNX1RBR1MuQ09TVF9BTExPQ0FUSU9OX0FDQ09VTlRfTkFNRSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogYWNjb3VudFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIEVuc3VyZSB0aGUgYWNjb3VudCBwb29sIGlzIGNyZWF0ZWQgYWZ0ZXIgdGhlIHJlZ2lvbmFsIENJRFIgYWxsb2NhdGlvblxuICAgICAgICBpcGFtUG9vbC5hZGREZXBlbmRlbmN5KHJlZ2lvbmFsQ2lkckFsbG9jYXRpb24pO1xuXG4gICAgICAgIC8vIFdhdmUgYm91bmRhcnk6IHBvb2xzIGluIHdhdmUgTisxIGRlcGVuZCBvbiB0aGUgbGFzdCBDSURSIGZyb20gd2F2ZSBOXG4gICAgICAgIGlmIChwcmV2aW91c1dhdmVBbmNob3JDaWRyKSB7XG4gICAgICAgICAgaXBhbVBvb2wuYWRkRGVwZW5kZW5jeShwcmV2aW91c1dhdmVBbmNob3JDaWRyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNpZHJBbGxvY2F0aW9uID0gbmV3IENmbklQQU1Qb29sQ2lkcihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGAke2FjY291bnR9UG9vbENpZHIke3Byb3Zpc2lvbmVkTmV0bWFza0xlbmd0aH0ke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlwYW1Qb29sSWQ6IGlwYW1Qb29sLmF0dHJJcGFtUG9vbElkLFxuICAgICAgICAgICAgbmV0bWFza0xlbmd0aDogcHJvdmlzaW9uZWROZXRtYXNrTGVuZ3RoXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFRoZSBsYXN0IHBvb2wgaW4gZWFjaCB3YXZlIGFuY2hvcnMgdGhlIG5leHQgd2F2ZSdzIGRlcGVuZGVuY3lcbiAgICAgICAgY29uc3QgaXNMYXN0SW5XYXZlID1cbiAgICAgICAgICAoaSArIDEpICUgSVBBTV9QT09MX0JBVENIX1NJWkUgPT09IDAgfHxcbiAgICAgICAgICBpID09PSBvcmdhbmlzYXRpb25BY2NvdW50cy5sZW5ndGggLSAxO1xuXG4gICAgICAgIGlmIChpc0xhc3RJbldhdmUpIHtcbiAgICAgICAgICBwcmV2aW91c1dhdmVBbmNob3JDaWRyID0gY2lkckFsbG9jYXRpb247XG4gICAgICAgIH1cblxuICAgICAgICAvLyBPbiBzdGFjayBkZWxldGlvbiwgVlBDIGFsbG9jYXRpb25zIChub3QgbWFuYWdlZCBieSBDbG91ZEZvcm1hdGlvbilcbiAgICAgICAgLy8gYmxvY2sgQ0lEUiBkZXByb3Zpc2lvbmluZy4gVGhpcyBjdXN0b20gcmVzb3VyY2UgcmVsZWFzZXMgdGhlbSBmaXJzdC5cbiAgICAgICAgY29uc3QgYWxsb2NhdGlvbkNsZWFudXAgPSBuZXcgQ3VzdG9tUmVzb3VyY2UoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBgJHthY2NvdW50fUlwYW1DbGVhbnVwJHtyZWdpb25TdWZmaXh9YCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICAgIGxhbWJkYURlc2NyaXB0aW9uOiBgJHthY2NvdW50fSBJUEFNIHBvb2wgYWxsb2NhdGlvbiBjbGVhbnVwIC0gJHtyZWdpb259YCxcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgSXBhbVBvb2xJZDogaXBhbVBvb2wuYXR0cklwYW1Qb29sSWQsXG4gICAgICAgICAgICAgIFBvb2xSZWdpb246IHJlZ2lvblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlubGluZVBvbGljeTogW1xuICAgICAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICAgICBcImVjMjpHZXRJcGFtUG9vbEFsbG9jYXRpb25zXCIsXG4gICAgICAgICAgICAgICAgICBcImVjMjpSZWxlYXNlSXBhbVBvb2xBbGxvY2F0aW9uXCJcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIHJlc291cmNlczogW1wiKlwiXVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGlubGluZUNvZGU6IGBcbmNvbnN0IHsgRUMyQ2xpZW50LCBHZXRJcGFtUG9vbEFsbG9jYXRpb25zQ29tbWFuZCwgUmVsZWFzZUlwYW1Qb29sQWxsb2NhdGlvbkNvbW1hbmQgfSA9IHJlcXVpcmUoJ0Bhd3Mtc2RrL2NsaWVudC1lYzInKTtcblxuZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKGV2ZW50KSA9PiB7XG4gIGNvbnN0IHBoeXNpY2FsUmVzb3VyY2VJZCA9IGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCB8fCBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCB8fCAnaXBhbS1wb29sLWNsZWFudXAnO1xuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgIT09ICdEZWxldGUnKSB7XG4gICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiBwaHlzaWNhbFJlc291cmNlSWQgfTtcbiAgfVxuICBjb25zdCBwb29sSWQgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuSXBhbVBvb2xJZDtcbiAgY29uc3QgcG9vbFJlZ2lvbiA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Qb29sUmVnaW9uO1xuICBjb25zdCBlYzIgPSBuZXcgRUMyQ2xpZW50KHsgcmVnaW9uOiBwb29sUmVnaW9uIH0pO1xuICBsZXQgbmV4dFRva2VuO1xuICBkbyB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZWMyLnNlbmQobmV3IEdldElwYW1Qb29sQWxsb2NhdGlvbnNDb21tYW5kKHtcbiAgICAgIElwYW1Qb29sSWQ6IHBvb2xJZCwgLi4uKG5leHRUb2tlbiAmJiB7IE5leHRUb2tlbjogbmV4dFRva2VuIH0pXG4gICAgfSkpO1xuICAgIGZvciAoY29uc3QgYWxsb2Mgb2YgKHJlcy5JcGFtUG9vbEFsbG9jYXRpb25zIHx8IFtdKSkge1xuICAgICAgaWYgKGFsbG9jLlJlc291cmNlVHlwZSA9PT0gJ2lwYW0tcG9vbCcpIGNvbnRpbnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZWMyLnNlbmQobmV3IFJlbGVhc2VJcGFtUG9vbEFsbG9jYXRpb25Db21tYW5kKHtcbiAgICAgICAgICBJcGFtUG9vbElkOiBwb29sSWQsXG4gICAgICAgICAgQ2lkcjogYWxsb2MuQ2lkcixcbiAgICAgICAgICBJcGFtUG9vbEFsbG9jYXRpb25JZDogYWxsb2MuSXBhbVBvb2xBbGxvY2F0aW9uSWRcbiAgICAgICAgfSkpO1xuICAgICAgfSBjYXRjaCAoZSkgeyBjb25zb2xlLmxvZygnUmVsZWFzZSBmYWlsZWQgKG1heSBhbHJlYWR5IGJlIHJlbGVhc2VkKTonLCBlLm1lc3NhZ2UpOyB9XG4gICAgfVxuICAgIG5leHRUb2tlbiA9IHJlcy5OZXh0VG9rZW47XG4gIH0gd2hpbGUgKG5leHRUb2tlbik7XG4gIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxSZXNvdXJjZUlkIH07XG59O2BcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIGFsbG9jYXRpb25DbGVhbnVwLm5vZGUuYWRkRGVwZW5kZW5jeShjaWRyQWxsb2NhdGlvbik7XG5cbiAgICAgICAgLy8gU2hhcmUgdGhlIHBvb2wgd2l0aCB0aGUgdGFyZ2V0IGFjY291bnQgc28gdGhhdCBWUENzIGNhbiBhbGxvY2F0ZVxuICAgICAgICBjb25zdCBzaGFyZSA9IG5ldyBSZXNvdXJjZVNoYXJlKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgYCR7YWNjb3VudH1JcGFtUmVzb3VyY2VTaGFyZSR7cmVnaW9uU3VmZml4fWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYCR7YWNjb3VudH1JcGFtUmVzb3VyY2VTaGFyZS4ke3JlZ2lvbn1gLFxuICAgICAgICAgICAgYWxsb3dFeHRlcm5hbFByaW5jaXBhbHM6IGZhbHNlLFxuICAgICAgICAgICAgcHJpbmNpcGFsczogW2FjY291bnRJZF0sXG4gICAgICAgICAgICByZXNvdXJjZUFybnM6IFtpcGFtUG9vbC5hdHRyQXJuXSxcbiAgICAgICAgICAgIHRhZ3M6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGtleTogSVBBTV9UQUdTLkNPU1RfQUxMT0NBVElPTl9FTlZJUk9OTUVOVCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogXCJtYW5hZ2VtZW50XCJcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICAvLyBEZWxldGUgb3JkZXI6IHNoYXJlIOKGkiBjbGVhbnVwIChyZWxlYXNlcyBWUEMgYWxsb2NhdGlvbnMpIOKGkiBjaWRyQWxsb2NhdGlvbiDihpIgcG9vbFxuICAgICAgICBzaGFyZS5ub2RlLmFkZERlcGVuZGVuY3koYWxsb2NhdGlvbkNsZWFudXAucmVzb3VyY2UpO1xuXG4gICAgICAgIC8vIEV4cG9zZSB0aGUgcG9vbCBJRCBmb3IgY3Jvc3Mtc3RhY2sgdXNhZ2UgKGUuZy4gVlBDIGFsbG9jYXRpb25zKVxuICAgICAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIGBJcGFtUG9vbElkJHthY2NvdW50SWR9JHtyZWdpb25TdWZmaXh9YCwge1xuICAgICAgICAgIGtleTogYElwYW1Qb29sSWQke2FjY291bnRJZH0ke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICAgIHZhbHVlOiBpcGFtUG9vbC5hdHRySXBhbVBvb2xJZCxcbiAgICAgICAgICBleHBvcnROYW1lOiBgSXBhbVBvb2xJZCR7YWNjb3VudElkfSR7cmVnaW9uU3VmZml4fWBcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCBgSXBhbVBvb2xBcm4ke2FjY291bnRJZH0ke3JlZ2lvblN1ZmZpeH1gLCB7XG4gICAgICAgICAga2V5OiBgSXBhbVBvb2xBcm4ke2FjY291bnRJZH0ke3JlZ2lvblN1ZmZpeH1gLFxuICAgICAgICAgIHZhbHVlOiBpcGFtUG9vbC5hdHRyQXJuLFxuICAgICAgICAgIGV4cG9ydE5hbWU6IGBJcGFtUG9vbEFybiR7YWNjb3VudElkfSR7cmVnaW9uU3VmZml4fWBcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIE5vIGNyb3NzLXJlZ2lvbiBjaGFpbmluZyBuZWVkZWQ6IGFjY291bnQgcG9vbHMgaW4gZGlmZmVyZW50IHJlZ2lvbnNcbiAgICAgIC8vIG11dGF0ZSBkaWZmZXJlbnQgcGFyZW50IHJlc291cmNlcyBhbmQgY2FuIHNhZmVseSBydW4gaW4gcGFyYWxsZWwuXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJcGFtUG9vbFN0YWNrIGV4dGVuZHMgU3RhY2sge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogSXBhbVBvb2xTdGFja1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIG5ldyBJcGFtUG9vbCh0aGlzLCBcIklwYW1Qb29sXCIsIHtcbiAgICAgIG9yZ0FjY291bnRzOiBwcm9wcy5vcmdBY2NvdW50cyxcbiAgICAgIHJlZ2lvbnM6IHByb3BzLnJlZ2lvbnNcbiAgICB9KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,5 @@
1
+ import * as ec2 from "aws-cdk-lib/aws-ec2";
2
+ import { type Construct } from "constructs";
3
+ export declare class SecurityGroup extends ec2.SecurityGroup {
4
+ constructor(scope: Construct, id: string, props: ec2.SecurityGroupProps);
5
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SecurityGroup = void 0;
4
+ const ec2 = require("aws-cdk-lib/aws-ec2");
5
+ class SecurityGroup extends ec2.SecurityGroup {
6
+ constructor(scope, id, props) {
7
+ super(scope, id, {
8
+ ...props,
9
+ description: props.description || `${id} Security Group`
10
+ });
11
+ }
12
+ }
13
+ exports.SecurityGroup = SecurityGroup;
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHlHcm91cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9yZXNvdXJjZXMvYXdzL25ldHdvcmtpbmcvc2VjdXJpdHlHcm91cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBMkM7QUFHM0MsTUFBYSxhQUFjLFNBQVEsR0FBRyxDQUFDLGFBQWE7SUFDbEQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE2QjtRQUNyRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLEdBQUcsS0FBSztZQUNSLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVyxJQUFJLEdBQUcsRUFBRSxpQkFBaUI7U0FDekQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBUEQsc0NBT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBlYzIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7IHR5cGUgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcblxuZXhwb3J0IGNsYXNzIFNlY3VyaXR5R3JvdXAgZXh0ZW5kcyBlYzIuU2VjdXJpdHlHcm91cCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBlYzIuU2VjdXJpdHlHcm91cFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wcy5kZXNjcmlwdGlvbiB8fCBgJHtpZH0gU2VjdXJpdHkgR3JvdXBgXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==