@cloudsnorkel/cdk-github-runners 0.11.5 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/.gitattributes +1 -2
  2. package/.jsii +442 -215
  3. package/API.md +185 -27
  4. package/README.md +10 -20
  5. package/assets/delete-failed-runner.lambda/index.js +6 -3714
  6. package/assets/idle-runner-repear.lambda/index.js +6 -3714
  7. package/assets/image-builders/aws-image-builder/delete-ami.lambda/index.js +3 -22
  8. package/assets/image-builders/aws-image-builder/versioner.lambda/index.js +2 -2
  9. package/assets/{providers → image-builders}/build-image.lambda/index.js +2 -14
  10. package/assets/setup.lambda/index.js +4 -3712
  11. package/assets/status.lambda/index.js +6 -3714
  12. package/assets/token-retriever.lambda/index.js +6 -3714
  13. package/assets/webhook-handler.lambda/index.js +15 -3723
  14. package/lib/access.js +1 -1
  15. package/lib/image-builders/api.d.ts +2 -2
  16. package/lib/image-builders/api.js +6 -6
  17. package/lib/image-builders/aws-image-builder/ami.d.ts +1 -0
  18. package/lib/image-builders/aws-image-builder/ami.js +9 -9
  19. package/lib/image-builders/aws-image-builder/builder.d.ts +1 -2
  20. package/lib/image-builders/aws-image-builder/builder.js +128 -74
  21. package/lib/image-builders/aws-image-builder/common.d.ts +1 -1
  22. package/lib/image-builders/aws-image-builder/common.js +2 -2
  23. package/lib/image-builders/aws-image-builder/container.d.ts +2 -1
  24. package/lib/image-builders/aws-image-builder/container.js +14 -14
  25. package/lib/image-builders/aws-image-builder/delete-ami.lambda.d.ts +1 -8
  26. package/lib/image-builders/aws-image-builder/delete-ami.lambda.js +5 -27
  27. package/lib/image-builders/aws-image-builder/deprecated/ami.js +1 -1
  28. package/lib/image-builders/aws-image-builder/deprecated/container.js +4 -3
  29. package/lib/image-builders/aws-image-builder/deprecated/linux-components.js +1 -1
  30. package/lib/image-builders/aws-image-builder/deprecated/windows-components.js +1 -1
  31. package/lib/{providers → image-builders}/build-image-function.d.ts +1 -1
  32. package/lib/image-builders/build-image-function.js +23 -0
  33. package/lib/image-builders/build-image.lambda.js +80 -0
  34. package/lib/image-builders/codebuild-deprecated.js +4 -3
  35. package/lib/image-builders/codebuild.js +4 -7
  36. package/lib/image-builders/common.d.ts +18 -9
  37. package/lib/image-builders/common.js +1 -11
  38. package/lib/image-builders/components.d.ts +2 -2
  39. package/lib/image-builders/components.js +2 -2
  40. package/lib/image-builders/static.js +1 -1
  41. package/lib/providers/codebuild.d.ts +9 -3
  42. package/lib/providers/codebuild.js +10 -4
  43. package/lib/providers/common.js +3 -3
  44. package/lib/providers/ec2.d.ts +9 -3
  45. package/lib/providers/ec2.js +10 -4
  46. package/lib/providers/ecs.d.ts +9 -3
  47. package/lib/providers/ecs.js +9 -3
  48. package/lib/providers/fargate.d.ts +9 -3
  49. package/lib/providers/fargate.js +10 -4
  50. package/lib/providers/lambda.d.ts +9 -3
  51. package/lib/providers/lambda.js +10 -4
  52. package/lib/runner.d.ts +8 -0
  53. package/lib/runner.js +4 -3
  54. package/lib/secrets.js +1 -1
  55. package/lib/webhook-handler.lambda.js +11 -10
  56. package/lib/webhook.d.ts +4 -0
  57. package/lib/webhook.js +2 -1
  58. package/package.json +22 -26
  59. package/assets/image-builders/aws-image-builder/reaper.lambda/index.js +0 -165
  60. package/lib/image-builders/aws-image-builder/reaper-function.d.ts +0 -13
  61. package/lib/image-builders/aws-image-builder/reaper-function.js +0 -23
  62. package/lib/image-builders/aws-image-builder/reaper.lambda.d.ts +0 -9
  63. package/lib/image-builders/aws-image-builder/reaper.lambda.js +0 -151
  64. package/lib/providers/build-image-function.js +0 -23
  65. package/lib/providers/build-image.lambda.js +0 -92
  66. /package/lib/{providers → image-builders}/build-image.lambda.d.ts +0 -0
package/package.json CHANGED
@@ -17,14 +17,12 @@
17
17
  "bundle:image-builders/aws-image-builder/delete-ami.lambda:watch": "npx projen bundle:image-builders/aws-image-builder/delete-ami.lambda:watch",
18
18
  "bundle:image-builders/aws-image-builder/filter-failed-builds.lambda": "npx projen bundle:image-builders/aws-image-builder/filter-failed-builds.lambda",
19
19
  "bundle:image-builders/aws-image-builder/filter-failed-builds.lambda:watch": "npx projen bundle:image-builders/aws-image-builder/filter-failed-builds.lambda:watch",
20
- "bundle:image-builders/aws-image-builder/reaper.lambda": "npx projen bundle:image-builders/aws-image-builder/reaper.lambda",
21
- "bundle:image-builders/aws-image-builder/reaper.lambda:watch": "npx projen bundle:image-builders/aws-image-builder/reaper.lambda:watch",
22
20
  "bundle:image-builders/aws-image-builder/versioner.lambda": "npx projen bundle:image-builders/aws-image-builder/versioner.lambda",
23
21
  "bundle:image-builders/aws-image-builder/versioner.lambda:watch": "npx projen bundle:image-builders/aws-image-builder/versioner.lambda:watch",
22
+ "bundle:image-builders/build-image.lambda": "npx projen bundle:image-builders/build-image.lambda",
23
+ "bundle:image-builders/build-image.lambda:watch": "npx projen bundle:image-builders/build-image.lambda:watch",
24
24
  "bundle:providers/ami-root-device.lambda": "npx projen bundle:providers/ami-root-device.lambda",
25
25
  "bundle:providers/ami-root-device.lambda:watch": "npx projen bundle:providers/ami-root-device.lambda:watch",
26
- "bundle:providers/build-image.lambda": "npx projen bundle:providers/build-image.lambda",
27
- "bundle:providers/build-image.lambda:watch": "npx projen bundle:providers/build-image.lambda:watch",
28
26
  "bundle:providers/update-lambda.lambda": "npx projen bundle:providers/update-lambda.lambda",
29
27
  "bundle:providers/update-lambda.lambda:watch": "npx projen bundle:providers/update-lambda.lambda:watch",
30
28
  "bundle:setup.lambda": "npx projen bundle:setup.lambda",
@@ -72,47 +70,45 @@
72
70
  "organization": false
73
71
  },
