@paulo_raca/cdk-skylight 0.0.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.
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WindowsEKSNodes = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ /**
7
+ * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
8
+ *
9
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
10
+ * with the License. A copy of the License is located at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
15
+ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
16
+ * and limitations under the License.
17
+ */
18
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
19
+ const constructs_1 = require("constructs");
20
+ const skylight = require("../../index");
21
+ class WindowsEKSNodes extends constructs_1.Construct {
22
+ constructor(scope, id, props) {
23
+ super(scope, id);
24
+ props.namespace = props.namespace ?? 'cdk-skylight';
25
+ props.instanceType =
26
+ props.instanceType ?? new aws_cdk_lib_1.aws_ec2.InstanceType('m5.large');
27
+ this.vpc = props.vpc;
28
+ const windows_machineImage = new aws_cdk_lib_1.aws_ec2.LookupMachineImage({
29
+ name: '*Windows_Server-2019-English-Full-EKS_Optimized-1.21*',
30
+ windows: true,
31
+ });
32
+ this.nodesSg = new aws_cdk_lib_1.aws_ec2.SecurityGroup(this, id + '-securityGroup', {
33
+ vpc: this.vpc,
34
+ });
35
+ this.windowsWorkersRole = new aws_cdk_lib_1.aws_iam.Role(this, 'windows-eks-workers-instance-role', {
36
+ assumedBy: new aws_cdk_lib_1.aws_iam.ServicePrincipal('ec2.amazonaws.com'),
37
+ roleName: 'windows-eks-workers-instance-role',
38
+ managedPolicies: [
39
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
40
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEKSWorkerNodePolicy'),
41
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly'),
42
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEKS_CNI_Policy'),
43
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMDirectoryServiceAccess'),
44
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AWSKeyManagementServicePowerUser'),
45
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEKSClusterPolicy'),
46
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('SecretsManagerReadWrite'),
47
+ ],
48
+ });
49
+ this.asg = new aws_cdk_lib_1.aws_autoscaling.AutoScalingGroup(this, 'WindowsInstancesCapacity', {
50
+ vpc: props.vpc,
51
+ role: this.windowsWorkersRole,
52
+ minCapacity: 2,
53
+ securityGroup: this.nodesSg,
54
+ maxCapacity: 10,
55
+ instanceType: props.instanceType,
56
+ machineImage: windows_machineImage,
57
+ });
58
+ this.asgResource = this.asg.node.children.find((c) => c.cfnResourceType ===
59
+ 'AWS::AutoScaling::AutoScalingGroup');
60
+ }
61
+ addUserData(...commands) {
62
+ this.asg.addUserData(...commands);
63
+ }
64
+ addAdDependency(adParametersStore) {
65
+ const secretName = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `/${adParametersStore.namespace}/${adParametersStore.secretPointer}`);
66
+ this.addUserData(`
67
+ #domain join with secret from secret manager
68
+ [string]$SecretAD = "${secretName}"
69
+ $SecretObj = Get-SECSecretValue -SecretId $SecretAD
70
+ [PSCustomObject]$Secret = ($SecretObj.SecretString | ConvertFrom-Json)
71
+ $password = $Secret.Password | ConvertTo-SecureString -asPlainText -Force
72
+ $username = $Secret.UserID + "@" + $Secret.Domain
73
+ $credential = New-Object System.Management.Automation.PSCredential($username,$password)
74
+ Add-Computer -DomainName $Secret.Domain -Credential $credential
75
+ Restart-Computer -Force
76
+ `);
77
+ }
78
+ runPowerShellSSMDocument(name, commands) {
79
+ new aws_cdk_lib_1.aws_ssm.CfnAssociation(this, name, {
80
+ name: 'AWS-RunPowerShellScript',
81
+ parameters: {
82
+ commands: commands,
83
+ },
84
+ targets: [
85
+ {
86
+ key: 'tag:aws:autoscaling:groupName',
87
+ values: [this.asg.autoScalingGroupName],
88
+ },
89
+ ],
90
+ });
91
+ }
92
+ gMSAWebHookAutoInstall(eksCluster, privateSignerName, awsaccountid, awsregion) {
93
+ const certmanager = new aws_cdk_lib_1.aws_iam.ManagedPolicy(this, 'webHookECR', {
94
+ description: 'Allow WebHook',
95
+ statements: [
96
+ new aws_cdk_lib_1.aws_iam.PolicyStatement({
97
+ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
98
+ actions: [
99
+ 'ecr:CreateRepository',
100
+ 'ecr:DescribeImages',
101
+ 'ecr:GetAuthorizationToken',
102
+ 'ecr:GetDownloadUrlForLayer',
103
+ 'ecr:BatchGetImage',
104
+ 'ecr:BatchCheckLayerAvailability',
105
+ 'ecr:GetDownloadUrlForLayer',
106
+ 'ecr:PutImage',
107
+ 'ecr:InitiateLayerUpload',
108
+ 'ecr:UploadLayerPart',
109
+ 'ecr:CompleteLayerUpload',
110
+ ],
111
+ resources: ['arn:aws:ecr:*:*:repository/certmanager-ca-controller'],
112
+ }),
113
+ ],
114
+ });
115
+ const describeCluster = new aws_cdk_lib_1.aws_iam.ManagedPolicy(this, 'AllowWebHookEKSCluster', {
116
+ description: 'Allow WebHook',
117
+ statements: [
118
+ new aws_cdk_lib_1.aws_iam.PolicyStatement({
119
+ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
120
+ actions: ['eks:DescribeCluster'],
121
+ resources: [`arn:aws:eks:*:${awsaccountid}:cluster/*`],
122
+ }),
123
+ ],
124
+ });
125
+ const allowAuthorizationToken = new aws_cdk_lib_1.aws_iam.ManagedPolicy(this, 'AllowWebHookECRCluster', {
126
+ description: 'Allow WebHook',
127
+ statements: [
128
+ new aws_cdk_lib_1.aws_iam.PolicyStatement({
129
+ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
130
+ actions: ['ecr:GetAuthorizationToken'],
131
+ resources: ['*'],
132
+ }),
133
+ ],
134
+ });
135
+ const node = new skylight.compute.DomainWindowsNode(this, 'eksWorkerForGMSA', {
136
+ vpc: this.vpc,
137
+ windowsMachine: false,
138
+ iamManagedPoliciesList: [
139
+ certmanager,
140
+ describeCluster,
141
+ allowAuthorizationToken,
142
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
143
+ ],
144
+ amiName: '*amzn2-ami-hvm-x86_64*',
145
+ instanceType: 't3.small',
146
+ });
147
+ this.asg.connections.allowFrom(node.instance, aws_cdk_lib_1.aws_ec2.Port.tcp(443));
148
+ eksCluster.awsAuth.addRoleMapping(node.nodeRole, {
149
+ groups: ['system:masters'],
150
+ username: 'admin',
151
+ });
152
+ node.runShellCommands([
153
+ 'sudo -i',
154
+ 'yum install -y git',
155
+ 'git clone https://github.com/aws-samples/amazon-eks-gmsa-admission-webhook-autoinstall',
156
+ 'cd amazon-eks-gmsa-admission-webhook-autoinstall/',
157
+ `bash installation.sh ${awsaccountid} ${awsregion} ${eksCluster.clusterName} ${privateSignerName}/my-signer AL2`,
158
+ ], 'webHookInstallation');
159
+ }
160
+ addStorageDependency(adParametersStore, fsxParametersStore, folderName) {
161
+ const secretName = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `/${adParametersStore.namespace}/${adParametersStore.secretPointer}`);
162
+ const fsxEndpoint = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `/${fsxParametersStore.namespace}/${fsxParametersStore.dnsEndpoint}`);
163
+ const smbPath = `\\\\${fsxEndpoint}\\${folderName}`;
164
+ const commands = [
165
+ '$bootfix = {',
166
+ '$LocalDrive = Get-SmbGlobalMapping',
167
+ 'if ($LocalDrive -eq $null)',
168
+ '{',
169
+ ` [string]$SecretAD = '${secretName}'`,
170
+ ' $SecretObj = Get-SECSecretValue -SecretId $SecretAD',
171
+ ' [PSCustomObject]$Secret = ($SecretObj.SecretString | ConvertFrom-Json)',
172
+ ' $password = $Secret.Password | ConvertTo-SecureString -asPlainText -Force',
173
+ " $username = $Secret.UserID + '@' + $Secret.Domain",
174
+ ' $domain_admin_credential = New-Object System.Management.Automation.PSCredential($username,$password)',
175
+ ` New-SmbGlobalMapping -RemotePath '${smbPath}' -Credential $domain_admin_credential -LocalPath G: -Persistent $true -RequirePrivacy $true -ErrorAction Stop`,
176
+ '}',
177
+ '}',
178
+ 'New-Item -ItemType Directory -Path c:\\Scripts',
179
+ '$bootfix | set-content c:\\Scripts\\bootfix.ps1',
180
+ '# Create a scheduled task on startup to execute the mapping',
181
+ "$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument 'c:\\scripts\\bootfix.ps1'",
182
+ '$trigger = New-ScheduledTaskTrigger -AtStartup',
183
+ ` [string]$SecretAD = '${secretName}'`,
184
+ ' $SecretObj = Get-SECSecretValue -SecretId $SecretAD',
185
+ ' [PSCustomObject]$Secret = ($SecretObj.SecretString | ConvertFrom-Json)',
186
+ " $username = $Secret.UserID + '@' + $Secret.Domain",
187
+ "Register-ScheduledTask -Action $action -Trigger $trigger -TaskName 'SmbGlobalMapping' -Description 'Mapping the SMB share and adding machine to gMSA' -RunLevel Highest -User $username -Password $Secret.Password",
188
+ '# Running the boot fix now',
189
+ '& $bootfix',
190
+ '',
191
+ ];
192
+ this.runPowerShellSSMDocument('SMBGlobalMapping', commands);
193
+ }
194
+ addEKSDependency(eksCluster) {
195
+ const commands = [
196
+ '# Joining EKS Cluster',
197
+ "[string]$EKSBootstrapScriptFile = 'C:\\Program Files\\Amazon\\EKS\\Start-EKSBootstrap.ps1'",
198
+ `powershell -File $EKSBootstrapScriptFile -EKSClusterName '${eksCluster.clusterName}'`,
199
+ ];
200
+ this.runPowerShellSSMDocument('EKSBootstrap', commands);
201
+ eksCluster.awsAuth.addRoleMapping(this.windowsWorkersRole, {
202
+ groups: [
203
+ 'system:bootstrappers',
204
+ 'system:nodes',
205
+ 'eks:kube-proxy-windows',
206
+ ],
207
+ username: 'system:node:{{EC2PrivateDNSName}}',
208
+ });
209
+ eksCluster.connectAutoScalingGroupCapacity(this.asg, {
210
+ bootstrapEnabled: false, //Windows Bootstrap done manually
211
+ });
212
+ }
213
+ addLocalCredFile(adParametersStore, ADGroupName, AccountName) {
214
+ const secretName = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `/${adParametersStore.namespace}/${adParametersStore.secretPointer}`);
215
+ const commands = [
216
+ '# Getting AD Password',
217
+ `[string]$SecretAD = '${secretName}'`,
218
+ '$SecretObj = Get-SECSecretValue -SecretId $SecretAD',
219
+ '[PSCustomObject]$Secret = ($SecretObj.SecretString | ConvertFrom-Json)',
220
+ '$password = $Secret.Password | ConvertTo-SecureString -asPlainText -Force',
221
+ "$username = $Secret.UserID + '@' + $Secret.Domain",
222
+ '$domain_admin_credential = New-Object System.Management.Automation.PSCredential($username,$password)',
223
+ 'Add-WindowsFeature RSAT-AD-PowerShell',
224
+ 'Install-PackageProvider NuGet -Force',
225
+ 'Install-Module CredentialSpec -Force',
226
+ 'Set-PSRepository PSGallery -InstallationPolicy Trusted',
227
+ `New-ADGroup -Name "${ADGroupName} AD Group" -SamAccountName ${ADGroupName}"" -GroupScope DomainLocal -Credential $domain_admin_credential`,
228
+ `New-ADServiceAccount -Name "${AccountName}" -DnsHostName "${AccountName}.$Secret.Domain" -ServicePrincipalNames "host/${AccountName}", "host/${AccountName}.$Secret.Domain" -PrincipalsAllowedToRetrieveManagedPassword "${ADGroupName}" -Credential $domain_admin_credential`,
229
+ `Add-ADGroupMember -Identity '${ADGroupName}' -Members $env:computername$ -Credential $domain_admin_credential`,
230
+ '# Saves the cred file to C:\\ProgramData\\Docker\\CredentialSpecs (default)',
231
+ '#Here upload to S3 the CredFile',
232
+ '$bootfix = {',
233
+ `New-CredentialSpec -AccountName ${AccountName}`,
234
+ '}',
235
+ '# Scheduling onboot',
236
+ '$trigger = New-ScheduledTaskTrigger -AtStartup',
237
+ '$bootfix | set-content c:\\Scripts\\gMSA.ps1',
238
+ "$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument 'c:\\scripts\\gMSA.ps1'",
239
+ "Register-ScheduledTask -Action $action -Trigger $trigger -TaskName 'CreateCredSpecFile' -Description 'CreateCredFile and saves it in default folder' -RunLevel Highest -User $username -Password $Secret.Password",
240
+ '# Reboot to apply changes',
241
+ 'Restart-Computer -Force',
242
+ '',
243
+ ];
244
+ this.runPowerShellSSMDocument('gMSA_AD_Group_CredFile', commands);
245
+ }
246
+ }
247
+ exports.WindowsEKSNodes = WindowsEKSNodes;
248
+ _a = JSII_RTTI_SYMBOL_1;
249
+ WindowsEKSNodes[_a] = { fqn: "cdk-skylight.compute.WindowsEKSNodes", version: "0.0.0" };
250
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2luZG93cy1la3Mtbm9kZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2t5bGlnaHQtY29tcHV0ZS9la3Mvd2luZG93cy1la3Mtbm9kZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7R0FXRztBQUVILDZDQU9xQjtBQUVyQiwyQ0FBdUM7QUFDdkMsd0NBQXdDO0FBc0R4QyxNQUFhLGVBQWdCLFNBQVEsc0JBQVM7SUFPNUMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE0QjtRQUNwRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLEtBQUssQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxjQUFjLENBQUM7UUFDcEQsS0FBSyxDQUFDLFlBQVk7WUFDaEIsS0FBSyxDQUFDLFlBQVksSUFBSSxJQUFJLHFCQUFPLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRTdELElBQUksQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQztRQUVyQixNQUFNLG9CQUFvQixHQUFHLElBQUkscUJBQU8sQ0FBQyxrQkFBa0IsQ0FBQztZQUMxRCxJQUFJLEVBQUUsdURBQXVEO1lBQzdELE9BQU8sRUFBRSxJQUFJO1NBQ2QsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLHFCQUFPLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxFQUFFLEdBQUcsZ0JBQWdCLEVBQUU7WUFDcEUsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO1NBQ2QsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUkscUJBQU8sQ0FBQyxJQUFJLENBQ3hDLElBQUksRUFDSixtQ0FBbUMsRUFDbkM7WUFDRSxTQUFTLEVBQUUsSUFBSSxxQkFBTyxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDO1lBQzVELFFBQVEsRUFBRSxt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RCxnQkFBZ0IsQ0FDZCxpQkFBMkUsRUFDM0UsV0FBbUIsRUFDbkIsV0FBbUI7UUFFbkIsTUFBTSxVQUFVLEdBQUcscUJBQU8sQ0FBQyxlQUFlLENBQUMsdUJBQXVCLENBQ2hFLElBQUksRUFDSixJQUFJLGlCQUFpQixDQUFDLFNBQVMsSUFBSSxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FDckUsQ0FBQztRQUVGLE1BQU0sUUFBUSxHQUFHO1lBQ2YsdUJBQXVCO1lBQ3ZCLHlCQUF5QixVQUFVLEdBQUc7WUFDdEMscURBQXFEO1lBQ3JELHlFQUF5RTtZQUN6RSw2RUFBNkU7WUFDN0UscURBQXFEO1lBQ3JELHNHQUFzRztZQUN0Ryx1Q0FBdUM7WUFDdkMsc0NBQXNDO1lBQ3RDLHNDQUFzQztZQUN0Qyx3REFBd0Q7WUFDeEQsc0JBQXNCLFdBQVcsOEJBQThCLFdBQVcsaUVBQWlFO1lBQzNJLCtCQUErQixXQUFXLG1CQUFtQixXQUFXLGlEQUFpRCxXQUFXLFlBQVksV0FBVyxpRUFBaUUsV0FBVyx3Q0FBd0M7WUFDL1EsZ0NBQWdDLFdBQVcsb0VBQW9FO1lBQy9HLDZFQUE2RTtZQUM3RSxpQ0FBaUM7WUFDakMsY0FBYztZQUNkLG1DQUFtQyxXQUFXLEVBQUU7WUFDaEQsR0FBRztZQUNILHFCQUFxQjtZQUNyQixpREFBaUQ7WUFDakQsOENBQThDO1lBQzlDLCtGQUErRjtZQUMvRixtTkFBbU47WUFDbk4sMkJBQTJCO1lBQzNCLHlCQUF5QjtZQUN6QixFQUFFO1NBQ0gsQ0FBQztRQUVGLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyx3QkFBd0IsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNwRSxDQUFDOztBQXRVSCwwQ0F1VUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqICBDb3B5cmlnaHQgMjAyMSBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpLiBZb3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiAgd2l0aCB0aGUgTGljZW5zZS4gQSBjb3B5IG9mIHRoZSBMaWNlbnNlIGlzIGxvY2F0ZWQgYXRcbiAqXG4gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBvciBpbiB0aGUgJ2xpY2Vuc2UnIGZpbGUgYWNjb21wYW55aW5nIHRoaXMgZmlsZS4gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICdBUyBJUycgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFU1xuICogIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXG4gKiAgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7XG4gIGF3c19hdXRvc2NhbGluZyxcbiAgYXdzX2VjMixcbiAgYXdzX2VrcyxcbiAgYXdzX2lhbSxcbiAgYXdzX3NzbSxcbiAgQ2ZuUmVzb3VyY2UsXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IEF1dG9TY2FsaW5nR3JvdXAgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtYXV0b3NjYWxpbmcnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgKiBhcyBza3lsaWdodCBmcm9tICcuLi8uLi9pbmRleCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVJ1bnRpbWVOb2RlcyB7XG4gIC8qKlxuICAgKiBNZXRob2QgdG8gYWRkIHVzZXJEYXRhIHRvIHRoZSBub2Rlc1xuICAgKi9cbiAgYWRkVXNlckRhdGEoLi4uY29tbWFuZHM6IHN0cmluZ1tdKTogdm9pZDtcbiAgLyoqXG4gICAqIE1ldGhvZCB0byBjb25maWd1cmUgdGhlIE5vZGVzIHRvIHBhcnQgb2YgQUQgRG9tYWluXG4gICAqIFNlY3JldDogVGhlIHNlY3JldHMgbWFuYWdlciBzZWNyZXQgdG8gdXNlIG11c3QgYmUgaW4gZm9ybWF0OlxuICAgKiAne0RvbWFpbjogPGRvbWFpbi5uYW1lPiwgVXNlcklEOiAnQWRtaW4nLCBQYXNzd29yZDogJzxwYXNzd29yZD4nfScgKEZyb20gY2RrLXNreWxpZ2h0LkF3c01hbmFnZWRNaWNyb3NvZnRBZFI1MyBPYmplY3QpXG4gICAqL1xuICBhZGRBZERlcGVuZGVuY3k/KFxuICAgIGFkUGFyYW1ldGVyc1N0b3JlOiBza3lsaWdodC5hdXRoZW50aWNhdGlvbi5JQXdzTWFuYWdlZE1pY3Jvc29mdEFkUGFyYW1ldGVyc1xuICApOiB2b2lkO1xuICAvKipcbiAgICogTWV0aG9kIHRvIGNvbmZpZ3VyZSBwZXJzaXN0ZW50IHN0b3JhZ2UgZGVwZW5kZW5jeSB0byB0aGUgaG9zdHMgYnkgdXNpbmcgR2xvYmFsIE1hcHBpbmcuXG4gICAqL1xuICBhZGRTdG9yYWdlRGVwZW5kZW5jeShcbiAgICBhZFBhcmFtZXRlcnNTdG9yZTogc2t5bGlnaHQuYXV0aGVudGljYXRpb24uSUF3c01hbmFnZWRNaWNyb3NvZnRBZFBhcmFtZXRlcnMsXG4gICAgZnN4UGFyYW1ldGVyc1N0b3JlOiBza3lsaWdodC5zdG9yYWdlLklGU3hXaW5kb3dzUGFyYW1ldGVycyxcbiAgICBmb2xkZXJOYW1lOiBzdHJpbmdcbiAgKTogdm9pZDtcblxuICAvKipcbiAgICogTWV0aG9kIHRvIGFkZCB0aGUgbm9kZXMgdG8gc3BlY2lmaWMgQ2x1c3RlclxuICAgKi9cbiAgYWRkRUtTRGVwZW5kZW5jeT8oZWtzQ2x1c3RlcjogYXdzX2Vrcy5DbHVzdGVyKTogdm9pZDtcblxuICAvKipcbiAgICogTWV0aG9kIHRvIGFkZCBzdXBwb3J0IGZvciBMb2NhbENyZWRGaWxlIDxFeHBlcmltZW50YWw+XG4gICAqL1xuICBhZGRMb2NhbENyZWRGaWxlPyhcbiAgICBhZFBhcmFtZXRlcnNTdG9yZTogc2t5bGlnaHQuYXV0aGVudGljYXRpb24uSUF3c01hbmFnZWRNaWNyb3NvZnRBZFBhcmFtZXRlcnMsXG4gICAgQURHcm91cE5hbWU6IHN0cmluZyxcbiAgICBBY2NvdW50TmFtZTogc3RyaW5nXG4gICk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVdpbmRvd3NFS1NOb2Rlc1Byb3BzIHtcbiAgdnBjOiBhd3NfZWMyLklWcGM7XG4gIC8qKlxuICAgKiBUaGUgU1NNIG5hbWVzcGFjZSB0byBzYXZlIHBhcmFtZXRlcnMgdG9cbiAgICogQGRlZmF1bHQgLSAnY2RrLXNreWxpZ2h0Jy5cbiAgICovXG4gIG5hbWVzcGFjZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGluc3RhbmNlIHRvIHVzZVxuICAgKiBAZGVmYXVsdCAtICdtNS5sYXJnZScuXG4gICAqL1xuICBpbnN0YW5jZVR5cGU/OiBhd3NfZWMyLkluc3RhbmNlVHlwZTtcbn1cblxuZXhwb3J0IGNsYXNzIFdpbmRvd3NFS1NOb2RlcyBleHRlbmRzIENvbnN0cnVjdCBpbXBsZW1lbnRzIElSdW50aW1lTm9kZXMge1xuICByZWFkb25seSBhc2c6IEF1dG9TY2FsaW5nR3JvdXA7XG4gIHJlYWRvbmx5IHdpbmRvd3NXb3JrZXJzUm9sZTogYXdzX2lhbS5Sb2xlO1xuICByZWFkb25seSBhc2dSZXNvdXJjZTogYXdzX2F1dG9zY2FsaW5nLkNmbkF1dG9TY2FsaW5nR3JvdXA7XG4gIHJlYWRvbmx5IHZwYzogYXdzX2VjMi5JVnBjO1xuICByZWFkb25seSBub2Rlc1NnOiBhd3NfZWMyLlNlY3VyaXR5R3JvdXA7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElXaW5kb3dzRUtTTm9kZXNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBwcm9wcy5uYW1lc3BhY2UgPSBwcm9wcy5uYW1lc3BhY2UgPz8gJ2Nkay1za3lsaWdodCc7XG4gICAgcHJvcHMuaW5zdGFuY2VUeXBlID1cbiAgICAgIHByb3BzLmluc3RhbmNlVHlwZSA/PyBuZXcgYXdzX2VjMi5JbnN0YW5jZVR5cGUoJ201LmxhcmdlJyk7XG5cbiAgICB0aGlzLnZwYyA9IHByb3BzLnZwYztcblxuICAgIGNvbnN0IHdpbmRvd3NfbWFjaGluZUltYWdlID0gbmV3IGF3c19lYzIuTG9va3VwTWFjaGluZUltYWdlKHtcbiAgICAgIG5hbWU6ICcqV2luZG93c19TZXJ2ZXItMjAxOS1FbmdsaXNoLUZ1bGwtRUtTX09wdGltaXplZC0xLjIxKicsXG4gICAgICB3aW5kb3dzOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5ub2Rlc1NnID0gbmV3IGF3c19lYzIuU2VjdXJpdHlHcm91cCh0aGlzLCBpZCArICctc2VjdXJpdHlHcm91cCcsIHtcbiAgICAgIHZwYzogdGhpcy52cGMsXG4gICAgfSk7XG4gICAgdGhpcy53aW5kb3dzV29ya2Vyc1JvbGUgPSBuZXcgYXdzX2lhbS5Sb2xlKFxuICAgICAgdGhpcyxcbiAgICAgICd3aW5kb3dzLWVrcy13b3JrZXJzLWluc3RhbmNlLXJvbGUnLFxuICAgICAge1xuICAgICAgICBhc3N1bWVkQnk6IG5ldyBhd3NfaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2VjMi5hbWF6b25hd3MuY29tJyksXG4gICAgICAgIHJvbGVOYW1lOiAnd2luZG93cy1la3Mtd29ya2Vycy1pbnN0YW5jZS1yb2xlJyxcbiAgICAgICAgbWFuYWdlZFBvbGljaWVzOiBbXG4gICAgICAgICAgYXdzX2lhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZShcbiAgICAgICAgICAgICdBbWF6b25TU01NYW5hZ2VkSW5zdGFuY2VDb3JlJyxcbiAgICAgICAgICApLFxuICAgICAgICAgIGF3c19pYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoXG4gICAgICAgICAgICAnQW1hem9uRUtTV29ya2VyTm9kZVBvbGljeScsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBhd3NfaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFxuICAgICAgICAgICAgJ0FtYXpvbkVDMkNvbnRhaW5lclJlZ2lzdHJ5UmVhZE9ubHknLFxuICAgICAgICAgICksXG4gICAgICAgICAgYXdzX2lhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZShcbiAgICAgICAgICAgICdBbWF6b25FS1NfQ05JX1BvbGljeScsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBhd3NfaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFxuICAgICAgICAgICAgJ0FtYXpvblNTTURpcmVjdG9yeVNlcnZpY2VBY2Nlc3MnLFxuICAgICAgICAgICksXG4gICAgICAgICAgYXdzX2lhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZShcbiAgICAgICAgICAgICdBV1NLZXlNYW5hZ2VtZW50U2VydmljZVBvd2VyVXNlcicsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBhd3NfaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFxuICAgICAgICAgICAgJ0FtYXpvbkVLU0NsdXN0ZXJQb2xpY3knLFxuICAgICAgICAgICksXG4gICAgICAgICAgYXdzX2lhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZShcbiAgICAgICAgICAgICdTZWNyZXRzTWFuYWdlclJlYWRXcml0ZScsXG4gICAgICAgICAgKSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHRoaXMuYXNnID0gbmV3IGF3c19hdXRvc2NhbGluZy5BdXRvU2NhbGluZ0dyb3VwKFxuICAgICAgdGhpcyxcbiAgICAgICdXaW5kb3dzSW5zdGFuY2VzQ2FwYWNpdHknLFxuICAgICAge1xuICAgICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgICAgcm9sZTogdGhpcy53aW5kb3dzV29ya2Vyc1JvbGUsXG4gICAgICAgIG1pbkNhcGFjaXR5OiAyLFxuICAgICAgICBzZWN1cml0eUdyb3VwOiB0aGlzLm5vZGVzU2csXG4gICAgICAgIG1heENhcGFjaXR5OiAxMCxcbiAgICAgICAgaW5zdGFuY2VUeXBlOiBwcm9wcy5pbnN0YW5jZVR5cGUsXG4gICAgICAgIG1hY2hpbmVJbWFnZTogd2luZG93c19tYWNoaW5lSW1hZ2UsXG4gICAgICB9LFxuICAgICk7XG5cbiAgICB0aGlzLmFzZ1Jlc291cmNlID0gdGhpcy5hc2cubm9kZS5jaGlsZHJlbi5maW5kKFxuICAgICAgKGMpID0+XG4gICAgICAgIChjIGFzIENmblJlc291cmNlKS5jZm5SZXNvdXJjZVR5cGUgPT09XG4gICAgICAgICdBV1M6OkF1dG9TY2FsaW5nOjpBdXRvU2NhbGluZ0dyb3VwJyxcbiAgICApIGFzIGF3c19hdXRvc2NhbGluZy5DZm5BdXRvU2NhbGluZ0dyb3VwO1xuICB9XG5cbiAgYWRkVXNlckRhdGEoLi4uY29tbWFuZHM6IHN0cmluZ1tdKSB7XG4gICAgdGhpcy5hc2cuYWRkVXNlckRhdGEoLi4uY29tbWFuZHMpO1xuICB9XG5cbiAgYWRkQWREZXBlbmRlbmN5KFxuICAgIGFkUGFyYW1ldGVyc1N0b3JlOiBza3lsaWdodC5hdXRoZW50aWNhdGlvbi5JQXdzTWFuYWdlZE1pY3Jvc29mdEFkUGFyYW1ldGVycyxcbiAgKSB7XG4gICAgY29uc3Qgc2VjcmV0TmFtZSA9IGF3c19zc20uU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKFxuICAgICAgdGhpcyxcbiAgICAgIGAvJHthZFBhcmFtZXRlcnNTdG9yZS5uYW1lc3BhY2V9LyR7YWRQYXJhbWV0ZXJzU3RvcmUuc2VjcmV0UG9pbnRlcn1gLFxuICAgICk7XG5cbiAgICB0aGlzLmFkZFVzZXJEYXRhKGBcblx0XHRcdCNkb21haW4gam9pbiB3aXRoIHNlY3JldCBmcm9tIHNlY3JldCBtYW5hZ2VyXG5cdFx0XHRbc3RyaW5nXSRTZWNyZXRBRCAgPSBcIiR7c2VjcmV0TmFtZX1cIlxuXHRcdFx0JFNlY3JldE9iaiA9IEdldC1TRUNTZWNyZXRWYWx1ZSAtU2VjcmV0SWQgJFNlY3JldEFEXG5cdFx0XHRbUFNDdXN0b21PYmplY3RdJFNlY3JldCA9ICgkU2VjcmV0T2JqLlNlY3JldFN0cmluZyAgfCBDb252ZXJ0RnJvbS1Kc29uKVxuXHRcdFx0JHBhc3N3b3JkICAgPSAkU2VjcmV0LlBhc3N3b3JkIHwgQ29udmVydFRvLVNlY3VyZVN0cmluZyAtYXNQbGFpblRleHQgLUZvcmNlXG5cdFx0XHQkdXNlcm5hbWUgICA9ICRTZWNyZXQuVXNlcklEICsgXCJAXCIgKyAkU2VjcmV0LkRvbWFpblxuXHRcdFx0JGNyZWRlbnRpYWwgPSBOZXctT2JqZWN0IFN5c3RlbS5NYW5hZ2VtZW50LkF1dG9tYXRpb24uUFNDcmVkZW50aWFsKCR1c2VybmFtZSwkcGFzc3dvcmQpXG5cdFx0XHRBZGQtQ29tcHV0ZXIgLURvbWFpbk5hbWUgJFNlY3JldC5Eb21haW4gLUNyZWRlbnRpYWwgJGNyZWRlbnRpYWxcblx0XHRcdFJlc3RhcnQtQ29tcHV0ZXIgLUZvcmNlXG5cdFx0YCk7XG4gIH1cblxuICBydW5Qb3dlclNoZWxsU1NNRG9jdW1lbnQobmFtZTogc3RyaW5nLCBjb21tYW5kczogc3RyaW5nW10pIHtcbiAgICBuZXcgYXdzX3NzbS5DZm5Bc3NvY2lhdGlvbih0aGlzLCBuYW1lLCB7XG4gICAgICBuYW1lOiAnQVdTLVJ1blBvd2VyU2hlbGxTY3JpcHQnLFxuICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICBjb21tYW5kczogY29tbWFuZHMsXG4gICAgICB9LFxuICAgICAgdGFyZ2V0czogW1xuICAgICAgICB7XG4gICAgICAgICAga2V5OiAndGFnOmF3czphdXRvc2NhbGluZzpncm91cE5hbWUnLFxuICAgICAgICAgIHZhbHVlczogW3RoaXMuYXNnLmF1dG9TY2FsaW5nR3JvdXBOYW1lXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICBnTVNBV2ViSG9va0F1dG9JbnN0YWxsKFxuICAgIGVrc0NsdXN0ZXI6IGF3c19la3MuQ2x1c3RlcixcbiAgICBwcml2YXRlU2lnbmVyTmFtZTogc3RyaW5nLFxuICAgIGF3c2FjY291bnRpZDogc3RyaW5nLFxuICAgIGF3c3JlZ2lvbjogc3RyaW5nLFxuICApIHtcbiAgICBjb25zdCBjZXJ0bWFuYWdlciA9IG5ldyBhd3NfaWFtLk1hbmFnZWRQb2xpY3kodGhpcywgJ3dlYkhvb2tFQ1InLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IFdlYkhvb2snLFxuICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICBuZXcgYXdzX2lhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGVmZmVjdDogYXdzX2lhbS5FZmZlY3QuQUxMT1csXG4gICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgJ2VjcjpDcmVhdGVSZXBvc2l0b3J5JyxcbiAgICAgICAgICAgICdlY3I6RGVzY3JpYmVJbWFnZXMnLFxuICAgICAgICAgICAgJ2VjcjpHZXRBdXRob3JpemF0aW9uVG9rZW4nLFxuICAgICAgICAgICAgJ2VjcjpHZXREb3dubG9hZFVybEZvckxheWVyJyxcbiAgICAgICAgICAgICdlY3I6QmF0Y2hHZXRJbWFnZScsXG4gICAgICAgICAgICAnZWNyOkJhdGNoQ2hlY2tMYXllckF2YWlsYWJpbGl0eScsXG4gICAgICAgICAgICAnZWNyOkdldERvd25sb2FkVXJsRm9yTGF5ZXInLFxuICAgICAgICAgICAgJ2VjcjpQdXRJbWFnZScsXG4gICAgICAgICAgICAnZWNyOkluaXRpYXRlTGF5ZXJVcGxvYWQnLFxuICAgICAgICAgICAgJ2VjcjpVcGxvYWRMYXllclBhcnQnLFxuICAgICAgICAgICAgJ2VjcjpDb21wbGV0ZUxheWVyVXBsb2FkJyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHJlc291cmNlczogWydhcm46YXdzOmVjcjoqOio6cmVwb3NpdG9yeS9jZXJ0bWFuYWdlci1jYS1jb250cm9sbGVyJ10sXG4gICAgICAgIH0pLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlc2NyaWJlQ2x1c3RlciA9IG5ldyBhd3NfaWFtLk1hbmFnZWRQb2xpY3koXG4gICAgICB0aGlzLFxuICAgICAgJ0FsbG93V2ViSG9va0VLU0NsdXN0ZXInLFxuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IFdlYkhvb2snLFxuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IGF3c19pYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGVmZmVjdDogYXdzX2lhbS5FZmZlY3QuQUxMT1csXG4gICAgICAgICAgICBhY3Rpb25zOiBbJ2VrczpEZXNjcmliZUNsdXN0ZXInXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW2Bhcm46YXdzOmVrczoqOiR7YXdzYWNjb3VudGlkfTpjbHVzdGVyLypgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IGFsbG93QXV0aG9yaXphdGlvblRva2VuID0gbmV3IGF3c19pYW0uTWFuYWdlZFBvbGljeShcbiAgICAgIHRoaXMsXG4gICAgICAnQWxsb3dXZWJIb29rRUNSQ2x1c3RlcicsXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgV2ViSG9vaycsXG4gICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICBuZXcgYXdzX2lhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgZWZmZWN0OiBhd3NfaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgICAgICAgIGFjdGlvbnM6IFsnZWNyOkdldEF1dGhvcml6YXRpb25Ub2tlbiddLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IG5vZGUgPSBuZXcgc2t5bGlnaHQuY29tcHV0ZS5Eb21haW5XaW5kb3dzTm9kZShcbiAgICAgIHRoaXMsXG4gICAgICAnZWtzV29ya2VyRm9yR01TQScsXG4gICAgICB7XG4gICAgICAgIHZwYzogdGhpcy52cGMsXG4gICAgICAgIHdpbmRvd3NNYWNoaW5lOiBmYWxzZSxcbiAgICAgICAgaWFtTWFuYWdlZFBvbGljaWVzTGlzdDogW1xuICAgICAgICAgIGNlcnRtYW5hZ2VyLFxuICAgICAgICAgIGRlc2NyaWJlQ2x1c3RlcixcbiAgICAgICAgICBhbGxvd0F1dGhvcml6YXRpb25Ub2tlbixcbiAgICAgICAgICBhd3NfaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFxuICAgICAgICAgICAgJ0FtYXpvblNTTU1hbmFnZWRJbnN0YW5jZUNvcmUnLFxuICAgICAgICAgICksXG4gICAgICAgIF0sXG4gICAgICAgIGFtaU5hbWU6ICcqYW16bjItYW1pLWh2bS14ODZfNjQqJyxcbiAgICAgICAgaW5zdGFuY2VUeXBlOiAndDMuc21hbGwnLFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgdGhpcy5hc2cuY29ubmVjdGlvbnMuYWxsb3dGcm9tKG5vZGUuaW5zdGFuY2UsIGF3c19lYzIuUG9ydC50Y3AoNDQzKSk7XG5cbiAgICBla3NDbHVzdGVyLmF3c0F1dGguYWRkUm9sZU1hcHBpbmcobm9kZS5ub2RlUm9sZSwge1xuICAgICAgZ3JvdXBzOiBbJ3N5c3RlbTptYXN0ZXJzJ10sXG4gICAgICB1c2VybmFtZTogJ2FkbWluJyxcbiAgICB9KTtcblxuICAgIG5vZGUucnVuU2hlbGxDb21tYW5kcyhcbiAgICAgIFtcbiAgICAgICAgJ3N1ZG8gLWknLFxuICAgICAgICAneXVtIGluc3RhbGwgLXkgZ2l0JyxcbiAgICAgICAgJ2dpdCBjbG9uZSBodHRwczovL2dpdGh1Yi5jb20vYXdzLXNhbXBsZXMvYW1hem9uLWVrcy1nbXNhLWFkbWlzc2lvbi13ZWJob29rLWF1dG9pbnN0YWxsJyxcbiAgICAgICAgJ2NkIGFtYXpvbi1la3MtZ21zYS1hZG1pc3Npb24td2ViaG9vay1hdXRvaW5zdGFsbC8nLFxuICAgICAgICBgYmFzaCBpbnN0YWxsYXRpb24uc2ggJHthd3NhY2NvdW50aWR9ICR7YXdzcmVnaW9ufSAke2Vrc0NsdXN0ZXIuY2x1c3Rlck5hbWV9ICR7cHJpdmF0ZVNpZ25lck5hbWV9L215LXNpZ25lciBBTDJgLFxuICAgICAgXSxcbiAgICAgICd3ZWJIb29rSW5zdGFsbGF0aW9uJyxcbiAgICApO1xuICB9XG5cbiAgYWRkU3RvcmFnZURlcGVuZGVuY3koXG4gICAgYWRQYXJhbWV0ZXJzU3RvcmU6IHNreWxpZ2h0LmF1dGhlbnRpY2F0aW9uLklBd3NNYW5hZ2VkTWljcm9zb2Z0QWRQYXJhbWV0ZXJzLFxuICAgIGZzeFBhcmFtZXRlcnNTdG9yZTogc2t5bGlnaHQuc3RvcmFnZS5JRlN4V2luZG93c1BhcmFtZXRlcnMsXG4gICAgZm9sZGVyTmFtZTogc3RyaW5nLFxuICApIHtcbiAgICBjb25zdCBzZWNyZXROYW1lID0gYXdzX3NzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIoXG4gICAgICB0aGlzLFxuICAgICAgYC8ke2FkUGFyYW1ldGVyc1N0b3JlLm5hbWVzcGFjZX0vJHthZFBhcmFtZXRlcnNTdG9yZS5zZWNyZXRQb2ludGVyfWAsXG4gICAgKTtcblxuICAgIGNvbnN0IGZzeEVuZHBvaW50ID0gYXdzX3NzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIoXG4gICAgICB0aGlzLFxuICAgICAgYC8ke2ZzeFBhcmFtZXRlcnNTdG9yZS5uYW1lc3BhY2V9LyR7ZnN4UGFyYW1ldGVyc1N0b3JlLmRuc0VuZHBvaW50fWAsXG4gICAgKTtcblxuICAgIGNvbnN0IHNtYlBhdGggPSBgXFxcXFxcXFwke2ZzeEVuZHBvaW50fVxcXFwke2ZvbGRlck5hbWV9YDtcblxuICAgIGNvbnN0IGNvbW1hbmRzID0gW1xuICAgICAgJyRib290Zml4ID0geycsXG4gICAgICAnJExvY2FsRHJpdmUgPSBHZXQtU21iR2xvYmFsTWFwcGluZycsXG4gICAgICAnaWYgKCRMb2NhbERyaXZlIC1lcSAkbnVsbCknLFxuICAgICAgJ3snLFxuICAgICAgYCBbc3RyaW5nXSRTZWNyZXRBRCAgPSAnJHtzZWNyZXROYW1lfSdgLFxuICAgICAgJyAkU2VjcmV0T2JqID0gR2V0LVNFQ1NlY3JldFZhbHVlIC1TZWNyZXRJZCAkU2VjcmV0QUQnLFxuICAgICAgJyBbUFNDdXN0b21PYmplY3RdJFNlY3JldCA9ICgkU2VjcmV0T2JqLlNlY3JldFN0cmluZyAgfCBDb252ZXJ0RnJvbS1Kc29uKScsXG4gICAgICAnICRwYXNzd29yZCAgID0gJFNlY3JldC5QYXNzd29yZCB8IENvbnZlcnRUby1TZWN1cmVTdHJpbmcgLWFzUGxhaW5UZXh0IC1Gb3JjZScsXG4gICAgICBcIiAkdXNlcm5hbWUgICA9ICRTZWNyZXQuVXNlcklEICsgJ0AnICsgJFNlY3JldC5Eb21haW5cIixcbiAgICAgICcgJGRvbWFpbl9hZG1pbl9jcmVkZW50aWFsID0gTmV3LU9iamVjdCBTeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLlBTQ3JlZGVudGlhbCgkdXNlcm5hbWUsJHBhc3N3b3JkKScsXG4gICAgICBgIE5ldy1TbWJHbG9iYWxNYXBwaW5nIC1SZW1vdGVQYXRoICcke3NtYlBhdGh9JyAtQ3JlZGVudGlhbCAkZG9tYWluX2FkbWluX2NyZWRlbnRpYWwgLUxvY2FsUGF0aCBHOiAtUGVyc2lzdGVudCAkdHJ1ZSAtUmVxdWlyZVByaXZhY3kgJHRydWUgLUVycm9yQWN0aW9uIFN0b3BgLFxuICAgICAgJ30nLFxuICAgICAgJ30nLFxuICAgICAgJ05ldy1JdGVtIC1JdGVtVHlwZSBEaXJlY3RvcnkgLVBhdGggYzpcXFxcU2NyaXB0cycsXG4gICAgICAnJGJvb3RmaXggfCBzZXQtY29udGVudCBjOlxcXFxTY3JpcHRzXFxcXGJvb3RmaXgucHMxJyxcbiAgICAgICcjIENyZWF0ZSBhIHNjaGVkdWxlZCB0YXNrIG9uIHN0YXJ0dXAgdG8gZXhlY3V0ZSB0aGUgbWFwcGluZycsXG4gICAgICBcIiRhY3Rpb24gPSBOZXctU2NoZWR1bGVkVGFza0FjdGlvbiAtRXhlY3V0ZSAnUG93ZXJzaGVsbC5leGUnIC1Bcmd1bWVudCAnYzpcXFxcc2NyaXB0c1xcXFxib290Zml4LnBzMSdcIixcbiAgICAgICckdHJpZ2dlciA9ICBOZXctU2NoZWR1bGVkVGFza1RyaWdnZXIgLUF0U3RhcnR1cCcsXG4gICAgICBgIFtzdHJpbmddJFNlY3JldEFEICA9ICcke3NlY3JldE5hbWV9J2AsXG4gICAgICAnICRTZWNyZXRPYmogPSBHZXQtU0VDU2VjcmV0VmFsdWUgLVNlY3JldElkICRTZWNyZXRBRCcsXG4gICAgICAnIFtQU0N1c3RvbU9iamVjdF0kU2VjcmV0ID0gKCRTZWNyZXRPYmouU2VjcmV0U3RyaW5nICB8IENvbnZlcnRGcm9tLUpzb24pJyxcbiAgICAgIFwiICR1c2VybmFtZSAgID0gJFNlY3JldC5Vc2VySUQgKyAnQCcgKyAkU2VjcmV0LkRvbWFpblwiLFxuICAgICAgXCJSZWdpc3Rlci1TY2hlZHVsZWRUYXNrIC1BY3Rpb24gJGFjdGlvbiAtVHJpZ2dlciAkdHJpZ2dlciAtVGFza05hbWUgJ1NtYkdsb2JhbE1hcHBpbmcnIC1EZXNjcmlwdGlvbiAnTWFwcGluZyB0aGUgU01CIHNoYXJlIGFuZCBhZGRpbmcgbWFjaGluZSB0byBnTVNBJyAtUnVuTGV2ZWwgSGlnaGVzdCAtVXNlciAkdXNlcm5hbWUgLVBhc3N3b3JkICRTZWNyZXQuUGFzc3dvcmRcIixcbiAgICAgICcjIFJ1bm5pbmcgdGhlIGJvb3QgZml4IG5vdycsXG4gICAgICAnJiAkYm9vdGZpeCcsXG4gICAgICAnJyxcbiAgICBdO1xuICAgIHRoaXMucnVuUG93ZXJTaGVsbFNTTURvY3VtZW50KCdTTUJHbG9iYWxNYXBwaW5nJywgY29tbWFuZHMpO1xuICB9XG5cbiAgYWRkRUtTRGVwZW5kZW5jeShla3NDbHVzdGVyOiBhd3NfZWtzLkNsdXN0ZXIpIHtcbiAgICBjb25zdCBjb21tYW5kcyA9IFtcbiAgICAgICcjIEpvaW5pbmcgRUtTIENsdXN0ZXInLFxuICAgICAgXCJbc3RyaW5nXSRFS1NCb290c3RyYXBTY3JpcHRGaWxlID0gJ0M6XFxcXFByb2dyYW0gRmlsZXNcXFxcQW1hem9uXFxcXEVLU1xcXFxTdGFydC1FS1NCb290c3RyYXAucHMxJ1wiLFxuICAgICAgYHBvd2Vyc2hlbGwgLUZpbGUgJEVLU0Jvb3RzdHJhcFNjcmlwdEZpbGUgLUVLU0NsdXN0ZXJOYW1lICcke2Vrc0NsdXN0ZXIuY2x1c3Rlck5hbWV9J2AsXG4gICAgXTtcbiAgICB0aGlzLnJ1blBvd2VyU2hlbGxTU01Eb2N1bWVudCgnRUtTQm9vdHN0cmFwJywgY29tbWFuZHMpO1xuICAgIGVrc0NsdXN0ZXIuYXdzQXV0aC5hZGRSb2xlTWFwcGluZyh0aGlzLndpbmRvd3NXb3JrZXJzUm9sZSwge1xuICAgICAgZ3JvdXBzOiBbXG4gICAgICAgICdzeXN0ZW06Ym9vdHN0cmFwcGVycycsXG4gICAgICAgICdzeXN0ZW06bm9kZXMnLFxuICAgICAgICAnZWtzOmt1YmUtcHJveHktd2luZG93cycsXG4gICAgICBdLFxuICAgICAgdXNlcm5hbWU6ICdzeXN0ZW06bm9kZTp7e0VDMlByaXZhdGVETlNOYW1lfX0nLFxuICAgIH0pO1xuICAgIGVrc0NsdXN0ZXIuY29ubmVjdEF1dG9TY2FsaW5nR3JvdXBDYXBhY2l0eSh0aGlzLmFzZywge1xuICAgICAgYm9vdHN0cmFwRW5hYmxlZDogZmFsc2UsIC8vV2luZG93cyBCb290c3RyYXAgZG9uZSBtYW51YWxseVxuICAgIH0pO1xuICB9XG5cbiAgYWRkTG9jYWxDcmVkRmlsZShcbiAgICBhZFBhcmFtZXRlcnNTdG9yZTogc2t5bGlnaHQuYXV0aGVudGljYXRpb24uSUF3c01hbmFnZWRNaWNyb3NvZnRBZFBhcmFtZXRlcnMsXG4gICAgQURHcm91cE5hbWU6IHN0cmluZyxcbiAgICBBY2NvdW50TmFtZTogc3RyaW5nLFxuICApIHtcbiAgICBjb25zdCBzZWNyZXROYW1lID0gYXdzX3NzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIoXG4gICAgICB0aGlzLFxuICAgICAgYC8ke2FkUGFyYW1ldGVyc1N0b3JlLm5hbWVzcGFjZX0vJHthZFBhcmFtZXRlcnNTdG9yZS5zZWNyZXRQb2ludGVyfWAsXG4gICAgKTtcblxuICAgIGNvbnN0IGNvbW1hbmRzID0gW1xuICAgICAgJyMgR2V0dGluZyBBRCBQYXNzd29yZCcsXG4gICAgICBgW3N0cmluZ10kU2VjcmV0QUQgID0gJyR7c2VjcmV0TmFtZX0nYCxcbiAgICAgICckU2VjcmV0T2JqID0gR2V0LVNFQ1NlY3JldFZhbHVlIC1TZWNyZXRJZCAkU2VjcmV0QUQnLFxuICAgICAgJ1tQU0N1c3RvbU9iamVjdF0kU2VjcmV0ID0gKCRTZWNyZXRPYmouU2VjcmV0U3RyaW5nICB8IENvbnZlcnRGcm9tLUpzb24pJyxcbiAgICAgICckcGFzc3dvcmQgICA9ICRTZWNyZXQuUGFzc3dvcmQgfCBDb252ZXJ0VG8tU2VjdXJlU3RyaW5nIC1hc1BsYWluVGV4dCAtRm9yY2UnLFxuICAgICAgXCIkdXNlcm5hbWUgICA9ICRTZWNyZXQuVXNlcklEICsgJ0AnICsgJFNlY3JldC5Eb21haW5cIixcbiAgICAgICckZG9tYWluX2FkbWluX2NyZWRlbnRpYWwgPSBOZXctT2JqZWN0IFN5c3RlbS5NYW5hZ2VtZW50LkF1dG9tYXRpb24uUFNDcmVkZW50aWFsKCR1c2VybmFtZSwkcGFzc3dvcmQpJyxcbiAgICAgICdBZGQtV2luZG93c0ZlYXR1cmUgUlNBVC1BRC1Qb3dlclNoZWxsJyxcbiAgICAgICdJbnN0YWxsLVBhY2thZ2VQcm92aWRlciBOdUdldCAtRm9yY2UnLFxuICAgICAgJ0luc3RhbGwtTW9kdWxlIENyZWRlbnRpYWxTcGVjIC1Gb3JjZScsXG4gICAgICAnU2V0LVBTUmVwb3NpdG9yeSBQU0dhbGxlcnkgLUluc3RhbGxhdGlvblBvbGljeSBUcnVzdGVkJyxcbiAgICAgIGBOZXctQURHcm91cCAtTmFtZSBcIiR7QURHcm91cE5hbWV9IEFEIEdyb3VwXCIgLVNhbUFjY291bnROYW1lICR7QURHcm91cE5hbWV9XCJcIiAtR3JvdXBTY29wZSBEb21haW5Mb2NhbCAtQ3JlZGVudGlhbCAkZG9tYWluX2FkbWluX2NyZWRlbnRpYWxgLFxuICAgICAgYE5ldy1BRFNlcnZpY2VBY2NvdW50IC1OYW1lIFwiJHtBY2NvdW50TmFtZX1cIiAtRG5zSG9zdE5hbWUgXCIke0FjY291bnROYW1lfS4kU2VjcmV0LkRvbWFpblwiIC1TZXJ2aWNlUHJpbmNpcGFsTmFtZXMgXCJob3N0LyR7QWNjb3VudE5hbWV9XCIsIFwiaG9zdC8ke0FjY291bnROYW1lfS4kU2VjcmV0LkRvbWFpblwiIC1QcmluY2lwYWxzQWxsb3dlZFRvUmV0cmlldmVNYW5hZ2VkUGFzc3dvcmQgXCIke0FER3JvdXBOYW1lfVwiIC1DcmVkZW50aWFsICRkb21haW5fYWRtaW5fY3JlZGVudGlhbGAsXG4gICAgICBgQWRkLUFER3JvdXBNZW1iZXIgLUlkZW50aXR5ICcke0FER3JvdXBOYW1lfScgLU1lbWJlcnMgJGVudjpjb21wdXRlcm5hbWUkIC1DcmVkZW50aWFsICRkb21haW5fYWRtaW5fY3JlZGVudGlhbGAsXG4gICAgICAnIyBTYXZlcyB0aGUgY3JlZCBmaWxlIHRvIEM6XFxcXFByb2dyYW1EYXRhXFxcXERvY2tlclxcXFxDcmVkZW50aWFsU3BlY3MgKGRlZmF1bHQpJyxcbiAgICAgICcjSGVyZSB1cGxvYWQgdG8gUzMgdGhlIENyZWRGaWxlJyxcbiAgICAgICckYm9vdGZpeCA9IHsnLFxuICAgICAgYE5ldy1DcmVkZW50aWFsU3BlYyAtQWNjb3VudE5hbWUgJHtBY2NvdW50TmFtZX1gLFxuICAgICAgJ30nLFxuICAgICAgJyMgU2NoZWR1bGluZyBvbmJvb3QnLFxuICAgICAgJyR0cmlnZ2VyID0gIE5ldy1TY2hlZHVsZWRUYXNrVHJpZ2dlciAtQXRTdGFydHVwJyxcbiAgICAgICckYm9vdGZpeCB8IHNldC1jb250ZW50IGM6XFxcXFNjcmlwdHNcXFxcZ01TQS5wczEnLFxuICAgICAgXCIkYWN0aW9uID0gTmV3LVNjaGVkdWxlZFRhc2tBY3Rpb24gLUV4ZWN1dGUgJ1Bvd2Vyc2hlbGwuZXhlJyAtQXJndW1lbnQgJ2M6XFxcXHNjcmlwdHNcXFxcZ01TQS5wczEnXCIsXG4gICAgICBcIlJlZ2lzdGVyLVNjaGVkdWxlZFRhc2sgLUFjdGlvbiAkYWN0aW9uIC1UcmlnZ2VyICR0cmlnZ2VyIC1UYXNrTmFtZSAnQ3JlYXRlQ3JlZFNwZWNGaWxlJyAtRGVzY3JpcHRpb24gJ0NyZWF0ZUNyZWRGaWxlIGFuZCBzYXZlcyBpdCBpbiBkZWZhdWx0IGZvbGRlcicgLVJ1bkxldmVsIEhpZ2hlc3QgLVVzZXIgJHVzZXJuYW1lIC1QYXNzd29yZCAkU2VjcmV0LlBhc3N3b3JkXCIsXG4gICAgICAnIyBSZWJvb3QgdG8gYXBwbHkgY2hhbmdlcycsXG4gICAgICAnUmVzdGFydC1Db21wdXRlciAtRm9yY2UnLFxuICAgICAgJycsXG4gICAgXTtcblxuICAgIHRoaXMucnVuUG93ZXJTaGVsbFNTTURvY3VtZW50KCdnTVNBX0FEX0dyb3VwX0NyZWRGaWxlJywgY29tbWFuZHMpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,2 @@
1
+ export * from './windows-node';
2
+ export * from './eks';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./windows-node"), exports);
18
+ __exportStar(require("./eks"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2t5bGlnaHQtY29tcHV0ZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsaURBQStCO0FBQy9CLHdDQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vd2luZG93cy1ub2RlJztcbmV4cG9ydCAqIGZyb20gJy4vZWtzJzsiXX0=
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
5
+ * with the License. A copy of the License is located at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
10
+ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
11
+ * and limitations under the License.
12
+ */
13
+ import { aws_iam as iam, aws_ec2 as ec2, aws_secretsmanager } from 'aws-cdk-lib';
14
+ import { ISecret } from 'aws-cdk-lib/aws-secretsmanager';
15
+ import { Construct } from 'constructs';
16
+ /**
17
+ * The properties of an DomainWindowsNodeProps, requires Active Directory parameter to read the Secret to join the domain
18
+ * Default setting: Domain joined, m5.2xlarge, latest windows, Managed by SSM.
19
+ */
20
+ export interface IDomainWindowsNodeProps {
21
+ /**
22
+ * IAM Instance role permissions
23
+ * @default - 'AmazonSSMManagedInstanceCore, AmazonSSMDirectoryServiceAccess'.
24
+ */
25
+ iamManagedPoliciesList?: iam.IManagedPolicy[];
26
+ /**
27
+ * The EC2 Instance type to use
28
+ *
29
+ * @default - 'm5.2xlarge'.
30
+ */
31
+ instanceType?: string;
32
+ /**
33
+ * Choose if to launch the instance in Private or in Public subnet
34
+ * Private = Subnet that routes to the internet, but not vice versa.
35
+ * Public = Subnet that routes to the internet and vice versa.
36
+ * @default - Private.
37
+ */
38
+ usePrivateSubnet?: boolean;
39
+ /**
40
+ * The name of the AMI to search in SSM (ec2.LookupNodeImage) supports Regex
41
+ * @default - 'Windows_Server-2022-English-Full'
42
+ */
43
+ amiName?: string;
44
+ /**
45
+ * Specific UserData to use
46
+ *
47
+ * The UserData may still be mutated after creation.
48
+ *
49
+ * @default - 'undefined'
50
+ */
51
+ userData?: string;
52
+ domainName?: string;
53
+ passwordObject?: aws_secretsmanager.ISecret;
54
+ /**
55
+ * @default - 'true'
56
+ */
57
+ windowsMachine?: boolean;
58
+ /**
59
+ * The VPC to use
60
+ */
61
+ vpc: ec2.IVpc;
62
+ }
63
+ /**
64
+ * A Domain Windows Node represents one Windows EC2 instance configured with Active Directory.
65
+ *
66
+ * The DomainWindowsNode can be customized to different instance sizes and additional permissions set just like any other EC2 Instance.
67
+ * You can use this construct to run elevated domain tasks with domain permissions or run your application in a single instance setup.
68
+ *
69
+ * The machine will be joined to the provided Active Directory domain using a custom CloudFormation bootstrap that will wait until the required reboot to join the domain. Then it will register the machine in SSM and pull tasks from the SSM State manager.
70
+ *
71
+ * You can send tasks to that machine using the provided methods: runPsCommands() and runPSwithDomainAdmin()
72
+ *
73
+ */
74
+ export declare class DomainWindowsNode extends Construct {
75
+ readonly instance: ec2.Instance;
76
+ readonly nodeRole: iam.Role;
77
+ readonly vpc: ec2.IVpc;
78
+ readonly passwordObject?: ISecret;
79
+ constructor(scope: Construct, id: string, props: IDomainWindowsNodeProps);
80
+ /**
81
+ * Running bash scripts on the Node with SSM Document.
82
+ * i.e: runPsCommands(["echo 'hello world'", "echo 'Second command'"], "myScript")
83
+ */
84
+ runShellCommands(ShellCommands: string[], id: string): void;
85
+ /**
86
+ * Running PowerShell scripts on the Node with SSM Document.
87
+ * i.e: runPsCommands(["Write-host 'Hello world'", "Write-host 'Second command'"], "myScript")
88
+ */
89
+ runPsCommands(psCommands: string[], id: string): void;
90
+ /**
91
+ * Open the security group of the Node Node to specific IP address on port 3389
92
+ * i.e: openRDP("1.1.1.1/32")
93
+ */
94
+ openRDP(ipaddress: string): void;
95
+ /**
96
+ * Running PowerShell scripts on the Node with SSM Document with Domain Admin (Using the Secret used to join the machine to the domain)
97
+ * i.e: runPsCommands(["Write-host 'Hello world'", "Write-host 'Second command'"], "myScript")
98
+ * The provided psCommands will be stored in C:\Scripts and will be run with scheduled task with Domain Admin rights
99
+ */
100
+ runPSwithDomainAdmin(psCommands: string[], id: string): void;
101
+ startInstance(): void;
102
+ }