token-injectable-docker-builder 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +121 -11
- package/API.md +104 -0
- package/README.md +198 -37
- package/lib/index.d.ts +59 -0
- package/lib/index.js +23 -6
- package/package.json +1 -1
package/.jsii
CHANGED
|
@@ -3898,7 +3898,7 @@
|
|
|
3898
3898
|
},
|
|
3899
3899
|
"name": "token-injectable-docker-builder",
|
|
3900
3900
|
"readme": {
|
|
3901
|
-
"markdown": "# TokenInjectableDockerBuilder\n\nThe `TokenInjectableDockerBuilder` is a flexible AWS CDK construct that enables the usage of AWS CDK tokens in the building, pushing, and deployment of Docker images to Amazon Elastic Container Registry (ECR). It leverages AWS CodeBuild and Lambda custom resources.\n\n---\n\n## Why?\n\nAWS CDK already provides mechanisms for creating deployable assets using Docker, such as [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerImageAsset.html) and [DockerImageCode](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.DockerImageCode.html), but these Constructs are limited because they cannot accept CDK tokens as build-args. The `TokenInjectableDockerBuilder` allows injecting CDK tokens as build-time arguments into Docker-based assets, enabling more dynamic dependency relationships.\n\nFor example, a Next.js frontend Docker image may require an API Gateway URL. With this construct, you can deploy the API Gateway first, then pass its URL as a build-time argument to the Next.js Docker image.\n\n---\n\n## Features\n\n- Automatically builds and pushes Docker images to ECR.\n- Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.\n- Retrieves Docker images for use in ECS or Lambda.\n\n---\n\n## Installation\n\n### For NPM\n\nInstall the construct using NPM:\n\n```bash\nnpm install token-injectable-docker-builder\n```\n\n### For Python\n\nInstall the construct using pip:\n\n```bash\npip install token-injectable-docker-builder\n```\n\n---\n\n## Constructor\n\n### `TokenInjectableDockerBuilder`\n\n#### Parameters\n\n- **`scope`**: The construct's parent scope.\n- **`id`**: The construct ID.\n- **`props`**: Configuration properties.\n\n#### Properties in `TokenInjectableDockerBuilderProps`\n\n| Property | Type | Required | Description |\n|------------------------|--------------------|----------|-------------------------------------------------------------------------------------------------------|\n| `path` | `string` | Yes | The file path to the Dockerfile or source code directory. |\n| `buildArgs` | `{ [key: string]: string }` | No | Build arguments to pass to the Docker build process. |\n| `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |\n\n---\n\n## Usage Examples\n\n### TypeScript/NPM Example\n\nHere is how to use `TokenInjectableDockerBuilder` in an AWS CDK project with TypeScript:\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';\nimport * as ecs from 'aws-cdk-lib/aws-ecs';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\n\nexport class MyStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: './docker',\n buildArgs: {\n TOKEN: 'my-secret-token',\n ENV: 'production',\n },\n dockerLoginSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret',\n });\n\n // Use in ECS\n new ecs.FargateTaskDefinition(this, 'TaskDefinition', {\n containerImage: dockerBuilder.containerImage,\n });\n\n // Use in Lambda\n new lambda.Function(this, 'DockerLambdaFunction', {\n runtime: lambda.Runtime.FROM_IMAGE,\n code: dockerBuilder.dockerImageCode,\n handler: lambda.Handler.FROM_IMAGE,\n });\n }\n}\n```\n\n---\n\n### Python Example\n\nHere is how to use `TokenInjectableDockerBuilder` in an AWS CDK project with Python:\n\n```python\nfrom aws_cdk import core as cdk\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\nfrom aws_cdk import aws_ecs as ecs\nfrom aws_cdk import aws_lambda as lambda_\n\nclass MyStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n docker_builder = TokenInjectableDockerBuilder(self, \"MyDockerBuilder\",\n path=\"./docker\",\n build_args={\n \"TOKEN\": \"my-secret-token\",\n \"ENV\": \"production\"\n },\n docker_login_secret_arn=\"arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret\"\n )\n\n # Use in ECS\n ecs.FargateTaskDefinition(self, \"TaskDefinition\",\n container_image=docker_builder.container_image\n )\n\n # Use in Lambda\n lambda_.Function(self, \"DockerLambdaFunction\",\n runtime=lambda_.Runtime.FROM_IMAGE,\n code=docker_builder.docker_image_code,\n handler=lambda_.Handler.FROM_IMAGE\n )\n```\n\n---\n\n## How It Works\n\n1. **Docker Source**: Packages the source code or Dockerfile specified in the `path` property as an S3 asset.\n2. **CodeBuild Project**:\n - Uses the packaged asset and `buildArgs` to build the Docker image.\n - Pushes the image to an ECR repository.\n3. **Custom Resource**:\n - Triggers the build process using a Lambda function (`onEvent`).\n - Monitors the build status using another Lambda function (`isComplete`).\n4. **Outputs**:\n - `.containerImage`: Returns the Docker image for ECS.\n - `.dockerImageCode`: Returns the Docker image code for Lambda.\n\n---\n\n## IAM Permissions\n\nThe construct automatically grants permissions for:\n- CodeBuild to pull and push images to ECR.\n- Lambda to monitor build status and retrieve logs.\n- Encryption via a custom KMS key.\n\n---\n\n## Notes\n\n- **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags.\n- **ECR Repository**: Automatically creates an ECR repository with lifecycle rules.\n- **Custom Resources**: Manages lifecycle events for builds using custom Lambda handlers.\n\n---\n\n## Troubleshooting\n\n1. **Build Errors**: Check CodeBuild logs in CloudWatch.\n2. **Lambda Errors**: Check `onEvent` and `isComplete` Lambda logs in CloudWatch.\n3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, and Secrets Manager.\n\n---\n\n## Support\n\nOpen an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).\n\n---\n\n## Reference Links\n[](https://constructs.dev/packages/token-injectable-docker-builder)\n"
|
|
3901
|
+
"markdown": "# TokenInjectableDockerBuilder\n\nThe `TokenInjectableDockerBuilder` is a flexible AWS CDK construct that enables the usage of AWS CDK tokens in the building, pushing, and deployment of Docker images to Amazon Elastic Container Registry (ECR). It leverages AWS CodeBuild and Lambda custom resources.\n\n---\n\n## Why?\n\nAWS CDK already provides mechanisms for creating deployable assets using Docker, such as [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerImageAsset.html) and [DockerImageCode](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.DockerImageCode.html), but these constructs are limited because they cannot accept CDK tokens as build-args. The `TokenInjectableDockerBuilder` allows injecting CDK tokens as build-time arguments into Docker-based assets, enabling more dynamic dependency relationships.\n\nFor example, a Next.js frontend Docker image may require an API Gateway URL as an argument. With this construct, you can deploy the API Gateway first, then pass its URL as a build-time argument to the Next.js Docker image. As a result, your Next.js frontend can dynamically fetch data from the API Gateway without hardcoding the URL, or needing mutliple sepereate Stacks.\n\n---\n\n## Features\n\n- **Build and Push Docker Images**: Automatically builds and pushes Docker images to ECR.\n- **Token Support**: Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.\n- **Custom Install and Pre-Build Commands**: Allows specifying custom commands to run during the `install` and `pre_build` phases of the CodeBuild build process.\n- **VPC Configuration**: Supports deploying the CodeBuild project within a VPC, with customizable security groups and subnet selection.\n- **Docker Login**: Supports Docker login using credentials stored in AWS Secrets Manager.\n- **ECR Repository Management**: Creates an ECR repository with lifecycle rules and encryption.\n- **Integration with ECS and Lambda**: Provides outputs for use in AWS ECS and AWS Lambda.\n\n---\n\n## Installation\n\n### For NPM\n\nInstall the construct using NPM:\n\n```bash\nnpm install token-injectable-docker-builder\n```\n\n### For Python\n\nInstall the construct using pip:\n\n```bash\npip install token-injectable-docker-builder\n```\n\n---\n\n## Constructor\n\n### `TokenInjectableDockerBuilder`\n\n#### Parameters\n\n- **`scope`**: The construct's parent scope.\n- **`id`**: The construct ID.\n- **`props`**: Configuration properties.\n\n#### Properties in `TokenInjectableDockerBuilderProps`\n\n| Property | Type | Required | Description |\n|--------------------------|-----------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `path` | `string` | Yes | The file path to the Dockerfile or source code directory. |\n| `buildArgs` | `{ [key: string]: string }` | No | Build arguments to pass to the Docker build process. These are transformed into `--build-arg` flags. |\n| `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |\n| `vpc` | `IVpc` | No | The VPC in which the CodeBuild project will be deployed. If provided, the CodeBuild project will be launched within the specified VPC. |\n| `securityGroups` | `ISecurityGroup[]` | No | The security groups to attach to the CodeBuild project. These should define the network access rules for the CodeBuild project. |\n| `subnetSelection` | `SubnetSelection` | No | The subnet selection to specify which subnets to use within the VPC. Allows the user to select private, public, or isolated subnets. |\n| `installCommands` | `string[]` | No | Custom commands to run during the `install` phase of the CodeBuild build process. |\n| `preBuildCommands` | `string[]` | No | Custom commands to run during the `pre_build` phase of the CodeBuild build process. |\n\n---\n\n## Usage Examples\n\n### Simple Usage Example\n\nThis example demonstrates the most basic usage of the `TokenInjectableDockerBuilder`, where you specify the path to your Docker context and provide simple build arguments.\n\n#### TypeScript/NPM Example\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';\nimport * as ecs from 'aws-cdk-lib/aws-ecs';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\n\nexport class SimpleStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'SimpleDockerBuilder', {\n path: './docker', // Path to your Dockerfile or Docker context\n buildArgs: {\n ENV: 'production', // Simple build argument\n },\n });\n\n // Use in ECS\n new ecs.ContainerDefinition(this, 'SimpleContainer', {\n image: dockerBuilder.containerImage,\n // ... other container properties ...\n });\n\n // Use in Lambda\n new lambda.Function(this, 'SimpleDockerLambdaFunction', {\n runtime: lambda.Runtime.FROM_IMAGE,\n code: dockerBuilder.dockerImageCode,\n handler: lambda.Handler.FROM_IMAGE,\n });\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ecs as ecs,\n aws_lambda as lambda_,\n core as cdk,\n)\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\n\nclass SimpleStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n docker_builder = TokenInjectableDockerBuilder(self, \"SimpleDockerBuilder\",\n path=\"./docker\", # Path to your Dockerfile or Docker context\n build_args={\n \"ENV\": \"production\", # Simple build argument\n },\n )\n\n # Use in ECS\n ecs.ContainerDefinition(self, \"SimpleContainer\",\n image=docker_builder.container_image,\n # ... other container properties ...\n )\n\n # Use in Lambda\n lambda_.Function(self, \"SimpleDockerLambdaFunction\",\n runtime=lambda_.Runtime.FROM_IMAGE,\n code=docker_builder.docker_image_code,\n handler=lambda_.Handler.FROM_IMAGE\n )\n```\n\n---\n\n### Advanced Usage Example\n\nThis example demonstrates more advanced usage, including using CDK tokens as build arguments, specifying custom install and pre-build commands, and configuring VPC settings.\n\n#### TypeScript/NPM Example\n\n```typescript\nimport * as cdk from 'aws-cdk-lib';\nimport { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';\nimport * as ecs from 'aws-cdk-lib/aws-ecs';\nimport * as lambda from 'aws-cdk-lib/aws-lambda';\nimport * as ec2 from 'aws-cdk-lib/aws-ec2';\n\nexport class MyStack extends cdk.Stack {\n constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n super(scope, id, props);\n\n // Example VPC and security group (optional)\n const vpc = new ec2.Vpc(this, 'MyVpc');\n const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', {\n vpc,\n });\n\n // Example of using CDK tokens as build arguments\n const myApiGateway = /* ... create or import your API Gateway ... */;\n\n const dockerBuilder = new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: './docker',\n buildArgs: {\n API_URL: myApiGateway.url, // Using CDK token\n ENV: 'production',\n },\n dockerLoginSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret',\n vpc,\n securityGroups: [securityGroup],\n subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },\n installCommands: [\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing required packages...\"',\n 'apt-get install -y curl dnsutils',\n ],\n preBuildCommands: [\n 'echo \"Fetching configuration from private API...\"',\n 'curl -o config.json https://api.example.com/config',\n ],\n });\n\n // Use in ECS\n new ecs.ContainerDefinition(this, 'MyContainer', {\n image: dockerBuilder.containerImage,\n // ... other container properties ...\n });\n\n // Use in Lambda\n new lambda.Function(this, 'DockerLambdaFunction', {\n runtime: lambda.Runtime.FROM_IMAGE,\n code: dockerBuilder.dockerImageCode,\n handler: lambda.Handler.FROM_IMAGE,\n });\n }\n}\n```\n\n#### Python Example\n\n```python\nfrom aws_cdk import (\n aws_ec2 as ec2,\n aws_ecs as ecs,\n aws_lambda as lambda_,\n core as cdk,\n)\nfrom token_injectable_docker_builder import TokenInjectableDockerBuilder\n\nclass MyStack(cdk.Stack):\n\n def __init__(self, scope: cdk.App, id: str, **kwargs):\n super().__init__(scope, id, **kwargs)\n\n # Example VPC and security group (optional)\n vpc = ec2.Vpc(self, \"MyVpc\")\n security_group = ec2.SecurityGroup(self, \"MySecurityGroup\", vpc=vpc)\n\n # Example of using CDK tokens as build arguments\n my_api_gateway = # ... create or import your API Gateway ...\n\n docker_builder = TokenInjectableDockerBuilder(self, \"MyDockerBuilder\",\n path=\"./docker\",\n build_args={\n \"API_URL\": my_api_gateway.url, # Using CDK token\n \"ENV\": \"production\"\n },\n docker_login_secret_arn=\"arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret\",\n vpc=vpc,\n security_groups=[security_group],\n subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS),\n install_commands=[\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing required packages...\"',\n 'apt-get install -y curl dnsutils',\n ],\n pre_build_commands=[\n 'echo \"Fetching configuration from private API...\"',\n 'curl -o config.json https://api.example.com/config',\n ],\n )\n\n # Use in ECS\n ecs.ContainerDefinition(self, \"MyContainer\",\n image=docker_builder.container_image,\n # ... other container properties ...\n )\n\n # Use in Lambda\n lambda_.Function(self, \"DockerLambdaFunction\",\n runtime=lambda_.Runtime.FROM_IMAGE,\n code=docker_builder.docker_image_code,\n handler=lambda_.Handler.FROM_IMAGE\n )\n```\n\n---\n\n## How It Works\n\n1. **Docker Source**: Packages the source code or Dockerfile specified in the `path` property as an S3 asset.\n2. **CodeBuild Project**:\n - Uses the packaged asset and `buildArgs` to build the Docker image.\n - Executes any custom `installCommands` and `preBuildCommands` during the build process.\n - Pushes the image to an ECR repository.\n3. **Custom Resource**:\n - Triggers the build process using a Lambda function (`onEvent`).\n - Monitors the build status using another Lambda function (`isComplete`).\n4. **Outputs**:\n - `.containerImage`: Returns the Docker image for ECS.\n - `.dockerImageCode`: Returns the Docker image code for Lambda.\n\n---\n\n## IAM Permissions\n\nThe construct automatically grants permissions for:\n\n- **CodeBuild**:\n - Pull and push images to ECR.\n - Access to AWS Secrets Manager if `dockerLoginSecretArn` is provided.\n - Access to the KMS key for encryption.\n- **Lambda Functions**:\n - Start and monitor CodeBuild builds.\n - Access CloudWatch Logs.\n - Access to the KMS key for encryption.\n - Pull and push images to ECR.\n\n---\n\n## Notes\n\n- **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags. CDK tokens can be used to inject dynamic values resolved at deployment time.\n- **Custom Commands**: Use `installCommands` and `preBuildCommands` to run custom shell commands during the build process. This can be useful for installing dependencies or fetching configuration files.\n- **VPC Configuration**: If your build process requires access to resources within a VPC, you can specify the VPC, security groups, and subnet selection.\n- **Docker Login**: If you need to log in to a private Docker registry before building the image, provide the ARN of a secret in AWS Secrets Manager containing the Docker credentials.\n- **ECR Repository**: Automatically creates an ECR repository with lifecycle rules to manage image retention, encryption with a KMS key, and image scanning on push.\n\n---\n\n## Troubleshooting\n\n1. **Build Errors**: Check the CodeBuild logs in CloudWatch Logs for detailed error messages.\n2. **Lambda Errors**: Check the `onEvent` and `isComplete` Lambda function logs in CloudWatch Logs.\n3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, Secrets Manager, and KMS if applicable.\n4. **Network Access**: If the build requires network access (e.g., to download dependencies), ensure that the VPC configuration allows outbound internet access, or use a NAT gateway if in private subnets.\n\n---\n\n## Support\n\nFor issues or feature requests, please open an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).\n\n---\n\n## Reference Links\n\n[](https://constructs.dev/packages/token-injectable-docker-builder)\n\n---\n\n# License\n\nThis project is licensed under the terms of the MIT license.\n\n---\n\n# Acknowledgements\n\n- Inspired by the need for more dynamic Docker asset management in AWS CDK.\n- Thanks to the AWS CDK community for their continuous support and contributions.\n\n---\n\nFeel free to reach out if you have any questions or need further assistance!"
|
|
3902
3902
|
},
|
|
3903
3903
|
"repository": {
|
|
3904
3904
|
"type": "git",
|
|
@@ -3929,7 +3929,7 @@
|
|
|
3929
3929
|
},
|
|
3930
3930
|
"locationInModule": {
|
|
3931
3931
|
"filename": "src/index.ts",
|
|
3932
|
-
"line":
|
|
3932
|
+
"line": 123
|
|
3933
3933
|
},
|
|
3934
3934
|
"parameters": [
|
|
3935
3935
|
{
|
|
@@ -3955,7 +3955,7 @@
|
|
|
3955
3955
|
"kind": "class",
|
|
3956
3956
|
"locationInModule": {
|
|
3957
3957
|
"filename": "src/index.ts",
|
|
3958
|
-
"line":
|
|
3958
|
+
"line": 118
|
|
3959
3959
|
},
|
|
3960
3960
|
"name": "TokenInjectableDockerBuilder",
|
|
3961
3961
|
"properties": [
|
|
@@ -3966,7 +3966,7 @@
|
|
|
3966
3966
|
"immutable": true,
|
|
3967
3967
|
"locationInModule": {
|
|
3968
3968
|
"filename": "src/index.ts",
|
|
3969
|
-
"line":
|
|
3969
|
+
"line": 120
|
|
3970
3970
|
},
|
|
3971
3971
|
"name": "containerImage",
|
|
3972
3972
|
"type": {
|
|
@@ -3980,7 +3980,7 @@
|
|
|
3980
3980
|
"immutable": true,
|
|
3981
3981
|
"locationInModule": {
|
|
3982
3982
|
"filename": "src/index.ts",
|
|
3983
|
-
"line":
|
|
3983
|
+
"line": 121
|
|
3984
3984
|
},
|
|
3985
3985
|
"name": "dockerImageCode",
|
|
3986
3986
|
"type": {
|
|
@@ -4001,7 +4001,7 @@
|
|
|
4001
4001
|
"kind": "interface",
|
|
4002
4002
|
"locationInModule": {
|
|
4003
4003
|
"filename": "src/index.ts",
|
|
4004
|
-
"line":
|
|
4004
|
+
"line": 18
|
|
4005
4005
|
},
|
|
4006
4006
|
"name": "TokenInjectableDockerBuilderProps",
|
|
4007
4007
|
"properties": [
|
|
@@ -4014,7 +4014,7 @@
|
|
|
4014
4014
|
"immutable": true,
|
|
4015
4015
|
"locationInModule": {
|
|
4016
4016
|
"filename": "src/index.ts",
|
|
4017
|
-
"line":
|
|
4017
|
+
"line": 22
|
|
4018
4018
|
},
|
|
4019
4019
|
"name": "path",
|
|
4020
4020
|
"type": {
|
|
@@ -4032,7 +4032,7 @@
|
|
|
4032
4032
|
"immutable": true,
|
|
4033
4033
|
"locationInModule": {
|
|
4034
4034
|
"filename": "src/index.ts",
|
|
4035
|
-
"line":
|
|
4035
|
+
"line": 33
|
|
4036
4036
|
},
|
|
4037
4037
|
"name": "buildArgs",
|
|
4038
4038
|
"optional": true,
|
|
@@ -4056,18 +4056,128 @@
|
|
|
4056
4056
|
"immutable": true,
|
|
4057
4057
|
"locationInModule": {
|
|
4058
4058
|
"filename": "src/index.ts",
|
|
4059
|
-
"line":
|
|
4059
|
+
"line": 48
|
|
4060
4060
|
},
|
|
4061
4061
|
"name": "dockerLoginSecretArn",
|
|
4062
4062
|
"optional": true,
|
|
4063
4063
|
"type": {
|
|
4064
4064
|
"primitive": "string"
|
|
4065
4065
|
}
|
|
4066
|
+
},
|
|
4067
|
+
{
|
|
4068
|
+
"abstract": true,
|
|
4069
|
+
"docs": {
|
|
4070
|
+
"default": "- No additional install commands.",
|
|
4071
|
+
"remarks": "**Example Usage:**\n```typescript\nnew TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: path.resolve(__dirname, '../app'),\n installCommands: [\n 'echo \"Updating package lists...\"',\n 'apt-get update -y',\n 'echo \"Installing required packages...\"',\n 'apt-get install -y curl dnsutils',\n ],\n // ... other properties ...\n});\n```\n*This example demonstrates how to install the `curl` and `dnsutils` packages during the install phase using `apt-get`, the package manager for Ubuntu-based CodeBuild environments.*",
|
|
4072
|
+
"stability": "stable",
|
|
4073
|
+
"summary": "Custom commands to run during the install phase."
|
|
4074
|
+
},
|
|
4075
|
+
"immutable": true,
|
|
4076
|
+
"locationInModule": {
|
|
4077
|
+
"filename": "src/index.ts",
|
|
4078
|
+
"line": 91
|
|
4079
|
+
},
|
|
4080
|
+
"name": "installCommands",
|
|
4081
|
+
"optional": true,
|
|
4082
|
+
"type": {
|
|
4083
|
+
"collection": {
|
|
4084
|
+
"elementtype": {
|
|
4085
|
+
"primitive": "string"
|
|
4086
|
+
},
|
|
4087
|
+
"kind": "array"
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
},
|
|
4091
|
+
{
|
|
4092
|
+
"abstract": true,
|
|
4093
|
+
"docs": {
|
|
4094
|
+
"default": "- No additional pre-build commands.",
|
|
4095
|
+
"remarks": "**Example Usage:**\n```typescript\nnew TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {\n path: path.resolve(__dirname, '../app'),\n preBuildCommands: [\n 'echo \"Fetching configuration from private API...\"',\n 'curl -o config.json https://api.example.com/config',\n ],\n // ... other properties ...\n});\n```\n*In this example, the builder fetches a configuration file from a private API before starting the Docker build. This config file will be available in the same directory as your Dockerfile during CDK deployment.*",
|
|
4096
|
+
"stability": "stable",
|
|
4097
|
+
"summary": "Custom commands to run during the pre_build phase."
|
|
4098
|
+
},
|
|
4099
|
+
"immutable": true,
|
|
4100
|
+
"locationInModule": {
|
|
4101
|
+
"filename": "src/index.ts",
|
|
4102
|
+
"line": 112
|
|
4103
|
+
},
|
|
4104
|
+
"name": "preBuildCommands",
|
|
4105
|
+
"optional": true,
|
|
4106
|
+
"type": {
|
|
4107
|
+
"collection": {
|
|
4108
|
+
"elementtype": {
|
|
4109
|
+
"primitive": "string"
|
|
4110
|
+
},
|
|
4111
|
+
"kind": "array"
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
4114
|
+
},
|
|
4115
|
+
{
|
|
4116
|
+
"abstract": true,
|
|
4117
|
+
"docs": {
|
|
4118
|
+
"default": "No security groups are attached.",
|
|
4119
|
+
"remarks": "These should define the network access rules for the CodeBuild project.",
|
|
4120
|
+
"stability": "stable",
|
|
4121
|
+
"summary": "The security groups to attach to the CodeBuild project."
|
|
4122
|
+
},
|
|
4123
|
+
"immutable": true,
|
|
4124
|
+
"locationInModule": {
|
|
4125
|
+
"filename": "src/index.ts",
|
|
4126
|
+
"line": 62
|
|
4127
|
+
},
|
|
4128
|
+
"name": "securityGroups",
|
|
4129
|
+
"optional": true,
|
|
4130
|
+
"type": {
|
|
4131
|
+
"collection": {
|
|
4132
|
+
"elementtype": {
|
|
4133
|
+
"fqn": "aws-cdk-lib.aws_ec2.ISecurityGroup"
|
|
4134
|
+
},
|
|
4135
|
+
"kind": "array"
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
},
|
|
4139
|
+
{
|
|
4140
|
+
"abstract": true,
|
|
4141
|
+
"docs": {
|
|
4142
|
+
"default": "All subnets in the VPC are used.",
|
|
4143
|
+
"remarks": "Allows the user to select private, public, or isolated subnets.",
|
|
4144
|
+
"stability": "stable",
|
|
4145
|
+
"summary": "The subnet selection to specify which subnets to use within the VPC."
|
|
4146
|
+
},
|
|
4147
|
+
"immutable": true,
|
|
4148
|
+
"locationInModule": {
|
|
4149
|
+
"filename": "src/index.ts",
|
|
4150
|
+
"line": 69
|
|
4151
|
+
},
|
|
4152
|
+
"name": "subnetSelection",
|
|
4153
|
+
"optional": true,
|
|
4154
|
+
"type": {
|
|
4155
|
+
"fqn": "aws-cdk-lib.aws_ec2.SubnetSelection"
|
|
4156
|
+
}
|
|
4157
|
+
},
|
|
4158
|
+
{
|
|
4159
|
+
"abstract": true,
|
|
4160
|
+
"docs": {
|
|
4161
|
+
"default": "No VPC is attached, and the CodeBuild project will use public internet.",
|
|
4162
|
+
"remarks": "If provided, the CodeBuild project will be launched within the specified VPC.",
|
|
4163
|
+
"stability": "stable",
|
|
4164
|
+
"summary": "The VPC in which the CodeBuild project will be deployed."
|
|
4165
|
+
},
|
|
4166
|
+
"immutable": true,
|
|
4167
|
+
"locationInModule": {
|
|
4168
|
+
"filename": "src/index.ts",
|
|
4169
|
+
"line": 55
|
|
4170
|
+
},
|
|
4171
|
+
"name": "vpc",
|
|
4172
|
+
"optional": true,
|
|
4173
|
+
"type": {
|
|
4174
|
+
"fqn": "aws-cdk-lib.aws_ec2.IVpc"
|
|
4175
|
+
}
|
|
4066
4176
|
}
|
|
4067
4177
|
],
|
|
4068
4178
|
"symbolId": "src/index:TokenInjectableDockerBuilderProps"
|
|
4069
4179
|
}
|
|
4070
4180
|
},
|
|
4071
|
-
"version": "1.
|
|
4072
|
-
"fingerprint": "
|
|
4181
|
+
"version": "1.2.0",
|
|
4182
|
+
"fingerprint": "TmxNeVUcLCoAgBQ00ly9fitXZzX7XszZMTsXOXhhKo4="
|
|
4073
4183
|
}
|
package/API.md
CHANGED
|
@@ -146,6 +146,11 @@ const tokenInjectableDockerBuilderProps: TokenInjectableDockerBuilderProps = { .
|
|
|
146
146
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.path">path</a></code> | <code>string</code> | The path to the directory containing the Dockerfile or source code. |
|
|
147
147
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.buildArgs">buildArgs</a></code> | <code>{[ key: string ]: string}</code> | Build arguments to pass to the Docker build process. |
|
|
148
148
|
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.dockerLoginSecretArn">dockerLoginSecretArn</a></code> | <code>string</code> | The ARN of the AWS Secrets Manager secret containing Docker login credentials. |
|
|
149
|
+
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.installCommands">installCommands</a></code> | <code>string[]</code> | Custom commands to run during the install phase. |
|
|
150
|
+
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.preBuildCommands">preBuildCommands</a></code> | <code>string[]</code> | Custom commands to run during the pre_build phase. |
|
|
151
|
+
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.securityGroups">securityGroups</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup[]</code> | The security groups to attach to the CodeBuild project. |
|
|
152
|
+
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.subnetSelection">subnetSelection</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | The subnet selection to specify which subnets to use within the VPC. |
|
|
153
|
+
| <code><a href="#token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.vpc">vpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | The VPC in which the CodeBuild project will be deployed. |
|
|
149
154
|
|
|
150
155
|
---
|
|
151
156
|
|
|
@@ -213,5 +218,104 @@ If not provided, the construct will skip Docker login during the build process.
|
|
|
213
218
|
```
|
|
214
219
|
|
|
215
220
|
|
|
221
|
+
##### `installCommands`<sup>Optional</sup> <a name="installCommands" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.installCommands"></a>
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
public readonly installCommands: string[];
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
- *Type:* string[]
|
|
228
|
+
- *Default:* No additional install commands.
|
|
229
|
+
|
|
230
|
+
Custom commands to run during the install phase.
|
|
231
|
+
|
|
232
|
+
**Example Usage:**
|
|
233
|
+
```typescript
|
|
234
|
+
new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
|
|
235
|
+
path: path.resolve(__dirname, '../app'),
|
|
236
|
+
installCommands: [
|
|
237
|
+
'echo "Updating package lists..."',
|
|
238
|
+
'apt-get update -y',
|
|
239
|
+
'echo "Installing required packages..."',
|
|
240
|
+
'apt-get install -y curl dnsutils',
|
|
241
|
+
],
|
|
242
|
+
// ... other properties ...
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
*This example demonstrates how to install the `curl` and `dnsutils` packages during the install phase using `apt-get`, the package manager for Ubuntu-based CodeBuild environments.*
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
##### `preBuildCommands`<sup>Optional</sup> <a name="preBuildCommands" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.preBuildCommands"></a>
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
public readonly preBuildCommands: string[];
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
- *Type:* string[]
|
|
256
|
+
- *Default:* No additional pre-build commands.
|
|
257
|
+
|
|
258
|
+
Custom commands to run during the pre_build phase.
|
|
259
|
+
|
|
260
|
+
**Example Usage:**
|
|
261
|
+
```typescript
|
|
262
|
+
new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
|
|
263
|
+
path: path.resolve(__dirname, '../app'),
|
|
264
|
+
preBuildCommands: [
|
|
265
|
+
'echo "Fetching configuration from private API..."',
|
|
266
|
+
'curl -o config.json https://api.example.com/config',
|
|
267
|
+
],
|
|
268
|
+
// ... other properties ...
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
*In this example, the builder fetches a configuration file from a private API before starting the Docker build. This config file will be available in the same directory as your Dockerfile during CDK deployment.*
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
##### `securityGroups`<sup>Optional</sup> <a name="securityGroups" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.securityGroups"></a>
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
public readonly securityGroups: ISecurityGroup[];
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[]
|
|
282
|
+
- *Default:* No security groups are attached.
|
|
283
|
+
|
|
284
|
+
The security groups to attach to the CodeBuild project.
|
|
285
|
+
|
|
286
|
+
These should define the network access rules for the CodeBuild project.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
##### `subnetSelection`<sup>Optional</sup> <a name="subnetSelection" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.subnetSelection"></a>
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
public readonly subnetSelection: SubnetSelection;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
- *Type:* aws-cdk-lib.aws_ec2.SubnetSelection
|
|
297
|
+
- *Default:* All subnets in the VPC are used.
|
|
298
|
+
|
|
299
|
+
The subnet selection to specify which subnets to use within the VPC.
|
|
300
|
+
|
|
301
|
+
Allows the user to select private, public, or isolated subnets.
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
##### `vpc`<sup>Optional</sup> <a name="vpc" id="token-injectable-docker-builder.TokenInjectableDockerBuilderProps.property.vpc"></a>
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
public readonly vpc: IVpc;
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
- *Type:* aws-cdk-lib.aws_ec2.IVpc
|
|
312
|
+
- *Default:* No VPC is attached, and the CodeBuild project will use public internet.
|
|
313
|
+
|
|
314
|
+
The VPC in which the CodeBuild project will be deployed.
|
|
315
|
+
|
|
316
|
+
If provided, the CodeBuild project will be launched within the specified VPC.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
216
320
|
|
|
217
321
|
|
package/README.md
CHANGED
|
@@ -6,17 +6,21 @@ The `TokenInjectableDockerBuilder` is a flexible AWS CDK construct that enables
|
|
|
6
6
|
|
|
7
7
|
## Why?
|
|
8
8
|
|
|
9
|
-
AWS CDK already provides mechanisms for creating deployable assets using Docker, such as [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerImageAsset.html) and [DockerImageCode](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.DockerImageCode.html), but these
|
|
9
|
+
AWS CDK already provides mechanisms for creating deployable assets using Docker, such as [DockerImageAsset](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets.DockerImageAsset.html) and [DockerImageCode](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.DockerImageCode.html), but these constructs are limited because they cannot accept CDK tokens as build-args. The `TokenInjectableDockerBuilder` allows injecting CDK tokens as build-time arguments into Docker-based assets, enabling more dynamic dependency relationships.
|
|
10
10
|
|
|
11
|
-
For example, a Next.js frontend Docker image may require an API Gateway URL. With this construct, you can deploy the API Gateway first, then pass its URL as a build-time argument to the Next.js Docker image.
|
|
11
|
+
For example, a Next.js frontend Docker image may require an API Gateway URL as an argument. With this construct, you can deploy the API Gateway first, then pass its URL as a build-time argument to the Next.js Docker image. As a result, your Next.js frontend can dynamically fetch data from the API Gateway without hardcoding the URL, or needing mutliple sepereate Stacks.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
|
-
- Automatically builds and pushes Docker images to ECR.
|
|
18
|
-
- Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.
|
|
19
|
-
-
|
|
17
|
+
- **Build and Push Docker Images**: Automatically builds and pushes Docker images to ECR.
|
|
18
|
+
- **Token Support**: Supports custom build arguments for Docker builds, including CDK tokens resolved at deployment time.
|
|
19
|
+
- **Custom Install and Pre-Build Commands**: Allows specifying custom commands to run during the `install` and `pre_build` phases of the CodeBuild build process.
|
|
20
|
+
- **VPC Configuration**: Supports deploying the CodeBuild project within a VPC, with customizable security groups and subnet selection.
|
|
21
|
+
- **Docker Login**: Supports Docker login using credentials stored in AWS Secrets Manager.
|
|
22
|
+
- **ECR Repository Management**: Creates an ECR repository with lifecycle rules and encryption.
|
|
23
|
+
- **Integration with ECS and Lambda**: Provides outputs for use in AWS ECS and AWS Lambda.
|
|
20
24
|
|
|
21
25
|
---
|
|
22
26
|
|
|
@@ -52,42 +56,150 @@ pip install token-injectable-docker-builder
|
|
|
52
56
|
|
|
53
57
|
#### Properties in `TokenInjectableDockerBuilderProps`
|
|
54
58
|
|
|
55
|
-
| Property
|
|
56
|
-
|
|
57
|
-
| `path`
|
|
58
|
-
| `buildArgs`
|
|
59
|
-
| `dockerLoginSecretArn`
|
|
59
|
+
| Property | Type | Required | Description |
|
|
60
|
+
|--------------------------|-----------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
61
|
+
| `path` | `string` | Yes | The file path to the Dockerfile or source code directory. |
|
|
62
|
+
| `buildArgs` | `{ [key: string]: string }` | No | Build arguments to pass to the Docker build process. These are transformed into `--build-arg` flags. |
|
|
63
|
+
| `dockerLoginSecretArn` | `string` | No | ARN of an AWS Secrets Manager secret for Docker credentials. Skips login if not provided. |
|
|
64
|
+
| `vpc` | `IVpc` | No | The VPC in which the CodeBuild project will be deployed. If provided, the CodeBuild project will be launched within the specified VPC. |
|
|
65
|
+
| `securityGroups` | `ISecurityGroup[]` | No | The security groups to attach to the CodeBuild project. These should define the network access rules for the CodeBuild project. |
|
|
66
|
+
| `subnetSelection` | `SubnetSelection` | No | The subnet selection to specify which subnets to use within the VPC. Allows the user to select private, public, or isolated subnets. |
|
|
67
|
+
| `installCommands` | `string[]` | No | Custom commands to run during the `install` phase of the CodeBuild build process. |
|
|
68
|
+
| `preBuildCommands` | `string[]` | No | Custom commands to run during the `pre_build` phase of the CodeBuild build process. |
|
|
60
69
|
|
|
61
70
|
---
|
|
62
71
|
|
|
63
72
|
## Usage Examples
|
|
64
73
|
|
|
65
|
-
###
|
|
74
|
+
### Simple Usage Example
|
|
66
75
|
|
|
67
|
-
|
|
76
|
+
This example demonstrates the most basic usage of the `TokenInjectableDockerBuilder`, where you specify the path to your Docker context and provide simple build arguments.
|
|
77
|
+
|
|
78
|
+
#### TypeScript/NPM Example
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import * as cdk from 'aws-cdk-lib';
|
|
82
|
+
import { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';
|
|
83
|
+
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
84
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
85
|
+
|
|
86
|
+
export class SimpleStack extends cdk.Stack {
|
|
87
|
+
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
|
|
88
|
+
super(scope, id, props);
|
|
89
|
+
|
|
90
|
+
const dockerBuilder = new TokenInjectableDockerBuilder(this, 'SimpleDockerBuilder', {
|
|
91
|
+
path: './docker', // Path to your Dockerfile or Docker context
|
|
92
|
+
buildArgs: {
|
|
93
|
+
ENV: 'production', // Simple build argument
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Use in ECS
|
|
98
|
+
new ecs.ContainerDefinition(this, 'SimpleContainer', {
|
|
99
|
+
image: dockerBuilder.containerImage,
|
|
100
|
+
// ... other container properties ...
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Use in Lambda
|
|
104
|
+
new lambda.Function(this, 'SimpleDockerLambdaFunction', {
|
|
105
|
+
runtime: lambda.Runtime.FROM_IMAGE,
|
|
106
|
+
code: dockerBuilder.dockerImageCode,
|
|
107
|
+
handler: lambda.Handler.FROM_IMAGE,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Python Example
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from aws_cdk import (
|
|
117
|
+
aws_ecs as ecs,
|
|
118
|
+
aws_lambda as lambda_,
|
|
119
|
+
core as cdk,
|
|
120
|
+
)
|
|
121
|
+
from token_injectable_docker_builder import TokenInjectableDockerBuilder
|
|
122
|
+
|
|
123
|
+
class SimpleStack(cdk.Stack):
|
|
124
|
+
|
|
125
|
+
def __init__(self, scope: cdk.App, id: str, **kwargs):
|
|
126
|
+
super().__init__(scope, id, **kwargs)
|
|
127
|
+
|
|
128
|
+
docker_builder = TokenInjectableDockerBuilder(self, "SimpleDockerBuilder",
|
|
129
|
+
path="./docker", # Path to your Dockerfile or Docker context
|
|
130
|
+
build_args={
|
|
131
|
+
"ENV": "production", # Simple build argument
|
|
132
|
+
},
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Use in ECS
|
|
136
|
+
ecs.ContainerDefinition(self, "SimpleContainer",
|
|
137
|
+
image=docker_builder.container_image,
|
|
138
|
+
# ... other container properties ...
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Use in Lambda
|
|
142
|
+
lambda_.Function(self, "SimpleDockerLambdaFunction",
|
|
143
|
+
runtime=lambda_.Runtime.FROM_IMAGE,
|
|
144
|
+
code=docker_builder.docker_image_code,
|
|
145
|
+
handler=lambda_.Handler.FROM_IMAGE
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### Advanced Usage Example
|
|
152
|
+
|
|
153
|
+
This example demonstrates more advanced usage, including using CDK tokens as build arguments, specifying custom install and pre-build commands, and configuring VPC settings.
|
|
154
|
+
|
|
155
|
+
#### TypeScript/NPM Example
|
|
68
156
|
|
|
69
157
|
```typescript
|
|
70
158
|
import * as cdk from 'aws-cdk-lib';
|
|
71
159
|
import { TokenInjectableDockerBuilder } from 'token-injectable-docker-builder';
|
|
72
160
|
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
73
161
|
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
162
|
+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
74
163
|
|
|
75
164
|
export class MyStack extends cdk.Stack {
|
|
76
165
|
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
|
|
77
166
|
super(scope, id, props);
|
|
78
167
|
|
|
168
|
+
// Example VPC and security group (optional)
|
|
169
|
+
const vpc = new ec2.Vpc(this, 'MyVpc');
|
|
170
|
+
const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', {
|
|
171
|
+
vpc,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// Example of using CDK tokens as build arguments
|
|
175
|
+
const myApiGateway = /* ... create or import your API Gateway ... */;
|
|
176
|
+
|
|
79
177
|
const dockerBuilder = new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
|
|
80
178
|
path: './docker',
|
|
81
179
|
buildArgs: {
|
|
82
|
-
|
|
180
|
+
API_URL: myApiGateway.url, // Using CDK token
|
|
83
181
|
ENV: 'production',
|
|
84
182
|
},
|
|
85
183
|
dockerLoginSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret',
|
|
184
|
+
vpc,
|
|
185
|
+
securityGroups: [securityGroup],
|
|
186
|
+
subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
|
187
|
+
installCommands: [
|
|
188
|
+
'echo "Updating package lists..."',
|
|
189
|
+
'apt-get update -y',
|
|
190
|
+
'echo "Installing required packages..."',
|
|
191
|
+
'apt-get install -y curl dnsutils',
|
|
192
|
+
],
|
|
193
|
+
preBuildCommands: [
|
|
194
|
+
'echo "Fetching configuration from private API..."',
|
|
195
|
+
'curl -o config.json https://api.example.com/config',
|
|
196
|
+
],
|
|
86
197
|
});
|
|
87
198
|
|
|
88
199
|
// Use in ECS
|
|
89
|
-
new ecs.
|
|
90
|
-
|
|
200
|
+
new ecs.ContainerDefinition(this, 'MyContainer', {
|
|
201
|
+
image: dockerBuilder.containerImage,
|
|
202
|
+
// ... other container properties ...
|
|
91
203
|
});
|
|
92
204
|
|
|
93
205
|
// Use in Lambda
|
|
@@ -100,35 +212,55 @@ export class MyStack extends cdk.Stack {
|
|
|
100
212
|
}
|
|
101
213
|
```
|
|
102
214
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
### Python Example
|
|
106
|
-
|
|
107
|
-
Here is how to use `TokenInjectableDockerBuilder` in an AWS CDK project with Python:
|
|
215
|
+
#### Python Example
|
|
108
216
|
|
|
109
217
|
```python
|
|
110
|
-
from aws_cdk import
|
|
218
|
+
from aws_cdk import (
|
|
219
|
+
aws_ec2 as ec2,
|
|
220
|
+
aws_ecs as ecs,
|
|
221
|
+
aws_lambda as lambda_,
|
|
222
|
+
core as cdk,
|
|
223
|
+
)
|
|
111
224
|
from token_injectable_docker_builder import TokenInjectableDockerBuilder
|
|
112
|
-
from aws_cdk import aws_ecs as ecs
|
|
113
|
-
from aws_cdk import aws_lambda as lambda_
|
|
114
225
|
|
|
115
226
|
class MyStack(cdk.Stack):
|
|
116
227
|
|
|
117
228
|
def __init__(self, scope: cdk.App, id: str, **kwargs):
|
|
118
229
|
super().__init__(scope, id, **kwargs)
|
|
119
230
|
|
|
231
|
+
# Example VPC and security group (optional)
|
|
232
|
+
vpc = ec2.Vpc(self, "MyVpc")
|
|
233
|
+
security_group = ec2.SecurityGroup(self, "MySecurityGroup", vpc=vpc)
|
|
234
|
+
|
|
235
|
+
# Example of using CDK tokens as build arguments
|
|
236
|
+
my_api_gateway = # ... create or import your API Gateway ...
|
|
237
|
+
|
|
120
238
|
docker_builder = TokenInjectableDockerBuilder(self, "MyDockerBuilder",
|
|
121
239
|
path="./docker",
|
|
122
240
|
build_args={
|
|
123
|
-
"
|
|
241
|
+
"API_URL": my_api_gateway.url, # Using CDK token
|
|
124
242
|
"ENV": "production"
|
|
125
243
|
},
|
|
126
|
-
docker_login_secret_arn="arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret"
|
|
244
|
+
docker_login_secret_arn="arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret",
|
|
245
|
+
vpc=vpc,
|
|
246
|
+
security_groups=[security_group],
|
|
247
|
+
subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS),
|
|
248
|
+
install_commands=[
|
|
249
|
+
'echo "Updating package lists..."',
|
|
250
|
+
'apt-get update -y',
|
|
251
|
+
'echo "Installing required packages..."',
|
|
252
|
+
'apt-get install -y curl dnsutils',
|
|
253
|
+
],
|
|
254
|
+
pre_build_commands=[
|
|
255
|
+
'echo "Fetching configuration from private API..."',
|
|
256
|
+
'curl -o config.json https://api.example.com/config',
|
|
257
|
+
],
|
|
127
258
|
)
|
|
128
259
|
|
|
129
260
|
# Use in ECS
|
|
130
|
-
ecs.
|
|
131
|
-
|
|
261
|
+
ecs.ContainerDefinition(self, "MyContainer",
|
|
262
|
+
image=docker_builder.container_image,
|
|
263
|
+
# ... other container properties ...
|
|
132
264
|
)
|
|
133
265
|
|
|
134
266
|
# Use in Lambda
|
|
@@ -146,6 +278,7 @@ class MyStack(cdk.Stack):
|
|
|
146
278
|
1. **Docker Source**: Packages the source code or Dockerfile specified in the `path` property as an S3 asset.
|
|
147
279
|
2. **CodeBuild Project**:
|
|
148
280
|
- Uses the packaged asset and `buildArgs` to build the Docker image.
|
|
281
|
+
- Executes any custom `installCommands` and `preBuildCommands` during the build process.
|
|
149
282
|
- Pushes the image to an ECR repository.
|
|
150
283
|
3. **Custom Resource**:
|
|
151
284
|
- Triggers the build process using a Lambda function (`onEvent`).
|
|
@@ -159,33 +292,61 @@ class MyStack(cdk.Stack):
|
|
|
159
292
|
## IAM Permissions
|
|
160
293
|
|
|
161
294
|
The construct automatically grants permissions for:
|
|
162
|
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
295
|
+
|
|
296
|
+
- **CodeBuild**:
|
|
297
|
+
- Pull and push images to ECR.
|
|
298
|
+
- Access to AWS Secrets Manager if `dockerLoginSecretArn` is provided.
|
|
299
|
+
- Access to the KMS key for encryption.
|
|
300
|
+
- **Lambda Functions**:
|
|
301
|
+
- Start and monitor CodeBuild builds.
|
|
302
|
+
- Access CloudWatch Logs.
|
|
303
|
+
- Access to the KMS key for encryption.
|
|
304
|
+
- Pull and push images to ECR.
|
|
165
305
|
|
|
166
306
|
---
|
|
167
307
|
|
|
168
308
|
## Notes
|
|
169
309
|
|
|
170
|
-
- **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags.
|
|
171
|
-
- **
|
|
172
|
-
- **
|
|
310
|
+
- **Build Arguments**: Pass custom arguments via `buildArgs` as `--build-arg` flags. CDK tokens can be used to inject dynamic values resolved at deployment time.
|
|
311
|
+
- **Custom Commands**: Use `installCommands` and `preBuildCommands` to run custom shell commands during the build process. This can be useful for installing dependencies or fetching configuration files.
|
|
312
|
+
- **VPC Configuration**: If your build process requires access to resources within a VPC, you can specify the VPC, security groups, and subnet selection.
|
|
313
|
+
- **Docker Login**: If you need to log in to a private Docker registry before building the image, provide the ARN of a secret in AWS Secrets Manager containing the Docker credentials.
|
|
314
|
+
- **ECR Repository**: Automatically creates an ECR repository with lifecycle rules to manage image retention, encryption with a KMS key, and image scanning on push.
|
|
173
315
|
|
|
174
316
|
---
|
|
175
317
|
|
|
176
318
|
## Troubleshooting
|
|
177
319
|
|
|
178
|
-
1. **Build Errors**: Check CodeBuild logs in CloudWatch.
|
|
179
|
-
2. **Lambda Errors**: Check `onEvent` and `isComplete` Lambda logs in CloudWatch.
|
|
180
|
-
3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, and
|
|
320
|
+
1. **Build Errors**: Check the CodeBuild logs in CloudWatch Logs for detailed error messages.
|
|
321
|
+
2. **Lambda Errors**: Check the `onEvent` and `isComplete` Lambda function logs in CloudWatch Logs.
|
|
322
|
+
3. **Permissions**: Ensure IAM roles have the required permissions for CodeBuild, ECR, Secrets Manager, and KMS if applicable.
|
|
323
|
+
4. **Network Access**: If the build requires network access (e.g., to download dependencies), ensure that the VPC configuration allows outbound internet access, or use a NAT gateway if in private subnets.
|
|
181
324
|
|
|
182
325
|
---
|
|
183
326
|
|
|
184
327
|
## Support
|
|
185
328
|
|
|
186
|
-
|
|
329
|
+
For issues or feature requests, please open an issue on [GitHub](https://github.com/AlexTech314/TokenInjectableDockerBuilder).
|
|
187
330
|
|
|
188
331
|
---
|
|
189
332
|
|
|
190
333
|
## Reference Links
|
|
334
|
+
|
|
191
335
|
[](https://constructs.dev/packages/token-injectable-docker-builder)
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
# License
|
|
340
|
+
|
|
341
|
+
This project is licensed under the terms of the MIT license.
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
# Acknowledgements
|
|
346
|
+
|
|
347
|
+
- Inspired by the need for more dynamic Docker asset management in AWS CDK.
|
|
348
|
+
- Thanks to the AWS CDK community for their continuous support and contributions.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
Feel free to reach out if you have any questions or need further assistance!
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IVpc, ISecurityGroup, SubnetSelection } from 'aws-cdk-lib/aws-ec2';
|
|
1
2
|
import { ContainerImage } from 'aws-cdk-lib/aws-ecs';
|
|
2
3
|
import { DockerImageCode } from 'aws-cdk-lib/aws-lambda';
|
|
3
4
|
import { Construct } from 'constructs';
|
|
@@ -35,6 +36,64 @@ export interface TokenInjectableDockerBuilderProps {
|
|
|
35
36
|
* @example 'arn:aws:secretsmanager:us-east-1:123456789012:secret:DockerLoginSecret'
|
|
36
37
|
*/
|
|
37
38
|
readonly dockerLoginSecretArn?: string;
|
|
39
|
+
/**
|
|
40
|
+
* The VPC in which the CodeBuild project will be deployed.
|
|
41
|
+
* If provided, the CodeBuild project will be launched within the specified VPC.
|
|
42
|
+
* @default No VPC is attached, and the CodeBuild project will use public internet.
|
|
43
|
+
*/
|
|
44
|
+
readonly vpc?: IVpc;
|
|
45
|
+
/**
|
|
46
|
+
* The security groups to attach to the CodeBuild project.
|
|
47
|
+
* These should define the network access rules for the CodeBuild project.
|
|
48
|
+
* @default No security groups are attached.
|
|
49
|
+
*/
|
|
50
|
+
readonly securityGroups?: ISecurityGroup[];
|
|
51
|
+
/**
|
|
52
|
+
* The subnet selection to specify which subnets to use within the VPC.
|
|
53
|
+
* Allows the user to select private, public, or isolated subnets.
|
|
54
|
+
* @default All subnets in the VPC are used.
|
|
55
|
+
*/
|
|
56
|
+
readonly subnetSelection?: SubnetSelection;
|
|
57
|
+
/**
|
|
58
|
+
* Custom commands to run during the install phase.
|
|
59
|
+
*
|
|
60
|
+
* **Example Usage:**
|
|
61
|
+
* ```typescript
|
|
62
|
+
* new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
|
|
63
|
+
* path: path.resolve(__dirname, '../app'),
|
|
64
|
+
* installCommands: [
|
|
65
|
+
* 'echo "Updating package lists..."',
|
|
66
|
+
* 'apt-get update -y',
|
|
67
|
+
* 'echo "Installing required packages..."',
|
|
68
|
+
* 'apt-get install -y curl dnsutils',
|
|
69
|
+
* ],
|
|
70
|
+
* // ... other properties ...
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
* *This example demonstrates how to install the `curl` and `dnsutils` packages during the install phase using `apt-get`, the package manager for Ubuntu-based CodeBuild environments.*
|
|
74
|
+
*
|
|
75
|
+
* @default - No additional install commands.
|
|
76
|
+
*/
|
|
77
|
+
readonly installCommands?: string[];
|
|
78
|
+
/**
|
|
79
|
+
* Custom commands to run during the pre_build phase.
|
|
80
|
+
*
|
|
81
|
+
* **Example Usage:**
|
|
82
|
+
* ```typescript
|
|
83
|
+
* new TokenInjectableDockerBuilder(this, 'MyDockerBuilder', {
|
|
84
|
+
* path: path.resolve(__dirname, '../app'),
|
|
85
|
+
* preBuildCommands: [
|
|
86
|
+
* 'echo "Fetching configuration from private API..."',
|
|
87
|
+
* 'curl -o config.json https://api.example.com/config',
|
|
88
|
+
* ],
|
|
89
|
+
* // ... other properties ...
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
* *In this example, the builder fetches a configuration file from a private API before starting the Docker build. This config file will be available in the same directory as your Dockerfile during CDK deployment.*
|
|
93
|
+
*
|
|
94
|
+
* @default - No additional pre-build commands.
|
|
95
|
+
*/
|
|
96
|
+
readonly preBuildCommands?: string[];
|
|
38
97
|
}
|
|
39
98
|
/**
|
|
40
99
|
* A CDK construct to build and push Docker images to an ECR repository using CodeBuild and Lambda custom resources.
|
package/lib/index.js
CHANGED
|
@@ -21,7 +21,7 @@ const constructs_1 = require("constructs");
|
|
|
21
21
|
class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
22
22
|
constructor(scope, id, props) {
|
|
23
23
|
super(scope, id);
|
|
24
|
-
const { path: sourcePath, buildArgs, dockerLoginSecretArn } = props;
|
|
24
|
+
const { path: sourcePath, buildArgs, dockerLoginSecretArn, vpc, securityGroups, subnetSelection, installCommands, preBuildCommands, } = props;
|
|
25
25
|
// Define a KMS key for ECR encryption
|
|
26
26
|
const encryptionKey = new aws_kms_1.Key(this, 'EcrEncryptionKey', {
|
|
27
27
|
enableKeyRotation: true,
|
|
@@ -31,8 +31,8 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
31
31
|
lifecycleRules: [
|
|
32
32
|
{
|
|
33
33
|
rulePriority: 1,
|
|
34
|
-
description: 'Remove
|
|
35
|
-
tagStatus: aws_ecr_1.TagStatus.
|
|
34
|
+
description: 'Remove untagged images after 1 day',
|
|
35
|
+
tagStatus: aws_ecr_1.TagStatus.UNTAGGED,
|
|
36
36
|
maxImageAge: aws_cdk_lib_1.Duration.days(1),
|
|
37
37
|
},
|
|
38
38
|
],
|
|
@@ -73,12 +73,25 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
73
73
|
environmentVariables: {
|
|
74
74
|
ECR_REPO_URI: { value: this.ecrRepository.repositoryUri },
|
|
75
75
|
BUILD_ARGS: { value: buildArgsString },
|
|
76
|
+
// Include build arguments as environment variables if needed
|
|
77
|
+
...(buildArgs &&
|
|
78
|
+
Object.fromEntries(Object.entries(buildArgs).map(([key, value]) => [key, { value }]))),
|
|
76
79
|
},
|
|
80
|
+
vpc,
|
|
81
|
+
securityGroups,
|
|
82
|
+
subnetSelection,
|
|
77
83
|
buildSpec: aws_codebuild_1.BuildSpec.fromObject({
|
|
78
84
|
version: '0.2',
|
|
79
85
|
phases: {
|
|
86
|
+
install: {
|
|
87
|
+
commands: [
|
|
88
|
+
'echo "Beginning install phase..."',
|
|
89
|
+
...(installCommands || []),
|
|
90
|
+
],
|
|
91
|
+
},
|
|
80
92
|
pre_build: {
|
|
81
93
|
commands: [
|
|
94
|
+
...(preBuildCommands || []),
|
|
82
95
|
...dockerLoginCommands,
|
|
83
96
|
'echo "Retrieving AWS Account ID..."',
|
|
84
97
|
'export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)',
|
|
@@ -104,7 +117,11 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
104
117
|
// Grant permissions to CodeBuild
|
|
105
118
|
this.ecrRepository.grantPullPush(codeBuildProject);
|
|
106
119
|
codeBuildProject.role.addToPrincipalPolicy(new aws_iam_1.PolicyStatement({
|
|
107
|
-
actions: [
|
|
120
|
+
actions: [
|
|
121
|
+
'ecr:GetAuthorizationToken',
|
|
122
|
+
'ecr:GetDownloadUrlForLayer',
|
|
123
|
+
'ecr:BatchCheckLayerAvailability',
|
|
124
|
+
],
|
|
108
125
|
resources: [this.ecrRepository.repositoryArn],
|
|
109
126
|
}));
|
|
110
127
|
if (dockerLoginSecretArn) {
|
|
@@ -168,5 +185,5 @@ class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
|
168
185
|
}
|
|
169
186
|
exports.TokenInjectableDockerBuilder = TokenInjectableDockerBuilder;
|
|
170
187
|
_a = JSII_RTTI_SYMBOL_1;
|
|
171
|
-
TokenInjectableDockerBuilder[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilder", version: "1.
|
|
172
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsNkJBQTZCO0FBQzdCLDZDQUF1RDtBQUN2RCw2REFBd0Y7QUFDeEYsaURBQWtGO0FBQ2xGLGlEQUFxRDtBQUNyRCxpREFBc0Q7QUFDdEQsaURBQTBDO0FBQzFDLHVEQUFrRjtBQUNsRiw2REFBa0Q7QUFDbEQsbUVBQXdEO0FBQ3hELDJDQUF1QztBQXNDdkM7O0dBRUc7QUFDSCxNQUFhLDRCQUE2QixTQUFRLHNCQUFTO0lBS3pELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBd0M7UUFDaEYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFFcEUsc0NBQXNDO1FBQ3RDLE1BQU0sYUFBYSxHQUFHLElBQUksYUFBRyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtZQUN0RCxpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCLENBQUMsQ0FBQztRQUVILHdGQUF3RjtRQUN4RixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksb0JBQVUsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFO1lBQ3pELGNBQWMsRUFBRTtnQkFDZDtvQkFDRSxZQUFZLEVBQUUsQ0FBQztvQkFDZixXQUFXLEVBQUUscUJBQXFCO29CQUNsQyxTQUFTLEVBQUUsbUJBQVMsQ0FBQyxHQUFHO29CQUN4QixXQUFXLEVBQUUsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2lCQUM5QjthQUNGO1lBQ0QsVUFBVSxFQUFFLDhCQUFvQixDQUFDLEdBQUc7WUFDcEMsYUFBYSxFQUFFLGFBQWE7WUFDNUIsZUFBZSxFQUFFLElBQUk7U0FDdEIsQ0FBQyxDQUFDO1FBRUgsc0NBQXNDO1FB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Q0FBQztRQUMxRCxhQUFhLENBQUMsbUJBQW1CLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFNUQsb0NBQW9DO1FBQ3BDLE1BQU0sUUFBUSxHQUFHLElBQUksMkJBQVEsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUU7WUFDNUQsY0FBYyxFQUFFLHNCQUFzQjtZQUN0QyxpQkFBaUIsRUFBRSx5QkFBeUI7WUFDNUMsYUFBYSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztTQUNwQyxDQUFDLENBQUM7UUFFSCw2QkFBNkI7UUFDN0IsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLDRCQUFjLENBQUMsSUFBSSxFQUFFLHNCQUFzQixFQUFFO1lBQzVFLFlBQVksRUFBRSxRQUFRLENBQUMsWUFBWTtZQUNuQyxVQUFVLEVBQUU7Z0JBQ1YsV0FBVyxFQUFFLGdCQUFnQixDQUFDLFdBQVc7Z0JBQ3pDLE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFO2FBQzdCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxjQUFjLEdBQUcsd0JBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDM0UsSUFBSSxDQUFDLGVBQWUsR0FBRyw0QkFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckUsQ0FBQzs7QUFoTEgsb0VBaUxDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUHJvamVjdCwgU291cmNlLCBMaW51eEJ1aWxkSW1hZ2UsIEJ1aWxkU3BlYyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jb2RlYnVpbGQnO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSwgUmVwb3NpdG9yeUVuY3J5cHRpb24sIFRhZ1N0YXR1cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3InO1xuaW1wb3J0IHsgQ29udGFpbmVySW1hZ2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNzJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgS2V5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWttcyc7XG5pbXBvcnQgeyBSdW50aW1lLCBDb2RlLCBEb2NrZXJJbWFnZUNvZGUsIEZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBBc3NldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMy1hc3NldHMnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlcmAgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIERvY2tlcmZpbGUgb3Igc291cmNlIGNvZGUuXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBEb2NrZXIgYnVpbGQgcHJvY2Vzcy5cbiAgICogVGhlc2UgYXJlIHRyYW5zZm9ybWVkIGludG8gYC0tYnVpbGQtYXJnYCBmbGFncy5cbiAgICogQGV4YW1wbGVcbiAgICoge1xuICAgKiAgIFRPS0VOOiAnbXktc2VjcmV0LXRva2VuJyxcbiAgICogICBFTlY6ICdwcm9kdWN0aW9uJ1xuICAgKiB9XG4gICAqL1xuICByZWFkb25seSBidWlsZEFyZ3M/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBBV1MgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIERvY2tlciBsb2dpbiBjcmVkZW50aWFscy5cbiAgICogVGhpcyBzZWNyZXQgc2hvdWxkIHN0b3JlIGEgSlNPTiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAgICogYGBganNvblxuICAgKiB7XG4gICAqICAgXCJ1c2VybmFtZVwiOiBcIm15LWRvY2tlci11c2VybmFtZVwiLFxuICAgKiAgIFwicGFzc3dvcmRcIjogXCJteS1kb2NrZXItcGFzc3dvcmRcIlxuICAgKiB9XG4gICAqIGBgYFxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSBjb25zdHJ1Y3Qgd2lsbCBza2lwIERvY2tlciBsb2dpbiBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gICAqXG4gICAqIEBleGFtcGxlICdhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6c2VjcmV0OkRvY2tlckxvZ2luU2VjcmV0J1xuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyTG9naW5TZWNyZXRBcm4/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBDREsgY29uc3RydWN0IHRvIGJ1aWxkIGFuZCBwdXNoIERvY2tlciBpbWFnZXMgdG8gYW4gRUNSIHJlcG9zaXRvcnkgdXNpbmcgQ29kZUJ1aWxkIGFuZCBMYW1iZGEgY3VzdG9tIHJlc291cmNlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IGVjclJlcG9zaXRvcnk6IFJlcG9zaXRvcnk7XG4gIHB1YmxpYyByZWFkb25seSBjb250YWluZXJJbWFnZTogQ29udGFpbmVySW1hZ2U7XG4gIHB1YmxpYyByZWFkb25seSBkb2NrZXJJbWFnZUNvZGU6IERvY2tlckltYWdlQ29kZTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IHsgcGF0aDogc291cmNlUGF0aCwgYnVpbGRBcmdzLCBkb2NrZXJMb2dpblNlY3JldEFybiB9ID0gcHJvcHM7XG5cbiAgICAvLyBEZWZpbmUgYSBLTVMga2V5IGZvciBFQ1IgZW5jcnlwdGlvblxuICAgIGNvbnN0IGVuY3J5cHRpb25LZXkgPSBuZXcgS2V5KHRoaXMsICdFY3JFbmNyeXB0aW9uS2V5Jywge1xuICAgICAgZW5hYmxlS2V5Um90YXRpb246IHRydWUsXG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgYW4gRUNSIHJlcG9zaXRvcnkgd2l0aCBsaWZlY3ljbGUgcnVsZXMsIGVuY3J5cHRpb24sIGFuZCBpbWFnZSBzY2FubmluZyBlbmFibGVkXG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5ID0gbmV3IFJlcG9zaXRvcnkodGhpcywgJ0VDUlJlcG9zaXRvcnknLCB7XG4gICAgICBsaWZlY3ljbGVSdWxlczogW1xuICAgICAgICB7XG4gICAgICAgICAgcnVsZVByaW9yaXR5OiAxLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVtb3ZlIHN0YWxlIGltYWdlcycsXG4gICAgICAgICAgdGFnU3RhdHVzOiBUYWdTdGF0dXMuQU5ZLFxuICAgICAgICAgIG1heEltYWdlQWdlOiBEdXJhdGlvbi5kYXlzKDEpLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGVuY3J5cHRpb246IFJlcG9zaXRvcnlFbmNyeXB0aW9uLktNUyxcbiAgICAgIGVuY3J5cHRpb25LZXk6IGVuY3J5cHRpb25LZXksXG4gICAgICBpbWFnZVNjYW5PblB1c2g6IHRydWUsXG4gICAgfSk7XG5cbiAgICAvLyBQYWNrYWdlIHRoZSBzb3VyY2UgY29kZSBhcyBhbiBhc3NldFxuICAgIGNvbnN0IHNvdXJjZUFzc2V0ID0gbmV3IEFzc2V0KHRoaXMsICdTb3VyY2VBc3NldCcsIHtcbiAgICAgIHBhdGg6IHNvdXJjZVBhdGgsXG4gICAgfSk7XG5cbiAgICAvLyBUcmFuc2Zvcm0gYnVpbGRBcmdzIGludG8gYSBzdHJpbmcgb2YgLS1idWlsZC1hcmcgS0VZPVZBTFVFXG4gICAgY29uc3QgYnVpbGRBcmdzU3RyaW5nID0gYnVpbGRBcmdzXG4gICAgICA/IE9iamVjdC5lbnRyaWVzKGJ1aWxkQXJncylcbiAgICAgICAgLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBgLS1idWlsZC1hcmcgJHtrZXl9PSR7dmFsdWV9YClcbiAgICAgICAgLmpvaW4oJyAnKVxuICAgICAgOiAnJztcblxuICAgIC8vIENvbmRpdGlvbmFsIERvY2tlcmh1YiBsb2dpbiBjb21tYW5kc1xuICAgIGNvbnN0IGRvY2tlckxvZ2luQ29tbWFuZHMgPSBkb2NrZXJMb2dpblNlY3JldEFyblxuICAgICAgPyBbXG4gICAgICAgICdlY2hvIFwiUmV0cmlldmluZyBEb2NrZXIgY3JlZGVudGlhbHMgZnJvbSBTZWNyZXRzIE1hbmFnZXIuLi5cIicsXG4gICAgICAgIGBET0NLRVJfVVNFUk5BTUU9JChhd3Mgc2VjcmV0c21hbmFnZXIgZ2V0LXNlY3JldC12YWx1ZSAtLXNlY3JldC1pZCAke2RvY2tlckxvZ2luU2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0IHwganEgLXIgLnVzZXJuYW1lKWAsXG4gICAgICAgIGBET0NLRVJfUEFTU1dPUkQ9JChhd3Mgc2VjcmV0c21hbmFnZXIgZ2V0LXNlY3JldC12YWx1ZSAtLXNlY3JldC1pZCAke2RvY2tlckxvZ2luU2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0IHwganEgLXIgLnBhc3N3b3JkKWAsXG4gICAgICAgICdlY2hvIFwiTG9nZ2luZyBpbiB0byBEb2NrZXIuLi5cIicsXG4gICAgICAgICdlY2hvICRET0NLRVJfUEFTU1dPUkQgfCBkb2NrZXIgbG9naW4gLS11c2VybmFtZSAkRE9DS0VSX1VTRVJOQU1FIC0tcGFzc3dvcmQtc3RkaW4nLFxuICAgICAgXVxuICAgICAgOiBbJ2VjaG8gXCJObyBEb2NrZXIgY3JlZGVudGlhbHMgcHJvdmlkZWQuIFNraXBwaW5nIGxvZ2luIHN0ZXAuXCInXTtcblxuICAgIC8vIENyZWF0ZSBhIENvZGVCdWlsZCBwcm9qZWN0XG4gICAgY29uc3QgY29kZUJ1aWxkUHJvamVjdCA9IG5ldyBQcm9qZWN0KHRoaXMsICdVSUNvZGVCdWlsZFByb2plY3QnLCB7XG4gICAgICBzb3VyY2U6IFNvdXJjZS5zMyh7XG4gICAgICAgIGJ1Y2tldDogc291cmNlQXNzZXQuYnVja2V0LFxuICAgICAgICBwYXRoOiBzb3VyY2VBc3NldC5zM09iamVjdEtleSxcbiAgICAgIH0pLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgYnVpbGRJbWFnZTogTGludXhCdWlsZEltYWdlLlNUQU5EQVJEXzdfMCxcbiAgICAgICAgcHJpdmlsZWdlZDogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICBlbnZpcm9ubWVudFZhcmlhYmxlczoge1xuICAgICAgICBFQ1JfUkVQT19VUkk6IHsgdmFsdWU6IHRoaXMuZWNyUmVwb3NpdG9yeS5yZXBvc2l0b3J5VXJpIH0sXG4gICAgICAgIEJVSUxEX0FSR1M6IHsgdmFsdWU6IGJ1aWxkQXJnc1N0cmluZyB9LFxuICAgICAgfSxcbiAgICAgIGJ1aWxkU3BlYzogQnVpbGRTcGVjLmZyb21PYmplY3Qoe1xuICAgICAgICB2ZXJzaW9uOiAnMC4yJyxcbiAgICAgICAgcGhhc2VzOiB7XG4gICAgICAgICAgcHJlX2J1aWxkOiB7XG4gICAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgICAuLi5kb2NrZXJMb2dpbkNvbW1hbmRzLFxuICAgICAgICAgICAgICAnZWNobyBcIlJldHJpZXZpbmcgQVdTIEFjY291bnQgSUQuLi5cIicsXG4gICAgICAgICAgICAgICdleHBvcnQgQUNDT1VOVF9JRD0kKGF3cyBzdHMgZ2V0LWNhbGxlci1pZGVudGl0eSAtLXF1ZXJ5IEFjY291bnQgLS1vdXRwdXQgdGV4dCknLFxuICAgICAgICAgICAgICAnZWNobyBcIkxvZ2dpbmcgaW4gdG8gQW1hem9uIEVDUi4uLlwiJyxcbiAgICAgICAgICAgICAgJ2F3cyBlY3IgZ2V0LWxvZ2luLXBhc3N3b3JkIC0tcmVnaW9uICRBV1NfREVGQVVMVF9SRUdJT04gfCBkb2NrZXIgbG9naW4gLS11c2VybmFtZSBBV1MgLS1wYXNzd29yZC1zdGRpbiAkQUNDT1VOVF9JRC5ka3IuZWNyLiRBV1NfREVGQVVMVF9SRUdJT04uYW1hem9uYXdzLmNvbScsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIEJ1aWxkIHBoYXNlOiBCdWlsZGluZyB0aGUgRG9ja2VyIGltYWdlLi4uJyxcbiAgICAgICAgICAgICAgJ2RvY2tlciBidWlsZCAkQlVJTERfQVJHUyAtdCAkRUNSX1JFUE9fVVJJOmxhdGVzdCAkQ09ERUJVSUxEX1NSQ19ESVInLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBvc3RfYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIFBvc3QtYnVpbGQgcGhhc2U6IFB1c2hpbmcgdGhlIERvY2tlciBpbWFnZS4uLicsXG4gICAgICAgICAgICAgICdkb2NrZXIgcHVzaCAkRUNSX1JFUE9fVVJJOmxhdGVzdCcsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIC8vIEdyYW50IHBlcm1pc3Npb25zIHRvIENvZGVCdWlsZFxuICAgIHRoaXMuZWNyUmVwb3NpdG9yeS5ncmFudFB1bGxQdXNoKGNvZGVCdWlsZFByb2plY3QpO1xuXG4gICAgY29kZUJ1aWxkUHJvamVjdC5yb2xlIS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2VjcjpHZXRBdXRob3JpemF0aW9uVG9rZW4nLCAnZWNyOkdldERvd25sb2FkVXJsRm9yTGF5ZXInLCAnZWNyOkJhdGNoQ2hlY2tMYXllckF2YWlsYWJpbGl0eSddLFxuICAgICAgICByZXNvdXJjZXM6IFt0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeUFybl0sXG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgaWYgKGRvY2tlckxvZ2luU2VjcmV0QXJuKSB7XG4gICAgICBjb2RlQnVpbGRQcm9qZWN0LnJvbGUhLmFkZFRvUHJpbmNpcGFsUG9saWN5KFxuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJ10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbZG9ja2VyTG9naW5TZWNyZXRBcm5dLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gR3JhbnQgQ29kZUJ1aWxkIGFjY2VzcyB0byB0aGUgS01TIGtleVxuICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChjb2RlQnVpbGRQcm9qZWN0LnJvbGUhKTtcblxuICAgIC8vIENyZWF0ZSBMYW1iZGEgZnVuY3Rpb25zIGZvciBvbkV2ZW50IGFuZCBpc0NvbXBsZXRlIGhhbmRsZXJzXG4gICAgY29uc3Qgb25FdmVudEhhbmRsZXJGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnT25FdmVudEhhbmRsZXJGdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzE4X1gsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vb25FdmVudCcpKSxcbiAgICAgIGhhbmRsZXI6ICdvbkV2ZW50LmhhbmRsZXInLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgfSk7XG5cbiAgICBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2NvZGVidWlsZDpTdGFydEJ1aWxkJ10sXG4gICAgICAgIHJlc291cmNlczogW2NvZGVCdWlsZFByb2plY3QucHJvamVjdEFybl0sIC8vIFJlc3RyaWN0IHRvIHNwZWNpZmljIHByb2plY3RcbiAgICAgIH0pLFxuICAgICk7XG4gICAgY29uc3QgaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnSXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzE4X1gsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vaXNDb21wbGV0ZScpKSxcbiAgICAgIGhhbmRsZXI6ICdpc0NvbXBsZXRlLmhhbmRsZXInLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgfSk7XG5cbiAgICBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2NvZGVidWlsZDpCYXRjaEdldEJ1aWxkcycsXG4gICAgICAgICAgJ2NvZGVidWlsZDpMaXN0QnVpbGRzRm9yUHJvamVjdCcsXG4gICAgICAgICAgJ2xvZ3M6R2V0TG9nRXZlbnRzJyxcbiAgICAgICAgICAnbG9nczpEZXNjcmliZUxvZ1N0cmVhbXMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nR3JvdXBzJyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBHcmFudCBMYW1iZGEgZnVuY3Rpb25zIGFjY2VzcyB0byBLTVMga2V5IGFuZCBFQ1JcbiAgICBlbmNyeXB0aW9uS2V5LmdyYW50RW5jcnlwdERlY3J5cHQob25FdmVudEhhbmRsZXJGdW5jdGlvbik7XG4gICAgZW5jcnlwdGlvbktleS5ncmFudEVuY3J5cHREZWNyeXB0KGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24pO1xuICAgIHRoaXMuZWNyUmVwb3NpdG9yeS5ncmFudFB1bGxQdXNoKG9uRXZlbnRIYW5kbGVyRnVuY3Rpb24pO1xuICAgIHRoaXMuZWNyUmVwb3NpdG9yeS5ncmFudFB1bGxQdXNoKGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24pO1xuXG4gICAgLy8gQ3JlYXRlIGEgY3VzdG9tIHJlc291cmNlIHByb3ZpZGVyXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgJ0N1c3RvbVJlc291cmNlUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogb25FdmVudEhhbmRsZXJGdW5jdGlvbixcbiAgICAgIGlzQ29tcGxldGVIYW5kbGVyOiBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uLFxuICAgICAgcXVlcnlJbnRlcnZhbDogRHVyYXRpb24uc2Vjb25kcygzMCksXG4gICAgfSk7XG5cbiAgICAvLyBEZWZpbmUgdGhlIGN1c3RvbSByZXNvdXJjZVxuICAgIGNvbnN0IGJ1aWxkVHJpZ2dlclJlc291cmNlID0gbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsICdCdWlsZFRyaWdnZXJSZXNvdXJjZScsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBQcm9qZWN0TmFtZTogY29kZUJ1aWxkUHJvamVjdC5wcm9qZWN0TmFtZSxcbiAgICAgICAgVHJpZ2dlcjogY3J5cHRvLnJhbmRvbVVVSUQoKSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBidWlsZFRyaWdnZXJSZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koY29kZUJ1aWxkUHJvamVjdCk7XG4gICAgdGhpcy5jb250YWluZXJJbWFnZSA9IENvbnRhaW5lckltYWdlLmZyb21FY3JSZXBvc2l0b3J5KHRoaXMuZWNyUmVwb3NpdG9yeSk7XG4gICAgdGhpcy5kb2NrZXJJbWFnZUNvZGUgPSBEb2NrZXJJbWFnZUNvZGUuZnJvbUVjcih0aGlzLmVjclJlcG9zaXRvcnkpO1xuICB9XG59XG4iXX0=
|
|
188
|
+
TokenInjectableDockerBuilder[_a] = { fqn: "token-injectable-docker-builder.TokenInjectableDockerBuilder", version: "1.2.0" };
|
|
189
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsNkJBQTZCO0FBQzdCLDZDQUF1RDtBQUN2RCw2REFBd0Y7QUFFeEYsaURBQWtGO0FBQ2xGLGlEQUFxRDtBQUNyRCxpREFBc0Q7QUFDdEQsaURBQTBDO0FBQzFDLHVEQUFrRjtBQUNsRiw2REFBa0Q7QUFDbEQsbUVBQXdEO0FBQ3hELDJDQUF1QztBQXNHdkM7O0dBRUc7QUFDSCxNQUFhLDRCQUE2QixTQUFRLHNCQUFTO0lBS3pELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBd0M7UUFDaEYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQ0osSUFBSSxFQUFFLFVBQVUsRUFDaEIsU0FBUyxFQUNULG9CQUFvQixFQUNwQixHQUFHLEVBQ0gsY0FBYyxFQUNkLGVBQWUsRUFDZixlQUFlLEVBQ2YsZ0JBQWdCLEdBQ2pCLEdBQUcsS0FBSyxDQUFDO1FBRVYsc0NBQXNDO1FBQ3RDLE1BQU0sYUFBYSxHQUFHLElBQUksYUFBRyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtZQUN0RCxpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCLENBQUMsQ0FBQztRQUVILHdGQUF3RjtRQUN4RixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksb0JBQVUsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFO1lBQ3pELGNBQWMsRUFBRTtnQkFDZDtvQkFDRSxZQUFZLEVBQUUsQ0FBQztvQkFDZixXQUFXLEVBQUUsb0NBQW9DO29CQUNqRCxTQUFTLEVBQUUsbUJBQVMsQ0FBQyxRQUFRO29CQUM3QixXQUFXLEVBQUUsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2lCQUM5QjthQUNGO1lBQ0QsVUFBVSxFQUFFLDhCQUFvQixDQUFDLEdBQUc7WUFDcEMsYUFBYSxFQUFFLGFB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LGdCQUFnQixDQUFDLFdBQVc7Z0JBQ3pDLE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFO2FBQzdCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxjQUFjLEdBQUcsd0JBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDM0UsSUFBSSxDQUFDLGVBQWUsR0FBRyw0QkFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckUsQ0FBQzs7QUE3TUgsb0VBOE1DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUHJvamVjdCwgU291cmNlLCBMaW51eEJ1aWxkSW1hZ2UsIEJ1aWxkU3BlYyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jb2RlYnVpbGQnO1xuaW1wb3J0IHsgSVZwYywgSVNlY3VyaXR5R3JvdXAsIFN1Ym5ldFNlbGVjdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSwgUmVwb3NpdG9yeUVuY3J5cHRpb24sIFRhZ1N0YXR1cyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3InO1xuaW1wb3J0IHsgQ29udGFpbmVySW1hZ2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNzJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgS2V5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWttcyc7XG5pbXBvcnQgeyBSdW50aW1lLCBDb2RlLCBEb2NrZXJJbWFnZUNvZGUsIEZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBBc3NldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMy1hc3NldHMnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlcmAgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIERvY2tlcmZpbGUgb3Igc291cmNlIGNvZGUuXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBEb2NrZXIgYnVpbGQgcHJvY2Vzcy5cbiAgICogVGhlc2UgYXJlIHRyYW5zZm9ybWVkIGludG8gYC0tYnVpbGQtYXJnYCBmbGFncy5cbiAgICogQGV4YW1wbGVcbiAgICoge1xuICAgKiAgIFRPS0VOOiAnbXktc2VjcmV0LXRva2VuJyxcbiAgICogICBFTlY6ICdwcm9kdWN0aW9uJ1xuICAgKiB9XG4gICAqL1xuICByZWFkb25seSBidWlsZEFyZ3M/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBBV1MgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIERvY2tlciBsb2dpbiBjcmVkZW50aWFscy5cbiAgICogVGhpcyBzZWNyZXQgc2hvdWxkIHN0b3JlIGEgSlNPTiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAgICogYGBganNvblxuICAgKiB7XG4gICAqICAgXCJ1c2VybmFtZVwiOiBcIm15LWRvY2tlci11c2VybmFtZVwiLFxuICAgKiAgIFwicGFzc3dvcmRcIjogXCJteS1kb2NrZXItcGFzc3dvcmRcIlxuICAgKiB9XG4gICAqIGBgYFxuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSBjb25zdHJ1Y3Qgd2lsbCBza2lwIERvY2tlciBsb2dpbiBkdXJpbmcgdGhlIGJ1aWxkIHByb2Nlc3MuXG4gICAqXG4gICAqIEBleGFtcGxlICdhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6c2VjcmV0OkRvY2tlckxvZ2luU2VjcmV0J1xuICAgKi9cbiAgcmVhZG9ubHkgZG9ja2VyTG9naW5TZWNyZXRBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBWUEMgaW4gd2hpY2ggdGhlIENvZGVCdWlsZCBwcm9qZWN0IHdpbGwgYmUgZGVwbG95ZWQuXG4gICAqIElmIHByb3ZpZGVkLCB0aGUgQ29kZUJ1aWxkIHByb2plY3Qgd2lsbCBiZSBsYXVuY2hlZCB3aXRoaW4gdGhlIHNwZWNpZmllZCBWUEMuXG4gICAqIEBkZWZhdWx0IE5vIFZQQyBpcyBhdHRhY2hlZCwgYW5kIHRoZSBDb2RlQnVpbGQgcHJvamVjdCB3aWxsIHVzZSBwdWJsaWMgaW50ZXJuZXQuXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBJVnBjO1xuXG4gIC8qKlxuICAgKiBUaGUgc2VjdXJpdHkgZ3JvdXBzIHRvIGF0dGFjaCB0byB0aGUgQ29kZUJ1aWxkIHByb2plY3QuXG4gICAqIFRoZXNlIHNob3VsZCBkZWZpbmUgdGhlIG5ldHdvcmsgYWNjZXNzIHJ1bGVzIGZvciB0aGUgQ29kZUJ1aWxkIHByb2plY3QuXG4gICAqIEBkZWZhdWx0IE5vIHNlY3VyaXR5IGdyb3VwcyBhcmUgYXR0YWNoZWQuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IElTZWN1cml0eUdyb3VwW107XG5cbiAgLyoqXG4gICAqIFRoZSBzdWJuZXQgc2VsZWN0aW9uIHRvIHNwZWNpZnkgd2hpY2ggc3VibmV0cyB0byB1c2Ugd2l0aGluIHRoZSBWUEMuXG4gICAqIEFsbG93cyB0aGUgdXNlciB0byBzZWxlY3QgcHJpdmF0ZSwgcHVibGljLCBvciBpc29sYXRlZCBzdWJuZXRzLlxuICAgKiBAZGVmYXVsdCBBbGwgc3VibmV0cyBpbiB0aGUgVlBDIGFyZSB1c2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0U2VsZWN0aW9uPzogU3VibmV0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBDdXN0b20gY29tbWFuZHMgdG8gcnVuIGR1cmluZyB0aGUgaW5zdGFsbCBwaGFzZS5cbiAgICpcbiAgICogKipFeGFtcGxlIFVzYWdlOioqXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmV3IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIodGhpcywgJ015RG9ja2VyQnVpbGRlcicsIHtcbiAgICogICBwYXRoOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vYXBwJyksXG4gICAqICAgaW5zdGFsbENvbW1hbmRzOiBbXG4gICAqICAgICAnZWNobyBcIlVwZGF0aW5nIHBhY2thZ2UgbGlzdHMuLi5cIicsXG4gICAqICAgICAnYXB0LWdldCB1cGRhdGUgLXknLFxuICAgKiAgICAgJ2VjaG8gXCJJbnN0YWxsaW5nIHJlcXVpcmVkIHBhY2thZ2VzLi4uXCInLFxuICAgKiAgICAgJ2FwdC1nZXQgaW5zdGFsbCAteSBjdXJsIGRuc3V0aWxzJyxcbiAgICogICBdLFxuICAgKiAgIC8vIC4uLiBvdGhlciBwcm9wZXJ0aWVzIC4uLlxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqICpUaGlzIGV4YW1wbGUgZGVtb25zdHJhdGVzIGhvdyB0byBpbnN0YWxsIHRoZSBgY3VybGAgYW5kIGBkbnN1dGlsc2AgcGFja2FnZXMgZHVyaW5nIHRoZSBpbnN0YWxsIHBoYXNlIHVzaW5nIGBhcHQtZ2V0YCwgdGhlIHBhY2thZ2UgbWFuYWdlciBmb3IgVWJ1bnR1LWJhc2VkIENvZGVCdWlsZCBlbnZpcm9ubWVudHMuKlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGFkZGl0aW9uYWwgaW5zdGFsbCBjb21tYW5kcy5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxDb21tYW5kcz86IHN0cmluZ1tdO1xuXG5cbiAgLyoqXG4gICAqIEN1c3RvbSBjb21tYW5kcyB0byBydW4gZHVyaW5nIHRoZSBwcmVfYnVpbGQgcGhhc2UuXG4gICAqXG4gICAqICoqRXhhbXBsZSBVc2FnZToqKlxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIG5ldyBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyKHRoaXMsICdNeURvY2tlckJ1aWxkZXInLCB7XG4gICAqICAgcGF0aDogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uL2FwcCcpLFxuICAgKiAgIHByZUJ1aWxkQ29tbWFuZHM6IFtcbiAgICogICAgICdlY2hvIFwiRmV0Y2hpbmcgY29uZmlndXJhdGlvbiBmcm9tIHByaXZhdGUgQVBJLi4uXCInLFxuICAgKiAgICAgJ2N1cmwgLW8gY29uZmlnLmpzb24gaHR0cHM6Ly9hcGkuZXhhbXBsZS5jb20vY29uZmlnJyxcbiAgICogICBdLFxuICAgKiAgIC8vIC4uLiBvdGhlciBwcm9wZXJ0aWVzIC4uLlxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqICpJbiB0aGlzIGV4YW1wbGUsIHRoZSBidWlsZGVyIGZldGNoZXMgYSBjb25maWd1cmF0aW9uIGZpbGUgZnJvbSBhIHByaXZhdGUgQVBJIGJlZm9yZSBzdGFydGluZyB0aGUgRG9ja2VyIGJ1aWxkLiBUaGlzIGNvbmZpZyBmaWxlIHdpbGwgYmUgYXZhaWxhYmxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeSBhcyB5b3VyIERvY2tlcmZpbGUgZHVyaW5nIENESyBkZXBsb3ltZW50LipcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBhZGRpdGlvbmFsIHByZS1idWlsZCBjb21tYW5kcy5cbiAgICovXG4gIHJlYWRvbmx5IHByZUJ1aWxkQ29tbWFuZHM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBBIENESyBjb25zdHJ1Y3QgdG8gYnVpbGQgYW5kIHB1c2ggRG9ja2VyIGltYWdlcyB0byBhbiBFQ1IgcmVwb3NpdG9yeSB1c2luZyBDb2RlQnVpbGQgYW5kIExhbWJkYSBjdXN0b20gcmVzb3VyY2VzLlxuICovXG5leHBvcnQgY2xhc3MgVG9rZW5JbmplY3RhYmxlRG9ja2VyQnVpbGRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWNyUmVwb3NpdG9yeTogUmVwb3NpdG9yeTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbnRhaW5lckltYWdlOiBDb250YWluZXJJbWFnZTtcbiAgcHVibGljIHJlYWRvbmx5IGRvY2tlckltYWdlQ29kZTogRG9ja2VySW1hZ2VDb2RlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qge1xuICAgICAgcGF0aDogc291cmNlUGF0aCxcbiAgICAgIGJ1aWxkQXJncyxcbiAgICAgIGRvY2tlckxvZ2luU2VjcmV0QXJuLFxuICAgICAgdnBjLFxuICAgICAgc2VjdXJpdHlHcm91cHMsXG4gICAgICBzdWJuZXRTZWxlY3Rpb24sXG4gICAgICBpbnN0YWxsQ29tbWFuZHMsXG4gICAgICBwcmVCdWlsZENvbW1hbmRzLFxuICAgIH0gPSBwcm9wcztcblxuICAgIC8vIERlZmluZSBhIEtNUyBrZXkgZm9yIEVDUiBlbmNyeXB0aW9uXG4gICAgY29uc3QgZW5jcnlwdGlvbktleSA9IG5ldyBLZXkodGhpcywgJ0VjckVuY3J5cHRpb25LZXknLCB7XG4gICAgICBlbmFibGVLZXlSb3RhdGlvbjogdHJ1ZSxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBhbiBFQ1IgcmVwb3NpdG9yeSB3aXRoIGxpZmVjeWNsZSBydWxlcywgZW5jcnlwdGlvbiwgYW5kIGltYWdlIHNjYW5uaW5nIGVuYWJsZWRcbiAgICB0aGlzLmVjclJlcG9zaXRvcnkgPSBuZXcgUmVwb3NpdG9yeSh0aGlzLCAnRUNSUmVwb3NpdG9yeScsIHtcbiAgICAgIGxpZmVjeWNsZVJ1bGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBydWxlUHJpb3JpdHk6IDEsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdSZW1vdmUgdW50YWdnZWQgaW1hZ2VzIGFmdGVyIDEgZGF5JyxcbiAgICAgICAgICB0YWdTdGF0dXM6IFRhZ1N0YXR1cy5VTlRBR0dFRCxcbiAgICAgICAgICBtYXhJbWFnZUFnZTogRHVyYXRpb24uZGF5cygxKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBlbmNyeXB0aW9uOiBSZXBvc2l0b3J5RW5jcnlwdGlvbi5LTVMsXG4gICAgICBlbmNyeXB0aW9uS2V5OiBlbmNyeXB0aW9uS2V5LFxuICAgICAgaW1hZ2VTY2FuT25QdXNoOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgLy8gUGFja2FnZSB0aGUgc291cmNlIGNvZGUgYXMgYW4gYXNzZXRcbiAgICBjb25zdCBzb3VyY2VBc3NldCA9IG5ldyBBc3NldCh0aGlzLCAnU291cmNlQXNzZXQnLCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLFxuICAgIH0pO1xuXG4gICAgLy8gVHJhbnNmb3JtIGJ1aWxkQXJncyBpbnRvIGEgc3RyaW5nIG9mIC0tYnVpbGQtYXJnIEtFWT1WQUxVRVxuICAgIGNvbnN0IGJ1aWxkQXJnc1N0cmluZyA9IGJ1aWxkQXJnc1xuICAgICAgPyBPYmplY3QuZW50cmllcyhidWlsZEFyZ3MpXG4gICAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYC0tYnVpbGQtYXJnICR7a2V5fT0ke3ZhbHVlfWApXG4gICAgICAgIC5qb2luKCcgJylcbiAgICAgIDogJyc7XG5cbiAgICAvLyBDb25kaXRpb25hbCBEb2NrZXJodWIgbG9naW4gY29tbWFuZHNcbiAgICBjb25zdCBkb2NrZXJMb2dpbkNvbW1hbmRzID0gZG9ja2VyTG9naW5TZWNyZXRBcm5cbiAgICAgID8gW1xuICAgICAgICAnZWNobyBcIlJldHJpZXZpbmcgRG9ja2VyIGNyZWRlbnRpYWxzIGZyb20gU2VjcmV0cyBNYW5hZ2VyLi4uXCInLFxuICAgICAgICBgRE9DS0VSX1VTRVJOQU1FPSQoYXdzIHNlY3JldHNtYW5hZ2VyIGdldC1zZWNyZXQtdmFsdWUgLS1zZWNyZXQtaWQgJHtkb2NrZXJMb2dpblNlY3JldEFybn0gLS1xdWVyeSBTZWNyZXRTdHJpbmcgLS1vdXRwdXQgdGV4dCB8IGpxIC1yIC51c2VybmFtZSlgLFxuICAgICAgICBgRE9DS0VSX1BBU1NXT1JEPSQoYXdzIHNlY3JldHNtYW5hZ2VyIGdldC1zZWNyZXQtdmFsdWUgLS1zZWNyZXQtaWQgJHtkb2NrZXJMb2dpblNlY3JldEFybn0gLS1xdWVyeSBTZWNyZXRTdHJpbmcgLS1vdXRwdXQgdGV4dCB8IGpxIC1yIC5wYXNzd29yZClgLFxuICAgICAgICAnZWNobyBcIkxvZ2dpbmcgaW4gdG8gRG9ja2VyLi4uXCInLFxuICAgICAgICAnZWNobyAkRE9DS0VSX1BBU1NXT1JEIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgJERPQ0tFUl9VU0VSTkFNRSAtLXBhc3N3b3JkLXN0ZGluJyxcbiAgICAgIF1cbiAgICAgIDogWydlY2hvIFwiTm8gRG9ja2VyIGNyZWRlbnRpYWxzIHByb3ZpZGVkLiBTa2lwcGluZyBsb2dpbiBzdGVwLlwiJ107XG5cbiAgICAvLyBDcmVhdGUgYSBDb2RlQnVpbGQgcHJvamVjdFxuICAgIGNvbnN0IGNvZGVCdWlsZFByb2plY3QgPSBuZXcgUHJvamVjdCh0aGlzLCAnVUlDb2RlQnVpbGRQcm9qZWN0Jywge1xuICAgICAgc291cmNlOiBTb3VyY2UuczMoe1xuICAgICAgICBidWNrZXQ6IHNvdXJjZUFzc2V0LmJ1Y2tldCxcbiAgICAgICAgcGF0aDogc291cmNlQXNzZXQuczNPYmplY3RLZXksXG4gICAgICB9KSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIGJ1aWxkSW1hZ2U6IExpbnV4QnVpbGRJbWFnZS5TVEFOREFSRF83XzAsXG4gICAgICAgIHByaXZpbGVnZWQ6IHRydWUsXG4gICAgICB9LFxuICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IHtcbiAgICAgICAgRUNSX1JFUE9fVVJJOiB7IHZhbHVlOiB0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeVVyaSB9LFxuICAgICAgICBCVUlMRF9BUkdTOiB7IHZhbHVlOiBidWlsZEFyZ3NTdHJpbmcgfSxcbiAgICAgICAgLy8gSW5jbHVkZSBidWlsZCBhcmd1bWVudHMgYXMgZW52aXJvbm1lbnQgdmFyaWFibGVzIGlmIG5lZWRlZFxuICAgICAgICAuLi4oYnVpbGRBcmdzICYmXG4gICAgICAgICAgT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgICAgT2JqZWN0LmVudHJpZXMoYnVpbGRBcmdzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW2tleSwgeyB2YWx1ZSB9XSksXG4gICAgICAgICAgKSksXG4gICAgICB9LFxuICAgICAgdnBjLFxuICAgICAgc2VjdXJpdHlHcm91cHMsXG4gICAgICBzdWJuZXRTZWxlY3Rpb24sXG4gICAgICBidWlsZFNwZWM6IEJ1aWxkU3BlYy5mcm9tT2JqZWN0KHtcbiAgICAgICAgdmVyc2lvbjogJzAuMicsXG4gICAgICAgIHBoYXNlczoge1xuICAgICAgICAgIGluc3RhbGw6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIFwiQmVnaW5uaW5nIGluc3RhbGwgcGhhc2UuLi5cIicsXG4gICAgICAgICAgICAgIC4uLihpbnN0YWxsQ29tbWFuZHMgfHwgW10pLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHByZV9idWlsZDoge1xuICAgICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICAgLi4uKHByZUJ1aWxkQ29tbWFuZHMgfHwgW10pLFxuICAgICAgICAgICAgICAuLi5kb2NrZXJMb2dpbkNvbW1hbmRzLFxuICAgICAgICAgICAgICAnZWNobyBcIlJldHJpZXZpbmcgQVdTIEFjY291bnQgSUQuLi5cIicsXG4gICAgICAgICAgICAgICdleHBvcnQgQUNDT1VOVF9JRD0kKGF3cyBzdHMgZ2V0LWNhbGxlci1pZGVudGl0eSAtLXF1ZXJ5IEFjY291bnQgLS1vdXRwdXQgdGV4dCknLFxuICAgICAgICAgICAgICAnZWNobyBcIkxvZ2dpbmcgaW4gdG8gQW1hem9uIEVDUi4uLlwiJyxcbiAgICAgICAgICAgICAgJ2F3cyBlY3IgZ2V0LWxvZ2luLXBhc3N3b3JkIC0tcmVnaW9uICRBV1NfREVGQVVMVF9SRUdJT04gfCBkb2NrZXIgbG9naW4gLS11c2VybmFtZSBBV1MgLS1wYXNzd29yZC1zdGRpbiAkQUNDT1VOVF9JRC5ka3IuZWNyLiRBV1NfREVGQVVMVF9SRUdJT04uYW1hem9uYXdzLmNvbScsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIEJ1aWxkIHBoYXNlOiBCdWlsZGluZyB0aGUgRG9ja2VyIGltYWdlLi4uJyxcbiAgICAgICAgICAgICAgJ2RvY2tlciBidWlsZCAkQlVJTERfQVJHUyAtdCAkRUNSX1JFUE9fVVJJOmxhdGVzdCAkQ09ERUJVSUxEX1NSQ19ESVInLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBvc3RfYnVpbGQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmRzOiBbXG4gICAgICAgICAgICAgICdlY2hvIFBvc3QtYnVpbGQgcGhhc2U6IFB1c2hpbmcgdGhlIERvY2tlciBpbWFnZS4uLicsXG4gICAgICAgICAgICAgICdkb2NrZXIgcHVzaCAkRUNSX1JFUE9fVVJJOmxhdGVzdCcsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIC8vIEdyYW50IHBlcm1pc3Npb25zIHRvIENvZGVCdWlsZFxuICAgIHRoaXMuZWNyUmVwb3NpdG9yeS5ncmFudFB1bGxQdXNoKGNvZGVCdWlsZFByb2plY3QpO1xuXG4gICAgY29kZUJ1aWxkUHJvamVjdC5yb2xlIS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2VjcjpHZXRBdXRob3JpemF0aW9uVG9rZW4nLFxuICAgICAgICAgICdlY3I6R2V0RG93bmxvYWRVcmxGb3JMYXllcicsXG4gICAgICAgICAgJ2VjcjpCYXRjaENoZWNrTGF5ZXJBdmFpbGFiaWxpdHknLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFt0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeUFybl0sXG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgaWYgKGRvY2tlckxvZ2luU2VjcmV0QXJuKSB7XG4gICAgICBjb2RlQnVpbGRQcm9qZWN0LnJvbGUhLmFkZFRvUHJpbmNpcGFsUG9saWN5KFxuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJ10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbZG9ja2VyTG9naW5TZWNyZXRBcm5dLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gR3JhbnQgQ29kZUJ1aWxkIGFjY2VzcyB0byB0aGUgS01TIGtleVxuICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChjb2RlQnVpbGRQcm9qZWN0LnJvbGUhKTtcblxuICAgIC8vIENyZWF0ZSBMYW1iZGEgZnVuY3Rpb25zIGZvciBvbkV2ZW50IGFuZCBpc0NvbXBsZXRlIGhhbmRsZXJzXG4gICAgY29uc3Qgb25FdmVudEhhbmRsZXJGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnT25FdmVudEhhbmRsZXJGdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzE4X1gsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vb25FdmVudCcpKSxcbiAgICAgIGhhbmRsZXI6ICdvbkV2ZW50LmhhbmRsZXInLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgfSk7XG5cbiAgICBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2NvZGVidWlsZDpTdGFydEJ1aWxkJ10sXG4gICAgICAgIHJlc291cmNlczogW2NvZGVCdWlsZFByb2plY3QucHJvamVjdEFybl0sIC8vIFJlc3RyaWN0IHRvIHNwZWNpZmljIHByb2plY3RcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdJc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMThfWCxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9pc0NvbXBsZXRlJykpLFxuICAgICAgaGFuZGxlcjogJ2lzQ29tcGxldGUuaGFuZGxlcicsXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDE1KSxcbiAgICB9KTtcblxuICAgIGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAnY29kZWJ1aWxkOkJhdGNoR2V0QnVpbGRzJyxcbiAgICAgICAgICAnY29kZWJ1aWxkOkxpc3RCdWlsZHNGb3JQcm9qZWN0JyxcbiAgICAgICAgICAnbG9nczpHZXRMb2dFdmVudHMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nU3RyZWFtcycsXG4gICAgICAgICAgJ2xvZ3M6RGVzY3JpYmVMb2dHcm91cHMnLFxuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIEdyYW50IExhbWJkYSBmdW5jdGlvbnMgYWNjZXNzIHRvIEtNUyBrZXkgYW5kIEVDUlxuICAgIGVuY3J5cHRpb25LZXkuZ3JhbnRFbmNyeXB0RGVjcnlwdChvbkV2ZW50SGFuZGxlckZ1bmN0aW9uKTtcbiAgICBlbmNyeXB0aW9uS2V5LmdyYW50RW5jcnlwdERlY3J5cHQoaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbik7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2gob25FdmVudEhhbmRsZXJGdW5jdGlvbik7XG4gICAgdGhpcy5lY3JSZXBvc2l0b3J5LmdyYW50UHVsbFB1c2goaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbik7XG5cbiAgICAvLyBDcmVhdGUgYSBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXJcbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCAnQ3VzdG9tUmVzb3VyY2VQcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uLFxuICAgICAgaXNDb21wbGV0ZUhhbmRsZXI6IGlzQ29tcGxldGVIYW5kbGVyRnVuY3Rpb24sXG4gICAgICBxdWVyeUludGVydmFsOiBEdXJhdGlvbi5zZWNvbmRzKDMwKSxcbiAgICB9KTtcblxuICAgIC8vIERlZmluZSB0aGUgY3VzdG9tIHJlc291cmNlXG4gICAgY29uc3QgYnVpbGRUcmlnZ2VyUmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgJ0J1aWxkVHJpZ2dlclJlc291cmNlJywge1xuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFByb2plY3ROYW1lOiBjb2RlQnVpbGRQcm9qZWN0LnByb2plY3ROYW1lLFxuICAgICAgICBUcmlnZ2VyOiBjcnlwdG8ucmFuZG9tVVVJRCgpLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGJ1aWxkVHJpZ2dlclJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeShjb2RlQnVpbGRQcm9qZWN0KTtcbiAgICB0aGlzLmNvbnRhaW5lckltYWdlID0gQ29udGFpbmVySW1hZ2UuZnJvbUVjclJlcG9zaXRvcnkodGhpcy5lY3JSZXBvc2l0b3J5KTtcbiAgICB0aGlzLmRvY2tlckltYWdlQ29kZSA9IERvY2tlckltYWdlQ29kZS5mcm9tRWNyKHRoaXMuZWNyUmVwb3NpdG9yeSk7XG4gIH1cbn1cbiJdfQ==
|