74
72
  "devDependencies": {
75
- "@aws-sdk/client-cloudformation": "^3.438.0",
76
- "@aws-sdk/client-codebuild": "^3.438.0",
77
- "@aws-sdk/client-ec2": "^3.438.0",
78
- "@aws-sdk/client-ecr": "^3.438.0",
79
- "@aws-sdk/client-imagebuilder": "^3.438.0",
80
- "@aws-sdk/client-lambda": "^3.438.0",
81
- "@aws-sdk/client-secrets-manager": "^3.438.0",
82
- "@aws-sdk/client-sfn": "^3.438.0",
83
- "@aws-sdk/client-sns": "^3.438.0",
84
- "@aws-sdk/client-ssm": "^3.438.0",
73
+ "@aws-sdk/client-cloudformation": "^3.454.0",
74
+ "@aws-sdk/client-codebuild": "^3.454.0",
75
+ "@aws-sdk/client-ec2": "^3.456.0",
76
+ "@aws-sdk/client-ecr": "^3.454.0",
77
+ "@aws-sdk/client-imagebuilder": "^3.454.0",
78
+ "@aws-sdk/client-lambda": "^3.454.0",
79
+ "@aws-sdk/client-secrets-manager": "^3.454.0",
80
+ "@aws-sdk/client-sfn": "^3.454.0",
81
+ "@aws-sdk/client-sns": "^3.454.0",
82
+ "@aws-sdk/client-ssm": "^3.454.0",
85
83
  "@octokit/auth-app": "^4.0.13",
86
84
  "@octokit/core": "^4.2.4",
87
85
  "@octokit/request-error": "^3.0.3",
88
86
  "@octokit/rest": "^19.0.13",
89
87
  "@sveltejs/vite-plugin-svelte": "^1.0.1",
90
88
  "@tsconfig/svelte": "^3.0.0",
91
- "@types/aws-lambda": "^8.10.125",
89
+ "@types/aws-lambda": "^8.10.129",
92
90
  "@types/jest": "^27",
93
- "@types/node": "^16",
94
- "@types/semver": "^7.5.4",
91
+ "@types/node": "^18",
92
+ "@types/semver": "^7.5.6",
95
93
  "@typescript-eslint/eslint-plugin": "^6",
96
94
  "@typescript-eslint/parser": "^6",
97
95
  "aws-cdk": "^2",
98
- "aws-cdk-lib": "2.77.0",
96
+ "aws-cdk-lib": "2.110.0",
99
97
  "bootstrap": "^5.2.0",
100
98
  "constructs": "10.0.5",
101
- "esbuild": "^0.19.5",
99
+ "esbuild": "^0.19.8",
102
100
  "eslint": "^8",
103
- "eslint-import-resolver-node": "^0.3.9",
104
101
  "eslint-import-resolver-typescript": "^2.7.1",
105
102
  "eslint-plugin-import": "^2.29.0",
106
103
  "eslint-plugin-svelte": "^2.29.0",
107
104
  "jest": "^27",
108
105
  "jest-junit": "^15",
109
106
  "jsii": "5.0.x",
110
- "jsii-diff": "^1.91.0",
107
+ "jsii-diff": "^1.92.0",
111
108
  "jsii-docgen": "^6.3.27",
112
- "jsii-pacmak": "^1.91.0",
109
+ "jsii-pacmak": "^1.92.0",
113
110
  "jsii-rosetta": "5.0.x",
114
- "npm-check-updates": "^16",
115
- "projen": "^0.76.13",
111
+ "projen": "^0.77.2",
116
112
  "sass": "^1.54.0",
117
113
  "semver": "^7.5.4",
118
114
  "standard-version": "^9",
@@ -126,7 +122,7 @@
126
122
  "vite-plugin-singlefile": "^0.13.5"
127
123
  },
128
124
  "peerDependencies": {
129
- "aws-cdk-lib": "^2.77.0",
125
+ "aws-cdk-lib": "^2.110.0",
130
126
  "constructs": "^10.0.5"
131
127
  },
132
128
  "keywords": [
@@ -146,7 +142,7 @@
146
142
  "publishConfig": {
147
143
  "access": "public"
148
144
  },
149
- "version": "0.11.5",
145
+ "version": "0.12.0",
150
146
  "jest": {
151
147
  "testMatch": [
152
148
  "<rootDir>/src/**/__tests__/**/*.ts?(x)",
@@ -1,165 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/image-builders/aws-image-builder/reaper.lambda.ts
21
- var reaper_lambda_exports = {};
22
- __export(reaper_lambda_exports, {
23
- handler: () => handler
24
- });
25
- module.exports = __toCommonJS(reaper_lambda_exports);
26
- var import_client_ec2 = require("@aws-sdk/client-ec2");
27
- var import_client_ecr = require("@aws-sdk/client-ecr");
28
- var import_client_imagebuilder = require("@aws-sdk/client-imagebuilder");
29
- var ec2 = new import_client_ec2.EC2Client();
30
- var ecr = new import_client_ecr.ECRClient();
31
- var ib = new import_client_imagebuilder.ImagebuilderClient();
32
- async function iterateImageVersions(imageName) {
33
- let result = [];
34
- let params = {
35
- owner: "Self",
36
- filters: [
37
- {
38
- name: "name",
39
- values: [imageName]
40
- }
41
- ]
42
- };
43
- while (true) {
44
- const response = await ib.send(new import_client_imagebuilder.ListImagesCommand(params));
45
- if (response.imageVersionList) {
46
- for (const imageVersion of response.imageVersionList) {
47
- if (imageVersion.arn) {
48
- result.push(imageVersion.arn);
49
- }
50
- }
51
- }
52
- if (!response.nextToken) {
53
- break;
54
- }
55
- params.nextToken = response.nextToken;
56
- }
57
- return result;
58
- }
59
- async function iterateImageBuildVersions(imageVersionArn) {
60
- let result = [];
61
- let params = {
62
- imageVersionArn
63
- };
64
- while (true) {
65
- const response = await ib.send(new import_client_imagebuilder.ListImageBuildVersionsCommand(params));
66
- if (response.imageSummaryList) {
67
- for (const imageBuildVersion of response.imageSummaryList) {
68
- if (imageBuildVersion.state?.status !== "AVAILABLE") {
69
- console.log(`${imageBuildVersion.arn} is still being created, so we can't delete it`);
70
- continue;
71
- }
72
- result.push(imageBuildVersion);
73
- }
74
- }
75
- if (!response.nextToken) {
76
- break;
77
- }
78
- params.nextToken = response.nextToken;
79
- }
80
- return result;
81
- }
82
- async function amisGone(amis) {
83
- if (!amis) {
84
- console.log("No AMIs found, so we can delete the image version build");
85
- return true;
86
- }
87
- for (const ami of amis) {
88
- console.log(`Checking if ${ami.image} exists`);
89
- if (!ami.image) {
90
- console.log("No AMI, so we can delete it");
91
- continue;
92
- }
93
- try {
94
- const response = await ec2.send(new import_client_ec2.DescribeImagesCommand({
95
- ImageIds: [ami.image]
96
- }));
97
- if (response.Images?.length ?? 0 > 0) {
98
- console.log("AMI still available, so we can't delete it");
99
- return false;
100
- }
101
- } catch (e) {
102
- if (e.code != "InvalidAMIID.NotFound") {
103
- console.error(`Unknown exception while checking if ${ami.image} exists:`, e);
104
- return false;
105
- }
106
- }
107
- }
108
- console.log("All AMIs are gone, so we can delete the image version build");
109
- return true;
110
- }
111
- async function dockerImagesGone(dockerImages) {
112
- if (!dockerImages) {
113
- console.log("No docker images, so we can delete the image version build");
114
- return true;
115
- }
116
- for (const images of dockerImages) {
117
- for (const image of images.imageUris ?? []) {
118
- const [repo, version] = image.split(":", 2);
119
- const [_, repoName] = repo.split("/", 2);
120
- if (version === "latest") {
121
- continue;
122
- }
123
- console.log(`Checking if ${repoName}:${version} exists`);
124
- try {
125
- const response = await ecr.send(new import_client_ecr.DescribeImagesCommand({
126
- repositoryName: repoName,
127
- imageIds: [{ imageTag: version }]
128
- }));
129
- if (response.imageDetails && response.imageDetails.length > 0) {
130
- if (response.imageDetails[0].imageTags?.includes("latest")) {
131
- console.log(`Docker image ${repoName}:${version} still available and tagged latest, so we can't delete it`);
132
- return false;
133
- }
134
- }
135
- } catch (e) {
136
- if (e.code != "RepositoryNotFoundException" && e.code != "ImageNotFoundException") {
137
- console.error(`Unknown exception while checking if ${repoName}:${version} exists:`, e);
138
- return false;
139
- }
140
- }
141
- }
142
- }
143
- console.log("All Docker images are gone, so we can delete the image version build");
144
- return true;
145
- }
146
- async function handler(event, _context) {
147
- for (const imageVersion of await iterateImageVersions(event.RecipeName)) {
148
- for (const imageBuildVersion of await iterateImageBuildVersions(imageVersion)) {
149
- if (!imageBuildVersion.arn) {
150
- continue;
151
- }
152
- console.log(`Checking ${imageBuildVersion.name}/${imageBuildVersion.version}`);
153
- if (await amisGone(imageBuildVersion.outputResources?.amis) && await dockerImagesGone(imageBuildVersion.outputResources?.containers)) {
154
- console.log("Deleting image version build", imageBuildVersion.arn);
155
- await ib.send(new import_client_imagebuilder.DeleteImageCommand({
156
- imageBuildVersionArn: imageBuildVersion.arn
157
- }));
158
- }
159
- }
160
- }
161
- }
162
- // Annotate the CommonJS export names for ESM import in node:
163
- 0 && (module.exports = {
164
- handler
165
- });
@@ -1,13 +0,0 @@
1
- import * as lambda from 'aws-cdk-lib/aws-lambda';
2
- import { Construct } from 'constructs';
3
- /**
4
- * Props for ReaperFunction
5
- */
6
- export interface ReaperFunctionProps extends lambda.FunctionOptions {
7
- }
8
- /**
9
- * An AWS Lambda function which executes src/image-builders/aws-image-builder/reaper.
10
- */
11
- export declare class ReaperFunction extends lambda.Function {
12
- constructor(scope: Construct, id: string, props?: ReaperFunctionProps);
13
- }
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ReaperFunction = void 0;
4
- // ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
5
- const path = require("path");
6
- const lambda = require("aws-cdk-lib/aws-lambda");
7
- /**
8
- * An AWS Lambda function which executes src/image-builders/aws-image-builder/reaper.
9
- */
10
- class ReaperFunction extends lambda.Function {
11
- constructor(scope, id, props) {
12
- super(scope, id, {
13
- description: 'src/image-builders/aws-image-builder/reaper.lambda.ts',
14
- ...props,
15
- runtime: new lambda.Runtime('nodejs18.x', lambda.RuntimeFamily.NODEJS),
16
- handler: 'index.handler',
17
- code: lambda.Code.fromAsset(path.join(__dirname, '../../../assets/image-builders/aws-image-builder/reaper.lambda')),
18
- });
19
- this.addEnvironment('AWS_NODEJS_CONNECTION_REUSE_ENABLED', '1', { removeInEdge: true });
20
- }
21
- }
22
- exports.ReaperFunction = ReaperFunction;
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhcGVyLWZ1bmN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2ltYWdlLWJ1aWxkZXJzL2F3cy1pbWFnZS1idWlsZGVyL3JlYXBlci1mdW5jdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2RUFBNkU7QUFDN0UsNkJBQTZCO0FBQzdCLGlEQUFpRDtBQVNqRDs7R0FFRztBQUNILE1BQWEsY0FBZSxTQUFRLE1BQU0sQ0FBQyxRQUFRO0lBQ2pELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMkI7UUFDbkUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDZixXQUFXLEVBQUUsdURBQXVEO1lBQ3BFLEdBQUcsS0FBSztZQUNSLE9BQU8sRUFBRSxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO1lBQ3RFLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxnRUFBZ0UsQ0FBQyxDQUFDO1NBQ3BILENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxjQUFjLENBQUMscUNBQXFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDMUYsQ0FBQztDQUNGO0FBWEQsd0NBV0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB+fiBHZW5lcmF0ZWQgYnkgcHJvamVuLiBUbyBtb2RpZnksIGVkaXQgLnByb2plbnJjLmpzIGFuZCBydW4gXCJucHggcHJvamVuXCIuXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbi8qKlxuICogUHJvcHMgZm9yIFJlYXBlckZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVhcGVyRnVuY3Rpb25Qcm9wcyBleHRlbmRzIGxhbWJkYS5GdW5jdGlvbk9wdGlvbnMge1xufVxuXG4vKipcbiAqIEFuIEFXUyBMYW1iZGEgZnVuY3Rpb24gd2hpY2ggZXhlY3V0ZXMgc3JjL2ltYWdlLWJ1aWxkZXJzL2F3cy1pbWFnZS1idWlsZGVyL3JlYXBlci5cbiAqL1xuZXhwb3J0IGNsYXNzIFJlYXBlckZ1bmN0aW9uIGV4dGVuZHMgbGFtYmRhLkZ1bmN0aW9uIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBSZWFwZXJGdW5jdGlvblByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ3NyYy9pbWFnZS1idWlsZGVycy9hd3MtaW1hZ2UtYnVpbGRlci9yZWFwZXIubGFtYmRhLnRzJyxcbiAgICAgIC4uLnByb3BzLFxuICAgICAgcnVudGltZTogbmV3IGxhbWJkYS5SdW50aW1lKCdub2RlanMxOC54JywgbGFtYmRhLlJ1bnRpbWVGYW1pbHkuTk9ERUpTKSxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vLi4vYXNzZXRzL2ltYWdlLWJ1aWxkZXJzL2F3cy1pbWFnZS1idWlsZGVyL3JlYXBlci5sYW1iZGEnKSksXG4gICAgfSk7XG4gICAgdGhpcy5hZGRFbnZpcm9ubWVudCgnQVdTX05PREVKU19DT05ORUNUSU9OX1JFVVNFX0VOQUJMRUQnLCAnMScsIHsgcmVtb3ZlSW5FZGdlOiB0cnVlIH0pO1xuICB9XG59Il19
@@ -1,9 +0,0 @@
1
- import * as AWSLambda from 'aws-lambda';
2
- interface ReaperInput {
3
- /**
4
- * Recipe/image name.
5
- */
6
- RecipeName: string;
7
- }
8
- export declare function handler(event: ReaperInput, _context: AWSLambda.Context): Promise<void>;
9
- export {};
@@ -1,151 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handler = void 0;
4
- const client_ec2_1 = require("@aws-sdk/client-ec2");
5
- const client_ecr_1 = require("@aws-sdk/client-ecr");
6
- const client_imagebuilder_1 = require("@aws-sdk/client-imagebuilder");
7
- const ec2 = new client_ec2_1.EC2Client();
8
- const ecr = new client_ecr_1.ECRClient();
9
- const ib = new client_imagebuilder_1.ImagebuilderClient();
10
- async function iterateImageVersions(imageName) {
11
- let result = [];
12
- let params = {
13
- owner: 'Self',
14
- filters: [
15
- {
16
- name: 'name',
17
- values: [imageName],
18
- },
19
- ],
20
- };
21
- while (true) {
22
- const response = await ib.send(new client_imagebuilder_1.ListImagesCommand(params));
23
- if (response.imageVersionList) {
24
- for (const imageVersion of response.imageVersionList) {
25
- if (imageVersion.arn) {
26
- result.push(imageVersion.arn);
27
- }
28
- }
29
- }
30
- if (!response.nextToken) {
31
- break;
32
- }
33
- params.nextToken = response.nextToken;
34
- }
35
- return result;
36
- }
37
- async function iterateImageBuildVersions(imageVersionArn) {
38
- let result = [];
39
- let params = {
40
- imageVersionArn: imageVersionArn,
41
- };
42
- while (true) {
43
- const response = await ib.send(new client_imagebuilder_1.ListImageBuildVersionsCommand(params));
44
- if (response.imageSummaryList) {
45
- for (const imageBuildVersion of response.imageSummaryList) {
46
- if (imageBuildVersion.state?.status !== 'AVAILABLE') {
47
- // if it's not available, then it's still being created
48
- console.log(`${imageBuildVersion.arn} is still being created, so we can't delete it`);
49
- continue;
50
- }
51
- result.push(imageBuildVersion);
52
- }
53
- }
54
- if (!response.nextToken) {
55
- break;
56
- }
57
- params.nextToken = response.nextToken;
58
- }
59
- return result;
60
- }
61
- async function amisGone(amis) {
62
- if (!amis) {
63
- console.log('No AMIs found, so we can delete the image version build');
64
- return true;
65
- }
66
- for (const ami of amis) {
67
- console.log(`Checking if ${ami.image} exists`);
68
- if (!ami.image) {
69
- // no image? delete it
70
- console.log('No AMI, so we can delete it');
71
- continue;
72
- }
73
- try {
74
- const response = await ec2.send(new client_ec2_1.DescribeImagesCommand({
75
- ImageIds: [ami.image],
76
- }));
77
- if (response.Images?.length ?? 0 > 0) {
78
- // image still available
79
- console.log('AMI still available, so we can\'t delete it');
80
- return false;
81
- }
82
- }
83
- catch (e) {
84
- if (e.code != 'InvalidAMIID.NotFound') {
85
- // unknown exception, keep image for now
86
- console.error(`Unknown exception while checking if ${ami.image} exists:`, e);
87
- return false;
88
- }
89
- }
90
- }
91
- console.log('All AMIs are gone, so we can delete the image version build');
92
- return true;
93
- }
94
- async function dockerImagesGone(dockerImages) {
95
- if (!dockerImages) {
96
- console.log('No docker images, so we can delete the image version build');
97
- return true;
98
- }
99
- for (const images of dockerImages) {
100
- for (const image of images.imageUris ?? []) {
101
- const [repo, version] = image.split(':', 2);
102
- const [_, repoName] = repo.split('/', 2);
103
- if (version === 'latest') {
104
- // don't check latest as image builder sometimes keeps that tag on forever
105
- // we want to check if the image is still tagged as latest in ECR, not Image Builder
106
- continue;
107
- }
108
- console.log(`Checking if ${repoName}:${version} exists`);
109
- try {
110
- const response = await ecr.send(new client_ecr_1.DescribeImagesCommand({
111
- repositoryName: repoName,
112
- imageIds: [{ imageTag: version }],
113
- }));
114
- if (response.imageDetails && response.imageDetails.length > 0) {
115
- // image still available
116
- if (response.imageDetails[0].imageTags?.includes('latest')) {
117
- console.log(`Docker image ${repoName}:${version} still available and tagged latest, so we can't delete it`);
118
- return false;
119
- }
120
- }
121
- }
122
- catch (e) {
123
- if (e.code != 'RepositoryNotFoundException' && e.code != 'ImageNotFoundException') {
124
- // unknown exception, keep image for now
125
- console.error(`Unknown exception while checking if ${repoName}:${version} exists:`, e);
126
- return false;
127
- }
128
- }
129
- }
130
- }
131
- console.log('All Docker images are gone, so we can delete the image version build');
132
- return true;
133
- }
134
- async function handler(event, _context) {
135
- for (const imageVersion of await iterateImageVersions(event.RecipeName)) {
136
- for (const imageBuildVersion of await iterateImageBuildVersions(imageVersion)) {
137
- if (!imageBuildVersion.arn) {
138
- continue;
139
- }
140
- console.log(`Checking ${imageBuildVersion.name}/${imageBuildVersion.version}`);
141
- if (await amisGone(imageBuildVersion.outputResources?.amis) && await dockerImagesGone(imageBuildVersion.outputResources?.containers)) {
142
- console.log('Deleting image version build', imageBuildVersion.arn);
143
- await ib.send(new client_imagebuilder_1.DeleteImageCommand({
144
- imageBuildVersionArn: imageBuildVersion.arn,
145
- }));
146
- }
147
- }
148
- }
149
- }
150
- exports.handler = handler;
151
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhcGVyLmxhbWJkYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9pbWFnZS1idWlsZGVycy9hd3MtaW1hZ2UtYnVpbGRlci9yZWFwZXIubGFtYmRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG9EQUFtRztBQUNuRyxvREFBbUc7QUFDbkcsc0VBU3NDO0FBU3RDLE1BQU0sR0FBRyxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDO0FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDO0FBQzVCLE1BQU0sRUFBRSxHQUFHLElBQUksd0NBQWtCLEVBQUUsQ0FBQztBQUVwQyxLQUFLLFVBQVUsb0JBQW9CLENBQUMsU0FBaUI7SUFDbkQsSUFBSSxNQUFNLEdBQWEsRUFBRSxDQUFDO0lBRTFCLElBQUksTUFBTSxHQUFzQjtRQUM5QixLQUFLLEVBQUUsTUFBTTtRQUNiLE9BQU8sRUFBRTtZQUNQO2dCQUNFLElBQUksRUFBRSxNQUFNO2dCQUNaLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQzthQUNwQjtTQUNGO0tBQ0YsQ0FBQztJQUVGLE9BQU8sSUFBSSxFQUFFO1FBQ1gsTUFBTSxRQUFRLEdBQUcsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksdUNBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUU5RCxJQUFJLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtZQUM3QixLQUFLLE1BQU0sWUFBWSxJQUFJLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDcEQsSUFBSSxZQUFZLENBQUMsR0FBRyxFQUFFO29CQUNwQixNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztpQkFDL0I7YUFDRjtTQUNGO1FBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUU7WUFDdkIsTUFBTTtTQUNQO1FBQ0QsTUFBTSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxD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QUMsQ0FBQztvQkFDdkYsT0FBTyxLQUFLLENBQUM7aUJBQ2Q7YUFDRjtTQUNGO0tBQ0Y7SUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLHNFQUFzRSxDQUFDLENBQUM7SUFFcEYsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRU0sS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrQixFQUFFLFFBQTJCO0lBQzNFLEtBQUssTUFBTSxZQUFZLElBQUksTUFBTSxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFDdkUsS0FBSyxNQUFNLGlCQUFpQixJQUFJLE1BQU0seUJBQXlCLENBQUMsWUFBWSxDQUFDLEVBQUU7WUFDN0UsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtnQkFDMUIsU0FBUzthQUNWO1lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLGlCQUFpQixDQUFDLElBQUksSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBRS9FLElBQUksTUFBTSxRQUFRLENBQUMsaUJBQWlCLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxJQUFJLE1BQU0sZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsZUFBZSxFQUFFLFVBQVUsQ0FBQyxFQUFFO2dCQUNwSSxPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixFQUFFLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNuRSxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSx3Q0FBa0IsQ0FBQztvQkFDbkMsb0JBQW9CLEVBQUUsaUJBQWlCLENBQUMsR0FBRztpQkFDNUMsQ0FBQyxDQUFDLENBQUM7YUFDTDtTQUNGO0tBQ0Y7QUFDSCxDQUFDO0FBakJELDBCQWlCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlc2NyaWJlSW1hZ2VzQ29tbWFuZCBhcyBEZXNjcmliZUVjMkltYWdlc0NvbW1hbmQsIEVDMkNsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1lYzInO1xuaW1wb3J0IHsgRGVzY3JpYmVJbWFnZXNDb21tYW5kIGFzIERlc2NyaWJlRWNySW1hZ2VzQ29tbWFuZCwgRUNSQ2xpZW50IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWVjcic7XG5pbXBvcnQge1xuICBBbWksIENvbnRhaW5lcixcbiAgRGVsZXRlSW1hZ2VDb21tYW5kLFxuICBJbWFnZWJ1aWxkZXJDbGllbnQsXG4gIEltYWdlU3VtbWFyeSxcbiAgTGlzdEltYWdlQnVpbGRWZXJzaW9uc0NvbW1hbmQsXG4gIExpc3RJbWFnZUJ1aWxkVmVyc2lvbnNSZXF1ZXN0LFxuICBMaXN0SW1hZ2VzQ29tbWFuZCxcbiAgTGlzdEltYWdlc1JlcXVlc3QsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1pbWFnZWJ1aWxkZXInO1xuaW1wb3J0ICogYXMgQVdTTGFtYmRhIGZyb20gJ2F3cy1sYW1iZGEnO1xuaW50ZXJmYWNlIFJlYXBlcklucHV0IHtcbiAgLyoqXG4gICAqIFJlY2lwZS9pbWFnZSBuYW1lLlxuICAgKi9cbiAgUmVjaXBlTmFtZTogc3RyaW5nO1xufVxuXG5jb25zdCBlYzIgPSBuZXcgRUMyQ2xpZW50KCk7XG5jb25zdCBlY3IgPSBuZXcgRUNSQ2xpZW50KCk7XG5jb25zdCBpYiA9IG5ldyBJbWFnZWJ1aWxkZXJDbGllbnQoKTtcblxuYXN5bmMgZnVuY3Rpb24gaXRlcmF0ZUltYWdlVmVyc2lvbnMoaW1hZ2VOYW1lOiBzdHJpbmcpIHtcbiAgbGV0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcblxuICBsZXQgcGFyYW1zOiBMaXN0SW1hZ2VzUmVxdWVzdCA9IHtcbiAgICBvd25lcjogJ1NlbGYnLFxuICAgIGZpbHRlcnM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ25hbWUnLFxuICAgICAgICB2YWx1ZXM6IFtpbWFnZU5hbWVdLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBpYi5zZW5kKG5ldyBMaXN0SW1hZ2VzQ29tbWFuZChwYXJhbXMpKTtcblxuICAgIGlmIChyZXNwb25zZS5pbWFnZVZlcnNpb25MaXN0KSB7XG4gICAgICBmb3IgKGNvbnN0IGltYWdlVmVyc2lvbiBvZiByZXNwb25zZS5pbWFnZVZlcnNpb25MaXN0KSB7XG4gICAgICAgIGlmIChpbWFnZVZlcnNpb24uYXJuKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goaW1hZ2VWZXJzaW9uLmFybik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm5leHRUb2tlbikge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHBhcmFtcy5uZXh0VG9rZW4gPSByZXNwb25zZS5uZXh0VG9rZW47XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBpdGVyYXRlSW1hZ2VCdWlsZFZlcnNpb25zKGltYWdlVmVyc2lvbkFybjogc3RyaW5nKSB7XG4gIGxldCByZXN1bHQ6IEltYWdlU3VtbWFyeVtdID0gW107XG5cbiAgbGV0IHBhcmFtczogTGlzdEltYWdlQnVpbGRWZXJzaW9uc1JlcXVlc3QgPSB7XG4gICAgaW1hZ2VWZXJzaW9uQXJuOiBpbWFnZVZlcnNpb25Bcm4sXG4gIH07XG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGliLnNlbmQobmV3IExpc3RJbWFnZUJ1aWxkVmVyc2lvbnNDb21tYW5kKHBhcmFtcykpO1xuXG4gICAgaWYgKHJlc3BvbnNlLmltYWdlU3VtbWFyeUxpc3QpIHtcbiAgICAgIGZvciAoY29uc3QgaW1hZ2VCdWlsZFZlcnNpb24gb2YgcmVzcG9uc2UuaW1hZ2VTdW1tYXJ5TGlzdCkge1xuICAgICAgICBpZiAoaW1hZ2VCdWlsZFZlcnNpb24uc3RhdGU/LnN0YXR1cyAhPT0gJ0FWQUlMQUJMRScpIHtcbiAgICAgICAgICAvLyBpZiBpdCdzIG5vdCBhdmFpbGFibGUsIHRoZW4gaXQncyBzdGlsbCBiZWluZyBjcmVhdGVkXG4gICAgICAgICAgY29uc29sZS5sb2coYCR7aW1hZ2VCdWlsZFZlcnNpb24uYXJufSBpcyBzdGlsbCBiZWluZyBjcmVhdGVkLCBzbyB3ZSBjYW4ndCBkZWxldGUgaXRgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdC5wdXNoKGltYWdlQnVpbGRWZXJzaW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm5leHRUb2tlbikge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHBhcmFtcy5uZXh0VG9rZW4gPSByZXNwb25zZS5uZXh0VG9rZW47XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBhbWlzR29uZShhbWlzPzogQW1pW10pIHtcbiAgaWYgKCFhbWlzKSB7XG4gICAgY29uc29sZS5sb2coJ05vIEFNSXMgZm91bmQsIHNvIHdlIGNhbiBkZWxldGUgdGhlIGltYWdlIHZlcnNpb24gYnVpbGQnKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZvciAoY29uc3QgYW1pIG9mIGFtaXMpIHtcbiAgICBjb25zb2xlLmxvZyhgQ2hlY2tpbmcgaWYgJHthbWkuaW1hZ2V9IGV4aXN0c2ApO1xuXG4gICAgaWYgKCFhbWkuaW1hZ2UpIHtcbiAgICAgIC8vIG5vIGltYWdlPyBkZWxldGUgaXRcbiAgICAgIGNvbnNvbGUubG9nKCdObyBBTUksIHNvIHdlIGNhbiBkZWxldGUgaXQnKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGVjMi5zZW5kKG5ldyBEZXNjcmliZUVjMkltYWdlc0NvbW1hbmQoe1xuICAgICAgICBJbWFnZUlkczogW2FtaS5pbWFnZV0sXG4gICAgICB9KSk7XG5cbiAgICAgIGlmIChyZXNwb25zZS5JbWFnZXM/Lmxlbmd0aCA/PyAwID4gMCkge1xuICAgICAgICAvLyBpbWFnZSBzdGlsbCBhdmFpbGFibGVcbiAgICAgICAgY29uc29sZS5sb2coJ0FNSSBzdGlsbCBhdmFpbGFibGUsIHNvIHdlIGNhblxcJ3QgZGVsZXRlIGl0Jyk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmIChlLmNvZGUgIT0gJ0ludmFsaWRBTUlJRC5Ob3RGb3VuZCcpIHtcbiAgICAgICAgLy8gdW5rbm93biBleGNlcHRpb24sIGtlZXAgaW1hZ2UgZm9yIG5vd1xuICAgICAgICBjb25zb2xlLmVycm9yKGBVbmtub3duIGV4Y2VwdGlvbiB3aGlsZSBjaGVja2luZyBpZiAke2FtaS5pbWFnZX0gZXhpc3RzOmAsIGUpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc29sZS5sb2coJ0FsbCBBTUlzIGFyZSBnb25lLCBzbyB3ZSBjYW4gZGVsZXRlIHRoZSBpbWFnZSB2ZXJzaW9uIGJ1aWxkJyk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRvY2tlckltYWdlc0dvbmUoZG9ja2VySW1hZ2VzPzogQ29udGFpbmVyW10pIHtcbiAgaWYgKCFkb2NrZXJJbWFnZXMpIHtcbiAgICBjb25zb2xlLmxvZygnTm8gZG9ja2VyIGltYWdlcywgc28gd2UgY2FuIGRlbGV0ZSB0aGUgaW1hZ2UgdmVyc2lvbiBidWlsZCcpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZm9yIChjb25zdCBpbWFnZXMgb2YgZG9ja2VySW1hZ2VzKSB7XG4gICAgZm9yIChjb25zdCBpbWFnZSBvZiBpbWFnZXMuaW1hZ2VVcmlzID8/IFtdKSB7XG4gICAgICBjb25zdCBbcmVwbywgdmVyc2lvbl0gPSBpbWFnZS5zcGxpdCgnOicsIDIpO1xuICAgICAgY29uc3QgW18sIHJlcG9OYW1lXSA9IHJlcG8uc3BsaXQoJy8nLCAyKTtcblxuICAgICAgaWYgKHZlcnNpb24gPT09ICdsYXRlc3QnKSB7XG4gICAgICAgIC8vIGRvbid0IGNoZWNrIGxhdGVzdCBhcyBpbWFnZSBidWlsZGVyIHNvbWV0aW1lcyBrZWVwcyB0aGF0IHRhZyBvbiBmb3JldmVyXG4gICAgICAgIC8vIHdlIHdhbnQgdG8gY2hlY2sgaWYgdGhlIGltYWdlIGlzIHN0aWxsIHRhZ2dlZCBhcyBsYXRlc3QgaW4gRUNSLCBub3QgSW1hZ2UgQnVpbGRlclxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc29sZS5sb2coYENoZWNraW5nIGlmICR7cmVwb05hbWV9OiR7dmVyc2lvbn0gZXhpc3RzYCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZWNyLnNlbmQobmV3IERlc2NyaWJlRWNySW1hZ2VzQ29tbWFuZCh7XG4gICAgICAgICAgcmVwb3NpdG9yeU5hbWU6IHJlcG9OYW1lLFxuICAgICAgICAgIGltYWdlSWRzOiBbeyBpbWFnZVRhZzogdmVyc2lvbiB9XSxcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGlmIChyZXNwb25zZS5pbWFnZURldGFpbHMgJiYgcmVzcG9uc2UuaW1hZ2VEZXRhaWxzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAvLyBpbWFnZSBzdGlsbCBhdmFpbGFibGVcbiAgICAgICAgICBpZiAocmVzcG9uc2UuaW1hZ2VEZXRhaWxzWzBdLmltYWdlVGFncz8uaW5jbHVkZXMoJ2xhdGVzdCcpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgRG9ja2VyIGltYWdlICR7cmVwb05hbWV9OiR7dmVyc2lvbn0gc3RpbGwgYXZhaWxhYmxlIGFuZCB0YWdnZWQgbGF0ZXN0LCBzbyB3ZSBjYW4ndCBkZWxldGUgaXRgKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBpZiAoZS5jb2RlICE9ICdSZXBvc2l0b3J5Tm90Rm91bmRFeGNlcHRpb24nICYmIGUuY29kZSAhPSAnSW1hZ2VOb3RGb3VuZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgICAvLyB1bmtub3duIGV4Y2VwdGlvbiwga2VlcCBpbWFnZSBmb3Igbm93XG4gICAgICAgICAgY29uc29sZS5lcnJvcihgVW5rbm93biBleGNlcHRpb24gd2hpbGUgY2hlY2tpbmcgaWYgJHtyZXBvTmFtZX06JHt2ZXJzaW9ufSBleGlzdHM6YCwgZSk7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc29sZS5sb2coJ0FsbCBEb2NrZXIgaW1hZ2VzIGFyZSBnb25lLCBzbyB3ZSBjYW4gZGVsZXRlIHRoZSBpbWFnZSB2ZXJzaW9uIGJ1aWxkJyk7XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBSZWFwZXJJbnB1dCwgX2NvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGZvciAoY29uc3QgaW1hZ2VWZXJzaW9uIG9mIGF3YWl0IGl0ZXJhdGVJbWFnZVZlcnNpb25zKGV2ZW50LlJlY2lwZU5hbWUpKSB7XG4gICAgZm9yIChjb25zdCBpbWFnZUJ1aWxkVmVyc2lvbiBvZiBhd2FpdCBpdGVyYXRlSW1hZ2VCdWlsZFZlcnNpb25zKGltYWdlVmVyc2lvbikpIHtcbiAgICAgIGlmICghaW1hZ2VCdWlsZFZlcnNpb24uYXJuKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmxvZyhgQ2hlY2tpbmcgJHtpbWFnZUJ1aWxkVmVyc2lvbi5uYW1lfS8ke2ltYWdlQnVpbGRWZXJzaW9uLnZlcnNpb259YCk7XG5cbiAgICAgIGlmIChhd2FpdCBhbWlzR29uZShpbWFnZUJ1aWxkVmVyc2lvbi5vdXRwdXRSZXNvdXJjZXM/LmFtaXMpICYmIGF3YWl0IGRvY2tlckltYWdlc0dvbmUoaW1hZ2VCdWlsZFZlcnNpb24ub3V0cHV0UmVzb3VyY2VzPy5jb250YWluZXJzKSkge1xuICAgICAgICBjb25zb2xlLmxvZygnRGVsZXRpbmcgaW1hZ2UgdmVyc2lvbiBidWlsZCcsIGltYWdlQnVpbGRWZXJzaW9uLmFybik7XG4gICAgICAgIGF3YWl0IGliLnNlbmQobmV3IERlbGV0ZUltYWdlQ29tbWFuZCh7XG4gICAgICAgICAgaW1hZ2VCdWlsZFZlcnNpb25Bcm46IGltYWdlQnVpbGRWZXJzaW9uLmFybixcbiAgICAgICAgfSkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BuildImageFunction = void 0;
4
- // ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
5
- const path = require("path");
6
- const lambda = require("aws-cdk-lib/aws-lambda");
7
- /**
8
- * An AWS Lambda function which executes src/providers/build-image.
9
- */
10
- class BuildImageFunction extends lambda.Function {
11
- constructor(scope, id, props) {
12
- super(scope, id, {
13
- description: 'src/providers/build-image.lambda.ts',
14
- ...props,
15
- runtime: new lambda.Runtime('nodejs18.x', lambda.RuntimeFamily.NODEJS),
16
- handler: 'index.handler',
17
- code: lambda.Code.fromAsset(path.join(__dirname, '../../assets/providers/build-image.lambda')),
18
- });
19
- this.addEnvironment('AWS_NODEJS_CONNECTION_REUSE_ENABLED', '1', { removeInEdge: true });
20
- }
21
- }
22
- exports.BuildImageFunction = BuildImageFunction;
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtaW1hZ2UtZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmlkZXJzL2J1aWxkLWltYWdlLWZ1bmN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZFQUE2RTtBQUM3RSw2QkFBNkI7QUFDN0IsaURBQWlEO0FBU2pEOztHQUVHO0FBQ0gsTUFBYSxrQkFBbUIsU0FBUSxNQUFNLENBQUMsUUFBUTtJQUNyRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQStCO1FBQ3ZFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsV0FBVyxFQUFFLHFDQUFxQztZQUNsRCxHQUFHLEtBQUs7WUFDUixPQUFPLEVBQUUsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQztZQUN0RSxPQUFPLEVBQUUsZUFBZTtZQUN4QixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsMkNBQTJDLENBQUMsQ0FBQztTQUMvRixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsY0FBYyxDQUFDLHFDQUFxQyxFQUFFLEdBQUcsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzFGLENBQUM7Q0FDRjtBQVhELGdEQVdDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gfn4gR2VuZXJhdGVkIGJ5IHByb2plbi4gVG8gbW9kaWZ5LCBlZGl0IC5wcm9qZW5yYy5qcyBhbmQgcnVuIFwibnB4IHByb2plblwiLlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BzIGZvciBCdWlsZEltYWdlRnVuY3Rpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCdWlsZEltYWdlRnVuY3Rpb25Qcm9wcyBleHRlbmRzIGxhbWJkYS5GdW5jdGlvbk9wdGlvbnMge1xufVxuXG4vKipcbiAqIEFuIEFXUyBMYW1iZGEgZnVuY3Rpb24gd2hpY2ggZXhlY3V0ZXMgc3JjL3Byb3ZpZGVycy9idWlsZC1pbWFnZS5cbiAqL1xuZXhwb3J0IGNsYXNzIEJ1aWxkSW1hZ2VGdW5jdGlvbiBleHRlbmRzIGxhbWJkYS5GdW5jdGlvbiB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzPzogQnVpbGRJbWFnZUZ1bmN0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnc3JjL3Byb3ZpZGVycy9idWlsZC1pbWFnZS5sYW1iZGEudHMnLFxuICAgICAgLi4ucHJvcHMsXG4gICAgICBydW50aW1lOiBuZXcgbGFtYmRhLlJ1bnRpbWUoJ25vZGVqczE4LngnLCBsYW1iZGEuUnVudGltZUZhbWlseS5OT0RFSlMpLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgY29kZTogbGFtYmRhLkNvZGUuZnJvbUFzc2V0KHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8uLi9hc3NldHMvcHJvdmlkZXJzL2J1aWxkLWltYWdlLmxhbWJkYScpKSxcbiAgICB9KTtcbiAgICB0aGlzLmFkZEVudmlyb25tZW50KCdBV1NfTk9ERUpTX0NPTk5FQ1RJT05fUkVVU0VfRU5BQkxFRCcsICcxJywgeyByZW1vdmVJbkVkZ2U6IHRydWUgfSk7XG4gIH1cbn0iXX0=
@@ -1,92 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handler = void 0;
4
- const client_codebuild_1 = require("@aws-sdk/client-codebuild");
5
- const client_ecr_1 = require("@aws-sdk/client-ecr");
6
- const client_imagebuilder_1 = require("@aws-sdk/client-imagebuilder");
7
- const lambda_helpers_1 = require("../lambda-helpers");
8
- const codebuild = new client_codebuild_1.CodeBuildClient();
9
- const ecr = new client_ecr_1.ECRClient();
10
- const ib = new client_imagebuilder_1.ImagebuilderClient();
11
- async function handler(event, context) {
12
- try {
13
- console.log(JSON.stringify({ ...event, ResponseURL: '...' }));
14
- const deleteOnly = event.ResourceProperties.DeleteOnly;
15
- const repoName = event.ResourceProperties.RepoName;
16
- const projectName = event.ResourceProperties.ProjectName;
17
- const ibName = event.ResourceProperties.ImageBuilderName;
18
- // let physicalResourceId: string;
19
- // let data: { [key: string]: string } = {};
20
- switch (event.RequestType) {
21
- case 'Create':
22
- case 'Update':
23
- if (deleteOnly) {
24
- await (0, lambda_helpers_1.customResourceRespond)(event, 'SUCCESS', 'OK', 'Deleter', {});
25
- break;
26
- }
27
- console.log(`Starting CodeBuild project ${projectName}`);
28
- await codebuild.send(new client_codebuild_1.StartBuildCommand({
29
- projectName,
30
- environmentVariablesOverride: [
31
- {
32
- type: 'PLAINTEXT',
33
- name: 'STACK_ID',
34
- value: event.StackId,
35
- },
36
- {
37
- type: 'PLAINTEXT',
38
- name: 'REQUEST_ID',
39
- value: event.RequestId,
40
- },
41
- {
42
- type: 'PLAINTEXT',
43
- name: 'LOGICAL_RESOURCE_ID',
44
- value: event.LogicalResourceId,
45
- },
46
- {
47
- type: 'PLAINTEXT',
48
- name: 'RESPONSE_URL',
49
- value: event.ResponseURL,
50
- },
51
- ],
52
- }));
53
- break;
54
- case 'Delete':
55
- const ecrImages = await ecr.send(new client_ecr_1.ListImagesCommand({ repositoryName: repoName, maxResults: 100 }));
56
- if (ecrImages.imageIds && ecrImages.imageIds.length > 0) {
57
- await ecr.send(new client_ecr_1.BatchDeleteImageCommand({
58
- imageIds: ecrImages.imageIds.map(i => {
59
- return { imageDigest: i.imageDigest };
60
- }),
61
- repositoryName: repoName,
62
- }));
63
- }
64
- if (ibName) {
65
- const ibImages = await ib.send(new client_imagebuilder_1.ListImagesCommand({ filters: [{ name: 'name', values: [ibName] }] }));
66
- if (ibImages.imageVersionList) {
67
- for (const v of ibImages.imageVersionList) {
68
- if (v.arn) {
69
- const ibImageVersions = await ib.send(new client_imagebuilder_1.ListImageBuildVersionsCommand({ imageVersionArn: v.arn }));
70
- if (ibImageVersions.imageSummaryList) {
71
- for (const vs of ibImageVersions.imageSummaryList) {
72
- if (vs.arn) {
73
- console.log(`Deleting ${vs.arn}`);
74
- await ib.send(new client_imagebuilder_1.DeleteImageCommand({ imageBuildVersionArn: vs.arn }));
75
- }
76
- }
77
- }
78
- }
79
- }
80
- }
81
- }
82
- await (0, lambda_helpers_1.customResourceRespond)(event, 'SUCCESS', 'OK', event.PhysicalResourceId, {});
83
- break;
84
- }
85
- }
86
- catch (e) {
87
- console.error(e);
88
- await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', e.message || 'Internal Error', context.logStreamName, {});
89
- }
90
- }
91
- exports.handler = handler;
92
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtaW1hZ2UubGFtYmRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Byb3ZpZGVycy9idWlsZC1pbWFnZS5sYW1iZGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQStFO0FBQy9FLG9EQUFvSDtBQUNwSCxzRUFLc0M7QUFFdEMsc0RBQTBEO0FBRTFELE1BQU0sU0FBUyxHQUFHLElBQUksa0NBQWUsRUFBRSxDQUFDO0FBQ3hDLE1BQU0sR0FBRyxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDO0FBQzVCLE1BQU0sRUFBRSxHQUFHLElBQUksd0NBQWtCLEVBQUUsQ0FBQztBQUc3QixLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQWtELEVBQUUsT0FBMEI7SUFDMUcsSUFBSTtRQUNGLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFOUQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFVBQWlDLENBQUM7UUFDOUUsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQztRQUNuRCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO1FBQ3pELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBc0MsQ0FBQztRQUUvRSxrQ0FBa0M7UUFDbEMsNENBQTRDO1FBRTVDLFFBQVEsS0FBSyxDQUFDLFdBQVcsRUFBRTtZQUN6QixLQUFLLFFBQVEsQ0FBQztZQUNkLEtBQUssUUFBUTtnQkFDWCxJQUFJLFVBQVUsRUFBRTtvQkFDZCxNQUFNLElBQUEsc0NBQXFCLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUNuRSxNQUFNO2lC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Q2xGLE1BQU07U0FDVDtLQUNGO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVixPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pCLE1BQU0sSUFBQSxzQ0FBcUIsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFHLENBQVcsQ0FBQyxPQUFPLElBQUksZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztLQUNuSDtBQUNILENBQUM7QUFsRkQsMEJBa0ZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29kZUJ1aWxkQ2xpZW50LCBTdGFydEJ1aWxkQ29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jb2RlYnVpbGQnO1xuaW1wb3J0IHsgQmF0Y2hEZWxldGVJbWFnZUNvbW1hbmQsIEVDUkNsaWVudCwgTGlzdEltYWdlc0NvbW1hbmQgYXMgTGlzdEVjckltYWdlc0NvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtZWNyJztcbmltcG9ydCB7XG4gIERlbGV0ZUltYWdlQ29tbWFuZCxcbiAgSW1hZ2VidWlsZGVyQ2xpZW50LFxuICBMaXN0SW1hZ2VCdWlsZFZlcnNpb25zQ29tbWFuZCxcbiAgTGlzdEltYWdlc0NvbW1hbmQgYXMgTGlzdEliSW1hZ2VzQ29tbWFuZCxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWltYWdlYnVpbGRlcic7XG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBjdXN0b21SZXNvdXJjZVJlc3BvbmQgfSBmcm9tICcuLi9sYW1iZGEtaGVscGVycyc7XG5cbmNvbnN0IGNvZGVidWlsZCA9IG5ldyBDb2RlQnVpbGRDbGllbnQoKTtcbmNvbnN0IGVjciA9IG5ldyBFQ1JDbGllbnQoKTtcbmNvbnN0IGliID0gbmV3IEltYWdlYnVpbGRlckNsaWVudCgpO1xuXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICB0cnkge1xuICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHsgLi4uZXZlbnQsIFJlc3BvbnNlVVJMOiAnLi4uJyB9KSk7XG5cbiAgICBjb25zdCBkZWxldGVPbmx5ID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkRlbGV0ZU9ubHkgYXMgYm9vbGVhbiB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCByZXBvTmFtZSA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5SZXBvTmFtZTtcbiAgICBjb25zdCBwcm9qZWN0TmFtZSA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5Qcm9qZWN0TmFtZTtcbiAgICBjb25zdCBpYk5hbWUgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuSW1hZ2VCdWlsZGVyTmFtZSBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBsZXQgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmc7XG4gICAgLy8gbGV0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcblxuICAgIHN3aXRjaCAoZXZlbnQuUmVxdWVzdFR5cGUpIHtcbiAgICAgIGNhc2UgJ0NyZWF0ZSc6XG4gICAgICBjYXNlICdVcGRhdGUnOlxuICAgICAgICBpZiAoZGVsZXRlT25seSkge1xuICAgICAgICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ1NVQ0NFU1MnLCAnT0snLCAnRGVsZXRlcicsIHt9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGBTdGFydGluZyBDb2RlQnVpbGQgcHJvamVjdCAke3Byb2plY3ROYW1lfWApO1xuICAgICAgICBhd2FpdCBjb2RlYnVpbGQuc2VuZChuZXcgU3RhcnRCdWlsZENvbW1hbmQoe1xuICAgICAgICAgIHByb2plY3ROYW1lLFxuICAgICAgICAgIGVudmlyb25tZW50VmFyaWFibGVzT3ZlcnJpZGU6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogJ1BMQUlOVEVYVCcsXG4gICAgICAgICAgICAgIG5hbWU6ICdTVEFDS19JRCcsXG4gICAgICAgICAgICAgIHZhbHVlOiBldmVudC5TdGFja0lkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogJ1BMQUlOVEVYVCcsXG4gICAgICAgICAgICAgIG5hbWU6ICdSRVFVRVNUX0lEJyxcbiAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LlJlcXVlc3RJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6ICdQTEFJTlRFWFQnLFxuICAgICAgICAgICAgICBuYW1lOiAnTE9HSUNBTF9SRVNPVVJDRV9JRCcsXG4gICAgICAgICAgICAgIHZhbHVlOiBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6ICdQTEFJTlRFWFQnLFxuICAgICAgICAgICAgICBuYW1lOiAnUkVTUE9OU0VfVVJMJyxcbiAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LlJlc3BvbnNlVVJMLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgICAgY29uc3QgZWNySW1hZ2VzID0gYXdhaXQgZWNyLnNlbmQobmV3IExpc3RFY3JJbWFnZXNDb21tYW5kKHsgcmVwb3NpdG9yeU5hbWU6IHJlcG9OYW1lLCBtYXhSZXN1bHRzOiAxMDAgfSkpO1xuICAgICAgICBpZiAoZWNySW1hZ2VzLmltYWdlSWRzICYmIGVjckltYWdlcy5pbWFnZUlkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYXdhaXQgZWNyLnNlbmQobmV3IEJhdGNoRGVsZXRlSW1hZ2VDb21tYW5kKHtcbiAgICAgICAgICAgIGltYWdlSWRzOiBlY3JJbWFnZXMuaW1hZ2VJZHMubWFwKGkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4geyBpbWFnZURpZ2VzdDogaS5pbWFnZURpZ2VzdCB9O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICByZXBvc2l0b3J5TmFtZTogcmVwb05hbWUsXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpYk5hbWUpIHtcbiAgICAgICAgICBjb25zdCBpYkltYWdlcyA9IGF3YWl0IGliLnNlbmQobmV3IExpc3RJYkltYWdlc0NvbW1hbmQoeyBmaWx0ZXJzOiBbeyBuYW1lOiAnbmFtZScsIHZhbHVlczogW2liTmFtZV0gfV0gfSkpO1xuICAgICAgICAgIGlmIChpYkltYWdlcy5pbWFnZVZlcnNpb25MaXN0KSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHYgb2YgaWJJbWFnZXMuaW1hZ2VWZXJzaW9uTGlzdCkge1xuICAgICAgICAgICAgICBpZiAodi5hcm4pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpYkltYWdlVmVyc2lvbnMgPSBhd2FpdCBpYi5zZW5kKG5ldyBMaXN0SW1hZ2VCdWlsZFZlcnNpb25zQ29tbWFuZCh7IGltYWdlVmVyc2lvbkFybjogdi5hcm4gfSkpO1xuICAgICAgICAgICAgICAgIGlmIChpYkltYWdlVmVyc2lvbnMuaW1hZ2VTdW1tYXJ5TGlzdCkge1xuICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCB2cyBvZiBpYkltYWdlVmVyc2lvbnMuaW1hZ2VTdW1tYXJ5TGlzdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodnMuYXJuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYERlbGV0aW5nICR7dnMuYXJufWApO1xuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGliLnNlbmQobmV3IERlbGV0ZUltYWdlQ29tbWFuZCh7IGltYWdlQnVpbGRWZXJzaW9uQXJuOiB2cy5hcm4gfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ1NVQ0NFU1MnLCAnT0snLCBldmVudC5QaHlzaWNhbFJlc291cmNlSWQsIHt9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihlKTtcbiAgICBhd2FpdCBjdXN0b21SZXNvdXJjZVJlc3BvbmQoZXZlbnQsICdGQUlMRUQnLCAoZSBhcyBFcnJvcikubWVzc2FnZSB8fCAnSW50ZXJuYWwgRXJyb3InLCBjb250ZXh0LmxvZ1N0cmVhbU5hbWUsIHt9KTtcbiAgfVxufVxuIl19