@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.
- package/.jsii +5012 -0
- package/.jsii.tabl.json +1 -0
- package/API.md +2122 -0
- package/API.md.md +2038 -0
- package/LICENSE +202 -0
- package/README.md +181 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +7 -0
- package/lib/skylight-authentication/ad-authentication.d.ts +132 -0
- package/lib/skylight-authentication/ad-authentication.js +232 -0
- package/lib/skylight-authentication/index.d.ts +1 -0
- package/lib/skylight-authentication/index.js +18 -0
- package/lib/skylight-compute/eks/index.d.ts +2 -0
- package/lib/skylight-compute/eks/index.js +19 -0
- package/lib/skylight-compute/eks/windows-eks-cluster.d.ts +38 -0
- package/lib/skylight-compute/eks/windows-eks-cluster.js +77 -0
- package/lib/skylight-compute/eks/windows-eks-nodes.d.ts +68 -0
- package/lib/skylight-compute/eks/windows-eks-nodes.js +250 -0
- package/lib/skylight-compute/index.d.ts +2 -0
- package/lib/skylight-compute/index.js +19 -0
- package/lib/skylight-compute/windows-node.d.ts +102 -0
- package/lib/skylight-compute/windows-node.js +219 -0
- package/lib/skylight-storage/fsx-windows.d.ts +82 -0
- package/lib/skylight-storage/fsx-windows.js +130 -0
- package/lib/skylight-storage/index.d.ts +1 -0
- package/lib/skylight-storage/index.js +18 -0
- package/package.json +141 -0
- package/rosetta/default.ts-fixture +13 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DomainWindowsNode = 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 custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
20
|
+
const constructs_1 = require("constructs");
|
|
21
|
+
/**
|
|
22
|
+
* A Domain Windows Node represents one Windows EC2 instance configured with Active Directory.
|
|
23
|
+
*
|
|
24
|
+
* The DomainWindowsNode can be customized to different instance sizes and additional permissions set just like any other EC2 Instance.
|
|
25
|
+
* You can use this construct to run elevated domain tasks with domain permissions or run your application in a single instance setup.
|
|
26
|
+
*
|
|
27
|
+
* 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.
|
|
28
|
+
*
|
|
29
|
+
* You can send tasks to that machine using the provided methods: runPsCommands() and runPSwithDomainAdmin()
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
class DomainWindowsNode extends constructs_1.Construct {
|
|
33
|
+
constructor(scope, id, props) {
|
|
34
|
+
super(scope, id);
|
|
35
|
+
props.iamManagedPoliciesList = props.iamManagedPoliciesList ?? [
|
|
36
|
+
aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
|
|
37
|
+
aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('SecretsManagerReadWrite'),
|
|
38
|
+
];
|
|
39
|
+
props.usePrivateSubnet = props.usePrivateSubnet ?? false;
|
|
40
|
+
props.userData = props.userData ?? '';
|
|
41
|
+
props.windowsMachine = props.windowsMachine ?? true;
|
|
42
|
+
this.passwordObject = props.passwordObject ?? undefined;
|
|
43
|
+
this.vpc = props.vpc;
|
|
44
|
+
const nodeImage = new aws_cdk_lib_1.aws_ec2.LookupMachineImage({
|
|
45
|
+
name: props.amiName ?? '*Windows_Server-2022-English-Full-Base*',
|
|
46
|
+
windows: props.windowsMachine,
|
|
47
|
+
});
|
|
48
|
+
this.nodeRole = new aws_cdk_lib_1.aws_iam.Role(this, 'iam-Role', {
|
|
49
|
+
assumedBy: new aws_cdk_lib_1.aws_iam.ServicePrincipal('ec2.amazonaws.com'),
|
|
50
|
+
managedPolicies: props.iamManagedPoliciesList,
|
|
51
|
+
});
|
|
52
|
+
const securityGroup = new aws_cdk_lib_1.aws_ec2.SecurityGroup(this, 'SecurityGroup', {
|
|
53
|
+
vpc: this.vpc,
|
|
54
|
+
});
|
|
55
|
+
// Setting static logical ID for the Worker, to allow further customization
|
|
56
|
+
const workerName = 'EC2Node' + id;
|
|
57
|
+
workerName.replace(/[^0-9a-z]/gi, ''); //convert string to alphanumeric
|
|
58
|
+
if (props.domainName && this.passwordObject) {
|
|
59
|
+
this.passwordObject.grantRead(this.nodeRole);
|
|
60
|
+
// Create CloudFormation Config set to allow the Domain join report back to Cloudformation only after reboot.
|
|
61
|
+
const config = aws_cdk_lib_1.aws_ec2.CloudFormationInit.fromConfigSets({
|
|
62
|
+
configSets: {
|
|
63
|
+
domainJoinRestart: ['domainJoin', 'signal'],
|
|
64
|
+
},
|
|
65
|
+
configs: {
|
|
66
|
+
domainJoin: new aws_cdk_lib_1.aws_ec2.InitConfig([
|
|
67
|
+
aws_cdk_lib_1.aws_ec2.InitCommand.shellCommand(
|
|
68
|
+
// Step1 : Domain Join using the Secret provided
|
|
69
|
+
`powershell.exe -command "Invoke-Command -ScriptBlock {[string]$SecretAD = '${this.passwordObject.secretName}' ;$SecretObj = Get-SECSecretValue -SecretId $SecretAD ;[PSCustomObject]$Secret = ($SecretObj.SecretString | ConvertFrom-Json) ;$password = $Secret.Password | ConvertTo-SecureString -asPlainText -Force ;$username = 'Admin@' + '${props.domainName}' ;$credential = New-Object System.Management.Automation.PSCredential($username,$password) ;Add-Computer -DomainName ${props.domainName} -Credential $credential; Restart-Computer -Force}"`, {
|
|
70
|
+
waitAfterCompletion: aws_cdk_lib_1.aws_ec2.InitCommandWaitDuration.forever(),
|
|
71
|
+
}),
|
|
72
|
+
]),
|
|
73
|
+
signal: new aws_cdk_lib_1.aws_ec2.InitConfig([
|
|
74
|
+
aws_cdk_lib_1.aws_ec2.InitCommand.shellCommand(
|
|
75
|
+
// Step 3: CloudFormation signal
|
|
76
|
+
`cfn-signal.exe --success=true --resource=${workerName} --stack=${aws_cdk_lib_1.Stack.of(this).stackName} --region=${aws_cdk_lib_1.Stack.of(this).region}`, {
|
|
77
|
+
waitAfterCompletion: aws_cdk_lib_1.aws_ec2.InitCommandWaitDuration.none(),
|
|
78
|
+
}),
|
|
79
|
+
]),
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const attachInitOptions = {
|
|
83
|
+
platform: aws_cdk_lib_1.aws_ec2.OperatingSystemType.WINDOWS,
|
|
84
|
+
configSets: ['domainJoinRestart'],
|
|
85
|
+
instanceRole: this.nodeRole,
|
|
86
|
+
userData: aws_cdk_lib_1.aws_ec2.UserData.custom(''),
|
|
87
|
+
embedFingerprint: false,
|
|
88
|
+
};
|
|
89
|
+
this.instance = new aws_cdk_lib_1.aws_ec2.Instance(this, 'Domain-Instance', {
|
|
90
|
+
instanceType: new aws_cdk_lib_1.aws_ec2.InstanceType(props.instanceType ?? 'm5.large'),
|
|
91
|
+
machineImage: nodeImage,
|
|
92
|
+
vpc: this.vpc,
|
|
93
|
+
role: this.nodeRole,
|
|
94
|
+
securityGroup: securityGroup,
|
|
95
|
+
vpcSubnets: this.vpc.selectSubnets({
|
|
96
|
+
subnetType: props.usePrivateSubnet
|
|
97
|
+
? aws_cdk_lib_1.aws_ec2.SubnetType.PRIVATE_WITH_NAT
|
|
98
|
+
: aws_cdk_lib_1.aws_ec2.SubnetType.PUBLIC,
|
|
99
|
+
onePerAz: true,
|
|
100
|
+
}),
|
|
101
|
+
init: config,
|
|
102
|
+
initOptions: attachInitOptions,
|
|
103
|
+
});
|
|
104
|
+
// Override the logical ID name so it can be refereed before initialized
|
|
105
|
+
const CfnInstance = this.instance.node.defaultChild;
|
|
106
|
+
CfnInstance.overrideLogicalId(workerName);
|
|
107
|
+
// Override the default UserData script to execute only the cfn-init (without cfn-signal) as we want cfn-signal to be executed after reboot. More details here: https://aws.amazon.com/premiumsupport/knowledge-center/create-complete-bootstrapping/
|
|
108
|
+
CfnInstance.userData = aws_cdk_lib_1.Fn.base64(`<powershell>cfn-init.exe -v -s ${aws_cdk_lib_1.Stack.of(this).stackName} -r ${workerName} --configsets=domainJoinRestart --region ${aws_cdk_lib_1.Stack.of(this).region}</powershell>`);
|
|
109
|
+
// Override the default 5M timeout to support longer Windows boot time
|
|
110
|
+
CfnInstance.cfnOptions.creationPolicy = {
|
|
111
|
+
resourceSignal: {
|
|
112
|
+
count: 1,
|
|
113
|
+
timeout: 'PT30M',
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
this.instance = new aws_cdk_lib_1.aws_ec2.Instance(this, 'NonDomain-Instance', {
|
|
119
|
+
instanceType: new aws_cdk_lib_1.aws_ec2.InstanceType(props.instanceType ?? 'm5.large'),
|
|
120
|
+
machineImage: nodeImage,
|
|
121
|
+
vpc: this.vpc,
|
|
122
|
+
role: this.nodeRole,
|
|
123
|
+
securityGroup: securityGroup,
|
|
124
|
+
vpcSubnets: this.vpc.selectSubnets({
|
|
125
|
+
subnetType: props.usePrivateSubnet
|
|
126
|
+
? aws_cdk_lib_1.aws_ec2.SubnetType.PRIVATE_WITH_NAT
|
|
127
|
+
: aws_cdk_lib_1.aws_ec2.SubnetType.PUBLIC,
|
|
128
|
+
onePerAz: true,
|
|
129
|
+
}),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
// Append the user data
|
|
133
|
+
if (props.userData != '') {
|
|
134
|
+
this.instance.addUserData(props.userData);
|
|
135
|
+
}
|
|
136
|
+
new aws_cdk_lib_1.CfnOutput(this, 'InstanceId', {
|
|
137
|
+
value: `InstanceId: ${this.instance.instanceId}; dnsName: ${this.instance.instancePublicDnsName}`,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Running bash scripts on the Node with SSM Document.
|
|
142
|
+
* i.e: runPsCommands(["echo 'hello world'", "echo 'Second command'"], "myScript")
|
|
143
|
+
*/
|
|
144
|
+
runShellCommands(ShellCommands, id) {
|
|
145
|
+
new aws_cdk_lib_1.aws_ssm.CfnAssociation(this, id, {
|
|
146
|
+
name: 'AWS-RunShellScript',
|
|
147
|
+
parameters: {
|
|
148
|
+
commands: ShellCommands,
|
|
149
|
+
},
|
|
150
|
+
targets: [{ key: 'InstanceIds', values: [this.instance.instanceId] }],
|
|
151
|
+
maxErrors: '5',
|
|
152
|
+
maxConcurrency: '1',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Running PowerShell scripts on the Node with SSM Document.
|
|
157
|
+
* i.e: runPsCommands(["Write-host 'Hello world'", "Write-host 'Second command'"], "myScript")
|
|
158
|
+
*/
|
|
159
|
+
runPsCommands(psCommands, id) {
|
|
160
|
+
new aws_cdk_lib_1.aws_ssm.CfnAssociation(this, id, {
|
|
161
|
+
name: 'AWS-RunPowerShellScript',
|
|
162
|
+
parameters: {
|
|
163
|
+
commands: psCommands,
|
|
164
|
+
},
|
|
165
|
+
targets: [{ key: 'InstanceIds', values: [this.instance.instanceId] }],
|
|
166
|
+
maxErrors: '5',
|
|
167
|
+
maxConcurrency: '1',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Open the security group of the Node Node to specific IP address on port 3389
|
|
172
|
+
* i.e: openRDP("1.1.1.1/32")
|
|
173
|
+
*/
|
|
174
|
+
openRDP(ipaddress) {
|
|
175
|
+
this.instance.connections.allowFrom(aws_cdk_lib_1.aws_ec2.Peer.ipv4(ipaddress), aws_cdk_lib_1.aws_ec2.Port.tcp(3389), 'Allow RDP');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Running PowerShell scripts on the Node with SSM Document with Domain Admin (Using the Secret used to join the machine to the domain)
|
|
179
|
+
* i.e: runPsCommands(["Write-host 'Hello world'", "Write-host 'Second command'"], "myScript")
|
|
180
|
+
* The provided psCommands will be stored in C:\Scripts and will be run with scheduled task with Domain Admin rights
|
|
181
|
+
*/
|
|
182
|
+
runPSwithDomainAdmin(psCommands, id) {
|
|
183
|
+
var commands = ['$oneTimePS = {'];
|
|
184
|
+
psCommands.forEach((command) => {
|
|
185
|
+
commands.push(command);
|
|
186
|
+
});
|
|
187
|
+
commands.push('}', `[string]$SecretAD = '${this.passwordObject.secretName}'`, '$SecretObj = Get-SECSecretValue -SecretId $SecretAD', '[PSCustomObject]$Secret = ($SecretObj.SecretString | ConvertFrom-Json)', '$password = $Secret.Password | ConvertTo-SecureString -asPlainText -Force', "$username = 'Admin'", '$domain_admin_credential = New-Object System.Management.Automation.PSCredential($username,$password)', 'New-Item -ItemType Directory -Path c:\\Scripts', '$tempScriptPath = "C:\\Scripts\\$PID.ps1"', '$oneTimePS | set-content $tempScriptPath', '# Create a scheduled task on startup to execute the mapping', '$action = New-ScheduledTaskAction -Execute "Powershell.exe" -Argument $tempScriptPath', '$trigger = New-ScheduledTaskTrigger -Once -At (get-date).AddSeconds(10); ', '$trigger.EndBoundary = (get-date).AddSeconds(60).ToString("s") ', 'Register-ScheduledTask -Force -Action $action -Trigger $trigger -TaskName "Task $PID to run with DomainAdmin" -Description "Workaround to run the code with domain admin" -RunLevel Highest -User $username -Password $Secret.Password');
|
|
188
|
+
new aws_cdk_lib_1.aws_ssm.CfnAssociation(this, id, {
|
|
189
|
+
name: 'AWS-RunPowerShellScript',
|
|
190
|
+
parameters: {
|
|
191
|
+
commands: commands,
|
|
192
|
+
},
|
|
193
|
+
targets: [{ key: 'InstanceIds', values: [this.instance.instanceId] }],
|
|
194
|
+
maxErrors: '5',
|
|
195
|
+
maxConcurrency: '1',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
startInstance() {
|
|
199
|
+
new custom_resources_1.AwsCustomResource(this, 'start-instance-needed-' + this.instance.instanceId, {
|
|
200
|
+
policy: custom_resources_1.AwsCustomResourcePolicy.fromSdkCalls({
|
|
201
|
+
resources: custom_resources_1.AwsCustomResourcePolicy.ANY_RESOURCE,
|
|
202
|
+
}),
|
|
203
|
+
onUpdate: {
|
|
204
|
+
service: 'EC2',
|
|
205
|
+
action: 'startInstances', // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2.html#startInstances-property
|
|
206
|
+
parameters: {
|
|
207
|
+
InstanceIds: [this.instance.instanceId],
|
|
208
|
+
},
|
|
209
|
+
physicalResourceId: {
|
|
210
|
+
id: 'startInstance-' + this.instance.instanceId,
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.DomainWindowsNode = DomainWindowsNode;
|
|
217
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
218
|
+
DomainWindowsNode[_a] = { fqn: "cdk-skylight.compute.DomainWindowsNode", version: "0.0.0" };
|
|
219
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2luZG93cy1ub2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NreWxpZ2h0LWNvbXB1dGUvd2luZG93cy1ub2RlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7Ozs7Ozs7Ozs7O0dBV0c7QUFFSCw2Q0FTcUI7QUFFckIsbUVBR3NDO0FBQ3RDLDJDQUF1QztBQXFEdkM7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQWEsaUJBQWtCLFNBQVEsc0JBQVM7SUFNOUMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE4QjtRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pCLEtBQUssQ0FBQyxzQkFBc0IsR0FBRyxLQUFLLENBQUMsc0JBQXNCLElBQUk7WUFDN0QscUJBQUcsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQ3hDLDhCQUE4QixDQUMvQjtZQUNELHFCQUFHLENBQUMsYUFBYSxDQUFDLHdCQUF3QixDQUFDLHlCQUF5QixDQUFDO1NBQ3RFLENBQUM7UUFFRixLQUFLLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixJQUFJLEtBQUssQ0FBQztRQUN6RCxLQUFLLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO1FBQ3RDLEtBQUssQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUM7UUFDcEQsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsY0FBYyxJQUFJLFNBQVMsQ0FBQztRQUV4RCxJQUFJLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFFckIsTUFBTSxTQUFTLEdBQUcsSUFBSSxxQkFBRyxDQUFDLGtCQUFrQixDQUFDO1lBQzNDLElBQUksRUFBRSxLQUFLLENBQUMsT0FBTyxJQUFJLHlDQUF5QztZQUNoRSxPQUFPLEVBQUUsS0FBSyxDQUFDLGNBQWM7U0FDOUIsQ0FBQyxDQUFD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SSxxQkFBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFO1lBQy9CLElBQUksRUFBRSx5QkFBeUI7WUFDL0IsVUFBVSxFQUFFO2dCQUNWLFFBQVEsRUFBRSxRQUFRO2FBQ25CO1lBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNyRSxTQUFTLEVBQUUsR0FBRztZQUNkLGNBQWMsRUFBRSxHQUFHO1NBQ3BCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxhQUFhO1FBQ1gsSUFBSSxvQ0FBaUIsQ0FDbkIsSUFBSSxFQUNKLHdCQUF3QixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUNuRDtZQUNFLE1BQU0sRUFBRSwwQ0FBdUIsQ0FBQyxZQUFZLENBQUM7Z0JBQzNDLFNBQVMsRUFBRSwwQ0FBdUIsQ0FBQyxZQUFZO2FBQ2hELENBQUM7WUFDRixRQUFRLEVBQUU7Z0JBQ1IsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsTUFBTSxFQUFFLGdCQUFnQixFQUFFLDJGQUEyRjtnQkFDckgsVUFBVSxFQUFFO29CQUNWLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO2lCQUN4QztnQkFDRCxrQkFBa0IsRUFBRTtvQkFDbEIsRUFBRSxFQUFFLGdCQUFnQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVTtpQkFDaEQ7YUFDRjtTQUNGLENBQ0YsQ0FBQztJQUNKLENBQUM7O0FBbFBILDhDQW1QQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogIENvcHlyaWdodCAyMDIxIEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIikuIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqICB3aXRoIHRoZSBMaWNlbnNlLiBBIGNvcHkgb2YgdGhlIExpY2Vuc2UgaXMgbG9jYXRlZCBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIG9yIGluIHRoZSAnbGljZW5zZScgZmlsZSBhY2NvbXBhbnlpbmcgdGhpcyBmaWxlLiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgb24gYW4gJ0FTIElTJyBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTXG4gKiAgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcbiAqICBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHtcbiAgYXdzX2lhbSBhcyBpYW0sXG4gIGF3c19lYzIgYXMgZWMyLFxuICBhd3Nfc3NtIGFzIHNzbSxcbiAgQ2ZuT3V0cHV0LFxuICBhd3NfZWMyLFxuICBTdGFjayxcbiAgRm4sXG4gIGF3c19zZWNyZXRzbWFuYWdlcixcbn0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgSVNlY3JldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zZWNyZXRzbWFuYWdlcic7XG5pbXBvcnQge1xuICBBd3NDdXN0b21SZXNvdXJjZSxcbiAgQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3ksXG59IGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbi8qKlxuICogVGhlIHByb3BlcnRpZXMgb2YgYW4gRG9tYWluV2luZG93c05vZGVQcm9wcywgcmVxdWlyZXMgQWN0aXZlIERpcmVjdG9yeSBwYXJhbWV0ZXIgdG8gcmVhZCB0aGUgU2VjcmV0IHRvIGpvaW4gdGhlIGRvbWFpblxuICogRGVmYXVsdCBzZXR0aW5nOiBEb21haW4gam9pbmVkLCBtNS4yeGxhcmdlLCBsYXRlc3Qgd2luZG93cywgTWFuYWdlZCBieSBTU00uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSURvbWFpbldpbmRvd3NOb2RlUHJvcHMge1xuICAvKipcbiAgICogSUFNIEluc3RhbmNlIHJvbGUgcGVybWlzc2lvbnNcbiAgICogQGRlZmF1bHQgLSAnQW1hem9uU1NNTWFuYWdlZEluc3RhbmNlQ29yZSwgQW1hem9uU1NNRGlyZWN0b3J5U2VydmljZUFjY2VzcycuXG4gICAqL1xuICBpYW1NYW5hZ2VkUG9saWNpZXNMaXN0PzogaWFtLklNYW5hZ2VkUG9saWN5W107XG4gIC8qKlxuICAgKiBUaGUgRUMyIEluc3RhbmNlIHR5cGUgdG8gdXNlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gJ201LjJ4bGFyZ2UnLlxuICAgKi9cbiAgaW5zdGFuY2VUeXBlPzogc3RyaW5nO1xuICAvKipcbiAgICogQ2hvb3NlIGlmIHRvIGxhdW5jaCB0aGUgaW5zdGFuY2UgaW4gUHJpdmF0ZSBvciBpbiBQdWJsaWMgc3VibmV0XG4gICAqIFByaXZhdGUgPSBTdWJuZXQgdGhhdCByb3V0ZXMgdG8gdGhlIGludGVybmV0LCBidXQgbm90IHZpY2UgdmVyc2EuXG4gICAqIFB1YmxpYyA9IFN1Ym5ldCB0aGF0IHJvdXRlcyB0byB0aGUgaW50ZXJuZXQgYW5kIHZpY2UgdmVyc2EuXG4gICAqIEBkZWZhdWx0IC0gUHJpdmF0ZS5cbiAgICovXG4gIHVzZVByaXZhdGVTdWJuZXQ/OiBib29sZWFuO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIEFNSSB0byBzZWFyY2ggaW4gU1NNIChlYzIuTG9va3VwTm9kZUltYWdlKSBzdXBwb3J0cyBSZWdleFxuICAgKiAgQGRlZmF1bHQgLSAnV2luZG93c19TZXJ2ZXItMjAyMi1FbmdsaXNoLUZ1bGwnXG4gICAqL1xuICBhbWlOYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogU3BlY2lmaWMgVXNlckRhdGEgdG8gdXNlXG4gICAqXG4gICAqIFRoZSBVc2VyRGF0YSBtYXkgc3RpbGwgYmUgbXV0YXRlZCBhZnRlciBjcmVhdGlvbi5cbiAgICpcbiAgICogIEBkZWZhdWx0IC0gJ3VuZGVmaW5lZCdcbiAgICovXG4gIHVzZXJEYXRhPzogc3RyaW5nO1xuXG4gIGRvbWFpbk5hbWU/OiBzdHJpbmc7XG4gIHBhc3N3b3JkT2JqZWN0PzogYXdzX3NlY3JldHNtYW5hZ2VyLklTZWNyZXQ7XG5cbiAgLyoqXG4gICAqIEBkZWZhdWx0IC0gJ3RydWUnXG4gICAqL1xuICB3aW5kb3dzTWFjaGluZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBWUEMgdG8gdXNlXG4gICAqL1xuICB2cGM6IGVjMi5JVnBjO1xufVxuXG4vKipcbiAqIEEgRG9tYWluIFdpbmRvd3MgTm9kZSByZXByZXNlbnRzIG9uZSBXaW5kb3dzIEVDMiBpbnN0YW5jZSBjb25maWd1cmVkIHdpdGggQWN0aXZlIERpcmVjdG9yeS5cbiAqXG4gKiBUaGUgRG9tYWluV2luZG93c05vZGUgY2FuIGJlIGN1c3RvbWl6ZWQgdG8gZGlmZmVyZW50IGluc3RhbmNlIHNpemVzIGFuZCBhZGRpdGlvbmFsIHBlcm1pc3Npb25zIHNldCBqdXN0IGxpa2UgYW55IG90aGVyIEVDMiBJbnN0YW5jZS5cbiAqIFlvdSBjYW4gdXNlIHRoaXMgY29uc3RydWN0IHRvIHJ1biBlbGV2YXRlZCBkb21haW4gdGFza3Mgd2l0aCBkb21haW4gcGVybWlzc2lvbnMgb3IgcnVuIHlvdXIgYXBwbGljYXRpb24gaW4gYSBzaW5nbGUgaW5zdGFuY2Ugc2V0dXAuXG4gKlxuICogVGhlIG1hY2hpbmUgd2lsbCBiZSBqb2luZWQgdG8gdGhlIHByb3ZpZGVkIEFjdGl2ZSBEaXJlY3RvcnkgZG9tYWluIHVzaW5nIGEgY3VzdG9tIENsb3VkRm9ybWF0aW9uIGJvb3RzdHJhcCB0aGF0IHdpbGwgd2FpdCB1bnRpbCB0aGUgcmVxdWlyZWQgcmVib290IHRvIGpvaW4gdGhlIGRvbWFpbi4gVGhlbiBpdCB3aWxsIHJlZ2lzdGVyIHRoZSBtYWNoaW5lIGluIFNTTSBhbmQgcHVsbCB0YXNrcyBmcm9tIHRoZSBTU00gU3RhdGUgbWFuYWdlci5cbiAqXG4gKiBZb3UgY2FuIHNlbmQgdGFza3MgdG8gdGhhdCBtYWNoaW5lIHVzaW5nIHRoZSBwcm92aWRlZCBtZXRob2RzOiBydW5Qc0NvbW1hbmRzKCkgYW5kIHJ1blBTd2l0aERvbWFpbkFkbWluKClcbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBEb21haW5XaW5kb3dzTm9kZSBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHJlYWRvbmx5IGluc3RhbmNlOiBlYzIuSW5zdGFuY2U7XG4gIHJlYWRvbmx5IG5vZGVSb2xlOiBpYW0uUm9sZTtcbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcbiAgcmVhZG9ubHkgcGFzc3dvcmRPYmplY3Q/OiBJU2VjcmV0O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBJRG9tYWluV2luZG93c05vZGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgcHJvcHMuaWFtTWFuYWdlZFBvbGljaWVzTGlzdCA9IHByb3BzLmlhbU1hbmFnZWRQb2xpY2llc0xpc3QgPz8gW1xuICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFxuICAgICAgICAnQW1hem9uU1NNTWFuYWdlZEluc3RhbmNlQ29yZScsXG4gICAgICApLFxuICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdTZWNyZXRzTWFuYWdlclJlYWRXcml0ZScpLFxuICAgIF07XG5cbiAgICBwcm9wcy51c2VQcml2YXRlU3VibmV0ID0gcHJvcHMudXNlUHJpdmF0ZVN1Ym5ldCA/PyBmYWxzZTtcbiAgICBwcm9wcy51c2VyRGF0YSA9IHByb3BzLnVzZXJEYXRhID8/ICcnO1xuICAgIHByb3BzLndpbmRvd3NNYWNoaW5lID0gcHJvcHMud2luZG93c01hY2hpbmUgPz8gdHJ1ZTtcbiAgICB0aGlzLnBhc3N3b3JkT2JqZWN0ID0gcHJvcHMucGFzc3dvcmRPYmplY3QgPz8gdW5kZWZpbmVkO1xuXG4gICAgdGhpcy52cGMgPSBwcm9wcy52cGM7XG5cbiAgICBjb25zdCBub2RlSW1hZ2UgPSBuZXcgZWMyLkxvb2t1cE1hY2hpbmVJbWFnZSh7XG4gICAgICBuYW1lOiBwcm9wcy5hbWlOYW1lID8/ICcqV2luZG93c19TZXJ2ZXItMjAyMi1FbmdsaXNoLUZ1bGwtQmFzZSonLFxuICAgICAgd2luZG93czogcHJvcHMud2luZG93c01hY2hpbmUsXG4gICAgfSk7XG5cbiAgICB0aGlzLm5vZGVSb2xlID0gbmV3IGlhbS5Sb2xlKHRoaXMsICdpYW0tUm9sZScsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdlYzIuYW1hem9uYXdzLmNvbScpLFxuICAgICAgbWFuYWdlZFBvbGljaWVzOiBwcm9wcy5pYW1NYW5hZ2VkUG9saWNpZXNMaXN0LFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2VjdXJpdHlHcm91cCA9IG5ldyBlYzIuU2VjdXJpdHlHcm91cCh0aGlzLCAnU2VjdXJpdHlHcm91cCcsIHtcbiAgICAgIHZwYzogdGhpcy52cGMsXG4gICAgfSk7XG5cbiAgICAvLyBTZXR0aW5nIHN0YXRpYyBsb2dpY2FsIElEIGZvciB0aGUgV29ya2VyLCB0byBhbGxvdyBmdXJ0aGVyIGN1c3RvbWl6YXRpb25cbiAgICBjb25zdCB3b3JrZXJOYW1lID0gJ0VDMk5vZGUnICsgaWQ7XG4gICAgd29ya2VyTmFtZS5yZXBsYWNlKC9bXjAtOWEtel0vZ2ksICcnKTsgLy9jb252ZXJ0IHN0cmluZyB0byBhbHBoYW51bWVyaWNcblxuICAgIGlmIChwcm9wcy5kb21haW5OYW1lICYmIHRoaXMucGFzc3dvcmRPYmplY3QpIHtcbiAgICAgIHRoaXMucGFzc3dvcmRPYmplY3QuZ3JhbnRSZWFkKHRoaXMubm9kZVJvbGUpO1xuXG4gICAgICAvLyBDcmVhdGUgQ2xvdWRGb3JtYXRpb24gQ29uZmlnIHNldCB0byBhbGxvdyB0aGUgRG9tYWluIGpvaW4gcmVwb3J0IGJhY2sgdG8gQ2xvdWRmb3JtYXRpb24gb25seSBhZnRlciByZWJvb3QuXG4gICAgICBjb25zdCBjb25maWcgPSBlYzIuQ2xvdWRGb3JtYXRpb25Jbml0LmZyb21Db25maWdTZXRzKHtcbiAgICAgICAgY29uZmlnU2V0czoge1xuICAgICAgICAgIGRvbWFpbkpvaW5SZXN0YXJ0OiBbJ2RvbWFpbkpvaW4nLCAnc2lnbmFsJ10sXG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3M6IHtcbiAgICAgICAgICBkb21haW5Kb2luOiBuZXcgZWMyLkluaXRDb25maWcoW1xuICAgICAgICAgICAgZWMyLkluaXRDb21tYW5kLnNoZWxsQ29tbWFuZChcbiAgICAgICAgICAgICAgLy8gU3RlcDEgOiBEb21haW4gSm9pbiB1c2luZyB0aGUgU2VjcmV0IHByb3ZpZGVkXG4gICAgICAgICAgICAgIGBwb3dlcnNoZWxsLmV4ZSAtY29tbWFuZCAgXCJJbnZva2UtQ29tbWFuZCAtU2NyaXB0QmxvY2sge1tzdHJpbmddJFNlY3JldEFEICA9ICcke3RoaXMucGFzc3dvcmRPYmplY3Quc2VjcmV0TmFtZX0nIDskU2VjcmV0T2JqID0gR2V0LVNFQ1NlY3JldFZhbHVlIC1TZWNyZXRJZCAkU2VjcmV0QUQgO1tQU0N1c3RvbU9iamVjdF0kU2VjcmV0ID0gKCRTZWNyZXRPYmouU2VjcmV0U3RyaW5nICB8IENvbnZlcnRGcm9tLUpzb24pIDskcGFzc3dvcmQgICA9ICRTZWNyZXQuUGFzc3dvcmQgfCBDb252ZXJ0VG8tU2VjdXJlU3RyaW5nIC1hc1BsYWluVGV4dCAtRm9yY2UgOyR1c2VybmFtZSAgID0gJ0FkbWluQCcgKyAnJHtwcm9wcy5kb21haW5OYW1lfScgOyRjcmVkZW50aWFsID0gTmV3LU9iamVjdCBTeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLlBTQ3JlZGVudGlhbCgkdXNlcm5hbWUsJHBhc3N3b3JkKSA7QWRkLUNvbXB1dGVyIC1Eb21haW5OYW1lICR7cHJvcHMuZG9tYWluTmFtZX0gLUNyZWRlbnRpYWwgJGNyZWRlbnRpYWw7IFJlc3RhcnQtQ29tcHV0ZXIgLUZvcmNlfVwiYCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdhaXRBZnRlckNvbXBsZXRpb246IGVjMi5Jbml0Q29tbWFuZFdhaXREdXJhdGlvbi5mb3JldmVyKCksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApLFxuICAgICAgICAgIF0pLFxuICAgICAgICAgIHNpZ25hbDogbmV3IGVjMi5Jbml0Q29uZmlnKFtcbiAgICAgICAgICAgIGVjMi5Jbml0Q29tbWFuZC5zaGVsbENvbW1hbmQoXG4gICAgICAgICAgICAgIC8vIFN0ZXAgMzogQ2xvdWRGb3JtYXRpb24gc2lnbmFsXG4gICAgICAgICAgICAgIGBjZm4tc2lnbmFsLmV4ZSAtLXN1Y2Nlc3M9dHJ1ZSAtLXJlc291cmNlPSR7d29ya2VyTmFtZX0gLS1zdGFjaz0ke1xuICAgICAgICAgICAgICAgIFN0YWNrLm9mKHRoaXMpLnN0YWNrTmFtZVxuICAgICAgICAgICAgICB9IC0tcmVnaW9uPSR7U3RhY2sub2YodGhpcykucmVnaW9ufWAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3YWl0QWZ0ZXJDb21wbGV0aW9uOiBlYzIuSW5pdENvbW1hbmRXYWl0RHVyYXRpb24ubm9uZSgpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICBdKSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYXR0YWNoSW5pdE9wdGlvbnM6IGVjMi5BdHRhY2hJbml0T3B0aW9ucyA9IHtcbiAgICAgICAgcGxhdGZvcm06IGVjMi5PcGVyYXRpbmdTeXN0ZW1UeXBlLldJTkRPV1MsXG4gICAgICAgIGNvbmZpZ1NldHM6IFsnZG9tYWluSm9pblJlc3RhcnQnXSxcbiAgICAgICAgaW5zdGFuY2VSb2xlOiB0aGlzLm5vZGVSb2xlLFxuICAgICAgICB1c2VyRGF0YTogYXdzX2VjMi5Vc2VyRGF0YS5jdXN0b20oJycpLFxuICAgICAgICBlbWJlZEZpbmdlcnByaW50OiBmYWxzZSxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuaW5zdGFuY2UgPSBuZXcgZWMyLkluc3RhbmNlKHRoaXMsICdEb21haW4tSW5zdGFuY2UnLCB7XG4gICAgICAgIGluc3RhbmNlVHlwZTogbmV3IGVjMi5JbnN0YW5jZVR5cGUocHJvcHMuaW5zdGFuY2VUeXBlID8/ICdtNS5sYXJnZScpLFxuICAgICAgICBtYWNoaW5lSW1hZ2U6IG5vZGVJbWFnZSxcbiAgICAgICAgdnBjOiB0aGlzLnZwYyxcbiAgICAgICAgcm9sZTogdGhpcy5ub2RlUm9sZSxcbiAgICAgICAgc2VjdXJpdHlHcm91cDogc2VjdXJpdHlHcm91cCxcbiAgICAgICAgdnBjU3VibmV0czogdGhpcy52cGMuc2VsZWN0U3VibmV0cyh7XG4gICAgICAgICAgc3VibmV0VHlwZTogcHJvcHMudXNlUHJpdmF0ZVN1Ym5ldFxuICAgICAgICAgICAgPyBlYzIuU3VibmV0VHlwZS5QUklWQVRFX1dJVEhfTkFUXG4gICAgICAgICAgICA6IGVjMi5TdWJuZXRUeXBlLlBVQkxJQyxcbiAgICAgICAgICBvbmVQZXJBejogdHJ1ZSxcbiAgICAgICAgfSksXG4gICAgICAgIGluaXQ6IGNvbmZpZyxcbiAgICAgICAgaW5pdE9wdGlvbnM6IGF0dGFjaEluaXRPcHRpb25zLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE92ZXJyaWRlIHRoZSBsb2dpY2FsIElEIG5hbWUgc28gaXQgY2FuIGJlIHJlZmVyZWVkIGJlZm9yZSBpbml0aWFsaXplZFxuICAgICAgY29uc3QgQ2ZuSW5zdGFuY2UgPSB0aGlzLmluc3RhbmNlLm5vZGUuZGVmYXVsdENoaWxkIGFzIGVjMi5DZm5JbnN0YW5jZTtcbiAgICAgIENmbkluc3RhbmNlLm92ZXJyaWRlTG9naWNhbElkKHdvcmtlck5hbWUpO1xuXG4gICAgICAvLyBPdmVycmlkZSB0aGUgZGVmYXVsdCBVc2VyRGF0YSBzY3JpcHQgdG8gZXhlY3V0ZSBvbmx5IHRoZSBjZm4taW5pdCAod2l0aG91dCBjZm4tc2lnbmFsKSBhcyB3ZSB3YW50IGNmbi1zaWduYWwgdG8gYmUgZXhlY3V0ZWQgYWZ0ZXIgcmVib290LiBNb3JlIGRldGFpbHMgaGVyZTogaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9wcmVtaXVtc3VwcG9ydC9rbm93bGVkZ2UtY2VudGVyL2NyZWF0ZS1jb21wbGV0ZS1ib290c3RyYXBwaW5nL1xuICAgICAgQ2ZuSW5zdGFuY2UudXNlckRhdGEgPSBGbi5iYXNlNjQoXG4gICAgICAgIGA8cG93ZXJzaGVsbD5jZm4taW5pdC5leGUgLXYgLXMgJHtcbiAgICAgICAgICBTdGFjay5vZih0aGlzKS5zdGFja05hbWVcbiAgICAgICAgfSAtciAke3dvcmtlck5hbWV9IC0tY29uZmlnc2V0cz1kb21haW5Kb2luUmVzdGFydCAtLXJlZ2lvbiAke1xuICAgICAgICAgIFN0YWNrLm9mKHRoaXMpLnJlZ2lvblxuICAgICAgICB9PC9wb3dlcnNoZWxsPmAsXG4gICAgICApO1xuXG4gICAgICAvLyBPdmVycmlkZSB0aGUgZGVmYXVsdCA1TSB0aW1lb3V0IHRvIHN1cHBvcnQgbG9uZ2VyIFdpbmRvd3MgYm9vdCB0aW1lXG4gICAgICBDZm5JbnN0YW5jZS5jZm5PcHRpb25zLmNyZWF0aW9uUG9saWN5ID0ge1xuICAgICAgICByZXNvdXJjZVNpZ25hbDoge1xuICAgICAgICAgIGNvdW50OiAxLFxuICAgICAgICAgIHRpbWVvdXQ6ICdQVDMwTScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmluc3RhbmNlID0gbmV3IGVjMi5JbnN0YW5jZSh0aGlzLCAnTm9uRG9tYWluLUluc3RhbmNlJywge1xuICAgICAgICBpbnN0YW5jZVR5cGU6IG5ldyBlYzIuSW5zdGFuY2VUeXBlKHByb3BzLmluc3RhbmNlVHlwZSA/PyAnbTUubGFyZ2UnKSxcbiAgICAgICAgbWFjaGluZUltYWdlOiBub2RlSW1hZ2UsXG4gICAgICAgIHZwYzogdGhpcy52cGMsXG4gICAgICAgIHJvbGU6IHRoaXMubm9kZVJvbGUsXG4gICAgICAgIHNlY3VyaXR5R3JvdXA6IHNlY3VyaXR5R3JvdXAsXG4gICAgICAgIHZwY1N1Ym5ldHM6IHRoaXMudnBjLnNlbGVjdFN1Ym5ldHMoe1xuICAgICAgICAgIHN1Ym5ldFR5cGU6IHByb3BzLnVzZVByaXZhdGVTdWJuZXRcbiAgICAgICAgICAgID8gZWMyLlN1Ym5ldFR5cGUuUFJJVkFURV9XSVRIX05BVFxuICAgICAgICAgICAgOiBlYzIuU3VibmV0VHlwZS5QVUJMSUMsXG4gICAgICAgICAgb25lUGVyQXo6IHRydWUsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQXBwZW5kIHRoZSB1c2VyIGRhdGFcbiAgICBpZiAocHJvcHMudXNlckRhdGEgIT0gJycpIHtcbiAgICAgIHRoaXMuaW5zdGFuY2UuYWRkVXNlckRhdGEocHJvcHMudXNlckRhdGEpO1xuICAgIH1cblxuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ0luc3RhbmNlSWQnLCB7XG4gICAgICB2YWx1ZTogYEluc3RhbmNlSWQ6ICR7dGhpcy5pbnN0YW5jZS5pbnN0YW5jZUlkfTsgZG5zTmFtZTogJHt0aGlzLmluc3RhbmNlLmluc3RhbmNlUHVibGljRG5zTmFtZX1gLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bm5pbmcgYmFzaCBzY3JpcHRzIG9uIHRoZSBOb2RlIHdpdGggU1NNIERvY3VtZW50LlxuICAgKiBpLmU6IHJ1blBzQ29tbWFuZHMoW1wiZWNobyAnaGVsbG8gd29ybGQnXCIsIFwiZWNobyAnU2Vjb25kIGNvbW1hbmQnXCJdLCBcIm15U2NyaXB0XCIpXG4gICAqL1xuICBydW5TaGVsbENvbW1hbmRzKFNoZWxsQ29tbWFuZHM6IHN0cmluZ1tdLCBpZDogc3RyaW5nKSB7XG4gICAgbmV3IHNzbS5DZm5Bc3NvY2lhdGlvbih0aGlzLCBpZCwge1xuICAgICAgbmFtZTogJ0FXUy1SdW5TaGVsbFNjcmlwdCcsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIGNvbW1hbmRzOiBTaGVsbENvbW1hbmRzLFxuICAgICAgfSxcbiAgICAgIHRhcmdldHM6IFt7IGtleTogJ0luc3RhbmNlSWRzJywgdmFsdWVzOiBbdGhpcy5pbnN0YW5jZS5pbnN0YW5jZUlkXSB9XSxcbiAgICAgIG1heEVycm9yczogJzUnLFxuICAgICAgbWF4Q29uY3VycmVuY3k6ICcxJyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5uaW5nIFBvd2VyU2hlbGwgc2NyaXB0cyBvbiB0aGUgTm9kZSB3aXRoIFNTTSBEb2N1bWVudC5cbiAgICogaS5lOiBydW5Qc0NvbW1hbmRzKFtcIldyaXRlLWhvc3QgJ0hlbGxvIHdvcmxkJ1wiLCBcIldyaXRlLWhvc3QgJ1NlY29uZCBjb21tYW5kJ1wiXSwgXCJteVNjcmlwdFwiKVxuICAgKi9cbiAgcnVuUHNDb21tYW5kcyhwc0NvbW1hbmRzOiBzdHJpbmdbXSwgaWQ6IHN0cmluZykge1xuICAgIG5ldyBzc20uQ2ZuQXNzb2NpYXRpb24odGhpcywgaWQsIHtcbiAgICAgIG5hbWU6ICdBV1MtUnVuUG93ZXJTaGVsbFNjcmlwdCcsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIGNvbW1hbmRzOiBwc0NvbW1hbmRzLFxuICAgICAgfSxcbiAgICAgIHRhcmdldHM6IFt7IGtleTogJ0luc3RhbmNlSWRzJywgdmFsdWVzOiBbdGhpcy5pbnN0YW5jZS5pbnN0YW5jZUlkXSB9XSxcbiAgICAgIG1heEVycm9yczogJzUnLFxuICAgICAgbWF4Q29uY3VycmVuY3k6ICcxJyxcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogT3BlbiB0aGUgc2VjdXJpdHkgZ3JvdXAgb2YgdGhlIE5vZGUgTm9kZSB0byBzcGVjaWZpYyBJUCBhZGRyZXNzIG9uIHBvcnQgMzM4OVxuICAgKiBpLmU6IG9wZW5SRFAoXCIxLjEuMS4xLzMyXCIpXG4gICAqL1xuICBvcGVuUkRQKGlwYWRkcmVzczogc3RyaW5nKSB7XG4gICAgdGhpcy5pbnN0YW5jZS5jb25uZWN0aW9ucy5hbGxvd0Zyb20oXG4gICAgICBlYzIuUGVlci5pcHY0KGlwYWRkcmVzcyksXG4gICAgICBlYzIuUG9ydC50Y3AoMzM4OSksXG4gICAgICAnQWxsb3cgUkRQJyxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bm5pbmcgUG93ZXJTaGVsbCBzY3JpcHRzIG9uIHRoZSBOb2RlIHdpdGggU1NNIERvY3VtZW50IHdpdGggRG9tYWluIEFkbWluIChVc2luZyB0aGUgU2VjcmV0IHVzZWQgdG8gam9pbiB0aGUgbWFjaGluZSB0byB0aGUgZG9tYWluKVxuICAgKiBpLmU6IHJ1blBzQ29tbWFuZHMoW1wiV3JpdGUtaG9zdCAnSGVsbG8gd29ybGQnXCIsIFwiV3JpdGUtaG9zdCAnU2Vjb25kIGNvbW1hbmQnXCJdLCBcIm15U2NyaXB0XCIpXG4gICAqIFRoZSBwcm92aWRlZCBwc0NvbW1hbmRzIHdpbGwgYmUgc3RvcmVkIGluIEM6XFxTY3JpcHRzIGFuZCB3aWxsIGJlIHJ1biB3aXRoIHNjaGVkdWxlZCB0YXNrIHdpdGggRG9tYWluIEFkbWluIHJpZ2h0c1xuICAgKi9cbiAgcnVuUFN3aXRoRG9tYWluQWRtaW4ocHNDb21tYW5kczogc3RyaW5nW10sIGlkOiBzdHJpbmcpIHtcbiAgICB2YXIgY29tbWFuZHMgPSBbJyRvbmVUaW1lUFMgPSB7J107XG4gICAgcHNDb21tYW5kcy5mb3JFYWNoKChjb21tYW5kOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbW1hbmRzLnB1c2goY29tbWFuZCk7XG4gICAgfSk7XG4gICAgY29tbWFuZHMucHVzaChcbiAgICAgICd9JyxcbiAgICAgIGBbc3RyaW5nXSRTZWNyZXRBRCAgPSAnJHt0aGlzLnBhc3N3b3JkT2JqZWN0IS5zZWNyZXROYW1lfSdgLFxuICAgICAgJyRTZWNyZXRPYmogPSBHZXQtU0VDU2VjcmV0VmFsdWUgLVNlY3JldElkICRTZWNyZXRBRCcsXG4gICAgICAnW1BTQ3VzdG9tT2JqZWN0XSRTZWNyZXQgPSAoJFNlY3JldE9iai5TZWNyZXRTdHJpbmcgIHwgQ29udmVydEZyb20tSnNvbiknLFxuICAgICAgJyRwYXNzd29yZCAgID0gJFNlY3JldC5QYXNzd29yZCB8IENvbnZlcnRUby1TZWN1cmVTdHJpbmcgLWFzUGxhaW5UZXh0IC1Gb3JjZScsXG4gICAgICBcIiR1c2VybmFtZSAgID0gJ0FkbWluJ1wiLFxuICAgICAgJyRkb21haW5fYWRtaW5fY3JlZGVudGlhbCA9IE5ldy1PYmplY3QgU3lzdGVtLk1hbmFnZW1lbnQuQXV0b21hdGlvbi5QU0NyZWRlbnRpYWwoJHVzZXJuYW1lLCRwYXNzd29yZCknLFxuICAgICAgJ05ldy1JdGVtIC1JdGVtVHlwZSBEaXJlY3RvcnkgLVBhdGggYzpcXFxcU2NyaXB0cycsXG4gICAgICAnJHRlbXBTY3JpcHRQYXRoID0gXCJDOlxcXFxTY3JpcHRzXFxcXCRQSUQucHMxXCInLFxuICAgICAgJyRvbmVUaW1lUFMgfCBzZXQtY29udGVudCAkdGVtcFNjcmlwdFBhdGgnLFxuICAgICAgJyMgQ3JlYXRlIGEgc2NoZWR1bGVkIHRhc2sgb24gc3RhcnR1cCB0byBleGVjdXRlIHRoZSBtYXBwaW5nJyxcbiAgICAgICckYWN0aW9uID0gTmV3LVNjaGVkdWxlZFRhc2tBY3Rpb24gLUV4ZWN1dGUgXCJQb3dlcnNoZWxsLmV4ZVwiIC1Bcmd1bWVudCAkdGVtcFNjcmlwdFBhdGgnLFxuICAgICAgJyR0cmlnZ2VyID0gIE5ldy1TY2hlZHVsZWRUYXNrVHJpZ2dlciAtT25jZSAtQXQgKGdldC1kYXRlKS5BZGRTZWNvbmRzKDEwKTsgJyxcbiAgICAgICckdHJpZ2dlci5FbmRCb3VuZGFyeSA9IChnZXQtZGF0ZSkuQWRkU2Vjb25kcyg2MCkuVG9TdHJpbmcoXCJzXCIpICcsXG4gICAgICAnUmVnaXN0ZXItU2NoZWR1bGVkVGFzayAtRm9yY2UgLUFjdGlvbiAkYWN0aW9uIC1UcmlnZ2VyICR0cmlnZ2VyIC1UYXNrTmFtZSBcIlRhc2sgJFBJRCB0byBydW4gd2l0aCBEb21haW5BZG1pblwiIC1EZXNjcmlwdGlvbiBcIldvcmthcm91bmQgdG8gcnVuIHRoZSBjb2RlIHdpdGggZG9tYWluIGFkbWluXCIgLVJ1bkxldmVsIEhpZ2hlc3QgLVVzZXIgJHVzZXJuYW1lIC1QYXNzd29yZCAkU2VjcmV0LlBhc3N3b3JkJyxcbiAgICApO1xuICAgIG5ldyBzc20uQ2ZuQXNzb2NpYXRpb24odGhpcywgaWQsIHtcbiAgICAgIG5hbWU6ICdBV1MtUnVuUG93ZXJTaGVsbFNjcmlwdCcsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIGNvbW1hbmRzOiBjb21tYW5kcyxcbiAgICAgIH0sXG4gICAgICB0YXJnZXRzOiBbeyBrZXk6ICdJbnN0YW5jZUlkcycsIHZhbHVlczogW3RoaXMuaW5zdGFuY2UuaW5zdGFuY2VJZF0gfV0sXG4gICAgICBtYXhFcnJvcnM6ICc1JyxcbiAgICAgIG1heENvbmN1cnJlbmN5OiAnMScsXG4gICAgfSk7XG4gIH1cblxuICBzdGFydEluc3RhbmNlKCkge1xuICAgIG5ldyBBd3NDdXN0b21SZXNvdXJjZShcbiAgICAgIHRoaXMsXG4gICAgICAnc3RhcnQtaW5zdGFuY2UtbmVlZGVkLScgKyB0aGlzLmluc3RhbmNlLmluc3RhbmNlSWQsXG4gICAgICB7XG4gICAgICAgIHBvbGljeTogQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVNka0NhbGxzKHtcbiAgICAgICAgICByZXNvdXJjZXM6IEF3c0N1c3RvbVJlc291cmNlUG9saWN5LkFOWV9SRVNPVVJDRSxcbiAgICAgICAgfSksXG4gICAgICAgIG9uVXBkYXRlOiB7XG4gICAgICAgICAgc2VydmljZTogJ0VDMicsXG4gICAgICAgICAgYWN0aW9uOiAnc3RhcnRJbnN0YW5jZXMnLCAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvQVdTL0VDMi5odG1sI3N0YXJ0SW5zdGFuY2VzLXByb3BlcnR5XG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgSW5zdGFuY2VJZHM6IFt0aGlzLmluc3RhbmNlLmluc3RhbmNlSWRdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiB7XG4gICAgICAgICAgICBpZDogJ3N0YXJ0SW5zdGFuY2UtJyArIHRoaXMuaW5zdGFuY2UuaW5zdGFuY2VJZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICApO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,82 @@
|
|
|
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_ec2 as ec2, aws_fsx } from 'aws-cdk-lib';
|
|
14
|
+
import { ISecret } from 'aws-cdk-lib/aws-secretsmanager';
|
|
15
|
+
import { Construct } from 'constructs';
|
|
16
|
+
import { DomainWindowsNode } from '../skylight-compute';
|
|
17
|
+
/**
|
|
18
|
+
* The properties for the PersistentStorage class.
|
|
19
|
+
*/
|
|
20
|
+
export interface IFSxWindowsProps {
|
|
21
|
+
/**
|
|
22
|
+
* The Filesystem size in GB
|
|
23
|
+
*
|
|
24
|
+
* @default - 200.
|
|
25
|
+
*/
|
|
26
|
+
fileSystemSize?: number;
|
|
27
|
+
/**
|
|
28
|
+
* The Filesystem throughput in MBps
|
|
29
|
+
*
|
|
30
|
+
* @default - 128.
|
|
31
|
+
*/
|
|
32
|
+
throughputMbps?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Choosing Single-AZ or Multi-AZ file system deployment
|
|
35
|
+
* See: https://docs.aws.amazon.com/fsx/latest/WindowsGuide/high-availability-multiAZ.html
|
|
36
|
+
* @default - true.
|
|
37
|
+
*/
|
|
38
|
+
multiAZ?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Deploy the Amazon FSx file system in private subnet or public subnet
|
|
41
|
+
* See: https://docs.aws.amazon.com/fsx/latest/WindowsGuide/high-availability-multiAZ.html
|
|
42
|
+
* @default - true.
|
|
43
|
+
*/
|
|
44
|
+
fileSystemInPrivateSubnet?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The VPC to use, must have private subnets.
|
|
47
|
+
*/
|
|
48
|
+
vpc: ec2.IVpc;
|
|
49
|
+
directoryId: string;
|
|
50
|
+
ssmParameters?: IFSxWindowsParameters;
|
|
51
|
+
}
|
|
52
|
+
export interface IFSxWindowsParameters {
|
|
53
|
+
/**
|
|
54
|
+
* The name of the parameter to save the FSxEndpoint DNS Endpoint
|
|
55
|
+
* @default - 'FSxEndpoint-DNS'.
|
|
56
|
+
*/
|
|
57
|
+
dnsEndpoint?: string;
|
|
58
|
+
/**
|
|
59
|
+
* The SSM namespace to read/write parameters to
|
|
60
|
+
* @default - 'cdk-skylight'.
|
|
61
|
+
*/
|
|
62
|
+
namespace?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A FSxWindows represents an integration pattern of Amazon FSx and Managed AD in a specific VPC.
|
|
66
|
+
|
|
67
|
+
* The Construct creates Amazon FSx for Windows
|
|
68
|
+
* The construct also creates (optionally) t3.nano machine that is part of the domain that can be used to run admin-tasks (such as createFolder)
|
|
69
|
+
*
|
|
70
|
+
* The createFolder() method creates an SMB Folder in the FSx filesystem, using the domain admin user.
|
|
71
|
+
* Please note: When calling createFolder() API, a Lambda will be created to start the worker machine (Using AWS-SDK),
|
|
72
|
+
* then each command will be scheduled with State Manager, and the instance will be shut down after complete .
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
export declare class FSxWindows extends Construct {
|
|
76
|
+
readonly ssmParameters: IFSxWindowsParameters;
|
|
77
|
+
readonly fsxObject: aws_fsx.CfnFileSystem;
|
|
78
|
+
readonly props: IFSxWindowsProps;
|
|
79
|
+
constructor(scope: Construct, id: string, props: IFSxWindowsProps);
|
|
80
|
+
createWorker(domainName: string, domainPassword: ISecret): DomainWindowsNode;
|
|
81
|
+
createFolder(worker: DomainWindowsNode, folderName: string, secretName: ISecret): void;
|
|
82
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.FSxWindows = 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
|
+
// Imports
|
|
19
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
20
|
+
const constructs_1 = require("constructs");
|
|
21
|
+
const skylight_compute_1 = require("../skylight-compute");
|
|
22
|
+
/**
|
|
23
|
+
* A FSxWindows represents an integration pattern of Amazon FSx and Managed AD in a specific VPC.
|
|
24
|
+
|
|
25
|
+
* The Construct creates Amazon FSx for Windows
|
|
26
|
+
* The construct also creates (optionally) t3.nano machine that is part of the domain that can be used to run admin-tasks (such as createFolder)
|
|
27
|
+
*
|
|
28
|
+
* The createFolder() method creates an SMB Folder in the FSx filesystem, using the domain admin user.
|
|
29
|
+
* Please note: When calling createFolder() API, a Lambda will be created to start the worker machine (Using AWS-SDK),
|
|
30
|
+
* then each command will be scheduled with State Manager, and the instance will be shut down after complete .
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
class FSxWindows extends constructs_1.Construct {
|
|
34
|
+
constructor(scope, id, props) {
|
|
35
|
+
super(scope, id);
|
|
36
|
+
this.props = props;
|
|
37
|
+
this.props.fileSystemInPrivateSubnet =
|
|
38
|
+
props.fileSystemInPrivateSubnet ?? true;
|
|
39
|
+
this.props.throughputMbps = props.throughputMbps ?? 128;
|
|
40
|
+
this.props.fileSystemSize = props.fileSystemSize ?? 200;
|
|
41
|
+
this.props.multiAZ = props.multiAZ ?? true;
|
|
42
|
+
this.ssmParameters = props.ssmParameters ?? {};
|
|
43
|
+
this.ssmParameters.dnsEndpoint =
|
|
44
|
+
this.ssmParameters?.dnsEndpoint ?? 'FSxEndpoint-DNS';
|
|
45
|
+
if (this.ssmParameters.namespace) {
|
|
46
|
+
this.ssmParameters.namespace = `${this.ssmParameters.namespace}/storage/fsx`;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.ssmParameters.namespace = 'cdk-skylight/storage/fsx';
|
|
50
|
+
}
|
|
51
|
+
const subnets = this.props.vpc.selectSubnets({
|
|
52
|
+
subnetType: props.fileSystemInPrivateSubnet
|
|
53
|
+
? aws_cdk_lib_1.aws_ec2.SubnetType.PRIVATE_WITH_NAT
|
|
54
|
+
: aws_cdk_lib_1.aws_ec2.SubnetType.PUBLIC,
|
|
55
|
+
}).subnetIds;
|
|
56
|
+
const windows_configuration = {
|
|
57
|
+
throughputCapacity: this.props.throughputMbps,
|
|
58
|
+
activeDirectoryId: props.directoryId,
|
|
59
|
+
deploymentType: this.props.multiAZ ? 'MULTI_AZ_1' : 'SINGLE_AZ_2',
|
|
60
|
+
preferredSubnetId: this.props.multiAZ ? subnets[0] : undefined,
|
|
61
|
+
};
|
|
62
|
+
const sg = new aws_cdk_lib_1.aws_ec2.SecurityGroup(this, id + '-FSxSG', {
|
|
63
|
+
vpc: this.props.vpc,
|
|
64
|
+
});
|
|
65
|
+
// Allow access from inside the VPC
|
|
66
|
+
sg.addIngressRule(aws_cdk_lib_1.aws_ec2.Peer.ipv4(props.vpc.vpcCidrBlock), aws_cdk_lib_1.aws_ec2.Port.allTcp());
|
|
67
|
+
const fsx_props = {
|
|
68
|
+
fileSystemType: 'WINDOWS',
|
|
69
|
+
subnetIds: props.multiAZ ? [subnets[0], subnets[1]] : [subnets[0]],
|
|
70
|
+
windowsConfiguration: windows_configuration,
|
|
71
|
+
storageCapacity: props.fileSystemSize,
|
|
72
|
+
securityGroupIds: [sg.securityGroupId],
|
|
73
|
+
};
|
|
74
|
+
this.fsxObject = new aws_cdk_lib_1.aws_fsx.CfnFileSystem(this, (id = id + '-FSxObject'), fsx_props);
|
|
75
|
+
new aws_cdk_lib_1.aws_ssm.StringParameter(this, 'ssm-dns-fsxEndpoint', {
|
|
76
|
+
parameterName: `/${this.ssmParameters.namespace}/${this.ssmParameters.dnsEndpoint}`,
|
|
77
|
+
stringValue: this.fsxObject.getAtt('DNSName').toString(),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
createWorker(domainName, domainPassword) {
|
|
81
|
+
return new skylight_compute_1.DomainWindowsNode(this, 'FSxWindowsWorker', {
|
|
82
|
+
vpc: this.props.vpc,
|
|
83
|
+
instanceType: 't3.small',
|
|
84
|
+
iamManagedPoliciesList: [
|
|
85
|
+
aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
|
|
86
|
+
aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('SecretsManagerReadWrite'),
|
|
87
|
+
aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonFSxReadOnlyAccess'),
|
|
88
|
+
],
|
|
89
|
+
domainName: domainName,
|
|
90
|
+
passwordObject: domainPassword,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
createFolder(worker, folderName, secretName) {
|
|
94
|
+
worker.startInstance();
|
|
95
|
+
worker.runPSwithDomainAdmin([
|
|
96
|
+
`$FSX = '${this.fsxObject
|
|
97
|
+
.getAtt('DNSName')
|
|
98
|
+
.toString()}' ## Amazon FSx DNS Name`,
|
|
99
|
+
'$FSxPS = (Get-FSXFileSystem | ? {$_.DNSName -contains $FSX}).WindowsConfiguration.RemoteAdministrationEndpoint',
|
|
100
|
+
`$FolderName = '${folderName}'`,
|
|
101
|
+
`[string]$SecretAD = '${secretName}'`,
|
|
102
|
+
'$SecretObj = Get-SECSecretValue -SecretId $SecretAD',
|
|
103
|
+
'[PSCustomObject]$Secret = ($SecretObj.SecretString | ConvertFrom-Json)',
|
|
104
|
+
'$password = $Secret.Password | ConvertTo-SecureString -asPlainText -Force',
|
|
105
|
+
" $username = $Secret.Domain + '\\' + $Secret.UserID ",
|
|
106
|
+
'$domain_admin_credential = New-Object System.Management.Automation.PSCredential($username,$password)',
|
|
107
|
+
'# Create the folder (the shared driver to the hosts)',
|
|
108
|
+
'New-Item -ItemType Directory -Name $FolderName -Path \\\\$FSX\\D$\\',
|
|
109
|
+
'# Set NTFS Permissions',
|
|
110
|
+
'# ACL',
|
|
111
|
+
'$ACL = Get-Acl \\\\$FSx\\D$\\$FolderName',
|
|
112
|
+
'$permission = "NT AUTHORITY\\Authenticated Users","FullControl","Allow"',
|
|
113
|
+
'$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule $permission',
|
|
114
|
+
'$ACL.SetAccessRule($Ar)',
|
|
115
|
+
'Set-Acl \\\\$FSX\\D$\\$FolderName $ACL',
|
|
116
|
+
'# Create the Share and set the share permissions',
|
|
117
|
+
'$Session = New-PSSession -ComputerName $FSxPS -ConfigurationName FsxRemoteAdmin',
|
|
118
|
+
'Import-PsSession $Session',
|
|
119
|
+
'New-FSxSmbShare -Name $FolderName -Path "D:\\$FolderName" -Description "Shared folder with gMSA access" -Credential $domain_admin_credential -FolderEnumerationMode AccessBased',
|
|
120
|
+
'$accessList="NT AUTHORITY\\Authenticated Users"',
|
|
121
|
+
'Grant-FSxSmbShareaccess -Name $FolderName -AccountName $accessList -accessRight Full -Confirm:$false',
|
|
122
|
+
'Disconnect-PSSession -Session $Session',
|
|
123
|
+
'Stop-Computer -ComputerName localhost',
|
|
124
|
+
], 'createFolder');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.FSxWindows = FSxWindows;
|
|
128
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
129
|
+
FSxWindows[_a] = { fqn: "cdk-skylight.storage.FSxWindows", version: "0.0.0" };
|
|
130
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnN4LXdpbmRvd3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2t5bGlnaHQtc3RvcmFnZS9mc3gtd2luZG93cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBOzs7Ozs7Ozs7OztHQVdHO0FBRUgsVUFBVTtBQUNWLDZDQUF3RTtBQUV4RSwyQ0FBdUM7QUFDdkMsMERBQXdEO0FBdUR4RDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBYSxVQUFXLFNBQVEsc0JBQVM7SUFJdkMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF1QjtRQUMvRCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxLQUFLLENBQUMseUJBQXlCO1lBQ2xDLEtBQUssQ0FBQyx5QkFBeUIsSUFBSSxJQUFJLENBQUM7UUFDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLGNBQWMsSUFBSSxHQUFHLENBQUM7UUFDeEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLGNBQWMsSUFBSSxHQUFHLENBQUM7UUFDeEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUM7UUFDM0MsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxJQUFJLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVc7WUFDNUIsSUFBSSxDQUFDLGFBQWEsRUFBRSxXQUFXLElBQUksaUJBQWlCLENBQUM7UUFFdkQsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLGNBQWMsQ0FBQztRQUMvRSxD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Qyx5QkFBeUIsQ0FDMUI7YUFDRjtZQUNELFVBQVUsRUFBRSxVQUFVO1lBQ3RCLGNBQWMsRUFBRSxjQUFjO1NBQy9CLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxZQUFZLENBQ1YsTUFBeUIsRUFDekIsVUFBa0IsRUFDbEIsVUFBbUI7UUFFbkIsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxvQkFBb0IsQ0FDekI7WUFDRSxXQUFXLElBQUksQ0FBQyxTQUFTO2lCQUN0QixNQUFNLENBQUMsU0FBUyxDQUFDO2lCQUNqQixRQUFRLEVBQUUsMEJBQTBCO1lBQ3ZDLGdIQUFnSDtZQUNoSCxrQkFBa0IsVUFBVSxHQUFHO1lBQy9CLHlCQUF5QixVQUFVLEdBQUc7WUFDdEMscURBQXFEO1lBQ3JELHlFQUF5RTtZQUN6RSw2RUFBNkU7WUFDN0Usd0RBQXdEO1lBQ3hELHNHQUFzRztZQUN0RyxzREFBc0Q7WUFDdEQscUVBQXFFO1lBQ3JFLHdCQUF3QjtZQUN4QixPQUFPO1lBQ1AsMENBQTBDO1lBQzFDLHlFQUF5RTtZQUN6RSxpRkFBaUY7WUFDakYseUJBQXlCO1lBQ3pCLHdDQUF3QztZQUN4QyxrREFBa0Q7WUFDbEQsaUZBQWlGO1lBQ2pGLDJCQUEyQjtZQUMzQixpTEFBaUw7WUFDakwsaURBQWlEO1lBQ2pELHNHQUFzRztZQUN0Ryx3Q0FBd0M7WUFDeEMsdUNBQXVDO1NBQ3hDLEVBQ0QsY0FBYyxDQUNmLENBQUM7SUFDSixDQUFDOztBQTFISCxnQ0EySEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqICBDb3B5cmlnaHQgMjAyMSBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpLiBZb3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiAgd2l0aCB0aGUgTGljZW5zZS4gQSBjb3B5IG9mIHRoZSBMaWNlbnNlIGlzIGxvY2F0ZWQgYXRcbiAqXG4gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBvciBpbiB0aGUgJ2xpY2Vuc2UnIGZpbGUgYWNjb21wYW55aW5nIHRoaXMgZmlsZS4gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICdBUyBJUycgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFU1xuICogIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXG4gKiAgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbi8vIEltcG9ydHNcbmltcG9ydCB7IGF3c19lYzIgYXMgZWMyLCBhd3Nfc3NtLCBhd3NfZnN4LCBhd3NfaWFtIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgSVNlY3JldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zZWNyZXRzbWFuYWdlcic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IERvbWFpbldpbmRvd3NOb2RlIH0gZnJvbSAnLi4vc2t5bGlnaHQtY29tcHV0ZSc7XG5cbi8qKlxuICogVGhlIHByb3BlcnRpZXMgZm9yIHRoZSBQZXJzaXN0ZW50U3RvcmFnZSBjbGFzcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJRlN4V2luZG93c1Byb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBGaWxlc3lzdGVtIHNpemUgaW4gR0JcbiAgICpcbiAgICogQGRlZmF1bHQgLSAyMDAuXG4gICAqL1xuICBmaWxlU3lzdGVtU2l6ZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBGaWxlc3lzdGVtIHRocm91Z2hwdXQgaW4gTUJwc1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIDEyOC5cbiAgICovXG4gIHRocm91Z2hwdXRNYnBzPzogbnVtYmVyO1xuICAvKipcbiAgICogQ2hvb3NpbmcgU2luZ2xlLUFaIG9yIE11bHRpLUFaIGZpbGUgc3lzdGVtIGRlcGxveW1lbnRcbiAgICogU2VlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZnN4L2xhdGVzdC9XaW5kb3dzR3VpZGUvaGlnaC1hdmFpbGFiaWxpdHktbXVsdGlBWi5odG1sXG4gICAqIEBkZWZhdWx0IC0gdHJ1ZS5cbiAgICovXG4gIG11bHRpQVo/OiBib29sZWFuO1xuICAvKipcbiAgICogRGVwbG95IHRoZSBBbWF6b24gRlN4IGZpbGUgc3lzdGVtIGluIHByaXZhdGUgc3VibmV0IG9yIHB1YmxpYyBzdWJuZXRcbiAgICogU2VlOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZnN4L2xhdGVzdC9XaW5kb3dzR3VpZGUvaGlnaC1hdmFpbGFiaWxpdHktbXVsdGlBWi5odG1sXG4gICAqIEBkZWZhdWx0IC0gdHJ1ZS5cbiAgICovXG4gIGZpbGVTeXN0ZW1JblByaXZhdGVTdWJuZXQ/OiBib29sZWFuO1xuICAvKipcbiAgICogVGhlIFZQQyB0byB1c2UsIG11c3QgaGF2ZSBwcml2YXRlIHN1Ym5ldHMuXG4gICAqL1xuXG4gIHZwYzogZWMyLklWcGM7XG5cbiAgZGlyZWN0b3J5SWQ6IHN0cmluZztcblxuICBzc21QYXJhbWV0ZXJzPzogSUZTeFdpbmRvd3NQYXJhbWV0ZXJzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElGU3hXaW5kb3dzUGFyYW1ldGVycyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIHRvIHNhdmUgdGhlIEZTeEVuZHBvaW50IEROUyBFbmRwb2ludFxuICAgKiBAZGVmYXVsdCAtICdGU3hFbmRwb2ludC1ETlMnLlxuICAgKi9cbiAgZG5zRW5kcG9pbnQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBTU00gbmFtZXNwYWNlIHRvIHJlYWQvd3JpdGUgcGFyYW1ldGVycyB0b1xuICAgKiBAZGVmYXVsdCAtICdjZGstc2t5bGlnaHQnLlxuICAgKi9cbiAgbmFtZXNwYWNlPzogc3RyaW5nO1xufVxuXG4vKipcbiogQSBGU3hXaW5kb3dzIHJlcHJlc2VudHMgYW4gaW50ZWdyYXRpb24gcGF0dGVybiBvZiBBbWF6b24gRlN4IGFuZCBNYW5hZ2VkIEFEIGluIGEgc3BlY2lmaWMgVlBDLlxuXG4qIFRoZSBDb25zdHJ1Y3QgY3JlYXRlcyBBbWF6b24gRlN4IGZvciBXaW5kb3dzXG4qIFRoZSBjb25zdHJ1Y3QgYWxzbyBjcmVhdGVzIChvcHRpb25hbGx5KSB0My5uYW5vIG1hY2hpbmUgdGhhdCBpcyBwYXJ0IG9mIHRoZSBkb21haW4gdGhhdCBjYW4gYmUgdXNlZCB0byBydW4gYWRtaW4tdGFza3MgKHN1Y2ggYXMgY3JlYXRlRm9sZGVyKVxuKlxuKiBUaGUgY3JlYXRlRm9sZGVyKCkgbWV0aG9kIGNyZWF0ZXMgYW4gU01CIEZvbGRlciBpbiB0aGUgRlN4IGZpbGVzeXN0ZW0sIHVzaW5nIHRoZSBkb21haW4gYWRtaW4gdXNlci5cbiogUGxlYXNlIG5vdGU6IFdoZW4gY2FsbGluZyBjcmVhdGVGb2xkZXIoKSBBUEksIGEgTGFtYmRhIHdpbGwgYmUgY3JlYXRlZCB0byBzdGFydCB0aGUgd29ya2VyIG1hY2hpbmUgKFVzaW5nIEFXUy1TREspLFxuKiB0aGVuIGVhY2ggY29tbWFuZCB3aWxsIGJlIHNjaGVkdWxlZCB3aXRoIFN0YXRlIE1hbmFnZXIsIGFuZCB0aGUgaW5zdGFuY2Ugd2lsbCBiZSBzaHV0IGRvd24gYWZ0ZXIgY29tcGxldGUgLlxuICpcbiAqL1xuZXhwb3J0IGNsYXNzIEZTeFdpbmRvd3MgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICByZWFkb25seSBzc21QYXJhbWV0ZXJzOiBJRlN4V2luZG93c1BhcmFtZXRlcnM7XG4gIHJlYWRvbmx5IGZzeE9iamVjdDogYXdzX2ZzeC5DZm5GaWxlU3lzdGVtO1xuICByZWFkb25seSBwcm9wczogSUZTeFdpbmRvd3NQcm9wcztcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElGU3hXaW5kb3dzUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLnByb3BzLmZpbGVTeXN0ZW1JblByaXZhdGVTdWJuZXQgPVxuICAgICAgcHJvcHMuZmlsZVN5c3RlbUluUHJpdmF0ZVN1Ym5ldCA/PyB0cnVlO1xuICAgIHRoaXMucHJvcHMudGhyb3VnaHB1dE1icHMgPSBwcm9wcy50aHJvdWdocHV0TWJwcyA/PyAxMjg7XG4gICAgdGhpcy5wcm9wcy5maWxlU3lzdGVtU2l6ZSA9IHByb3BzLmZpbGVTeXN0ZW1TaXplID8/IDIwMDtcbiAgICB0aGlzLnByb3BzLm11bHRpQVogPSBwcm9wcy5tdWx0aUFaID8/IHRydWU7XG4gICAgdGhpcy5zc21QYXJhbWV0ZXJzID0gcHJvcHMuc3NtUGFyYW1ldGVycyA/PyB7fTtcbiAgICB0aGlzLnNzbVBhcmFtZXRlcnMuZG5zRW5kcG9pbnQgPVxuICAgICAgdGhpcy5zc21QYXJhbWV0ZXJzPy5kbnNFbmRwb2ludCA/PyAnRlN4RW5kcG9pbnQtRE5TJztcblxuICAgIGlmICh0aGlzLnNzbVBhcmFtZXRlcnMubmFtZXNwYWNlKSB7XG4gICAgICB0aGlzLnNzbVBhcmFtZXRlcnMubmFtZXNwYWNlID0gYCR7dGhpcy5zc21QYXJhbWV0ZXJzLm5hbWVzcGFjZX0vc3RvcmFnZS9mc3hgO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNzbVBhcmFtZXRlcnMubmFtZXNwYWNlID0gJ2Nkay1za3lsaWdodC9zdG9yYWdlL2ZzeCc7XG4gICAgfVxuXG4gICAgY29uc3Qgc3VibmV0cyA9IHRoaXMucHJvcHMudnBjLnNlbGVjdFN1Ym5ldHMoe1xuICAgICAgc3VibmV0VHlwZTogcHJvcHMuZmlsZVN5c3RlbUluUHJpdmF0ZVN1Ym5ldFxuICAgICAgICA/IGVjMi5TdWJuZXRUeXBlLlBSSVZBVEVfV0lUSF9OQVRcbiAgICAgICAgOiBlYzIuU3VibmV0VHlwZS5QVUJMSUMsXG4gICAgfSkuc3VibmV0SWRzO1xuXG4gICAgY29uc3Qgd2luZG93c19jb25maWd1cmF0aW9uOiBhd3NfZnN4LkNmbkZpbGVTeXN0ZW0uV2luZG93c0NvbmZpZ3VyYXRpb25Qcm9wZXJ0eSA9XG4gICAgICB7XG4gICAgICAgIHRocm91Z2hwdXRDYXBhY2l0eTogdGhpcy5wcm9wcy50aHJvdWdocHV0TWJwcyxcbiAgICAgICAgYWN0aXZlRGlyZWN0b3J5SWQ6IHByb3BzLmRpcmVjdG9yeUlkLFxuICAgICAgICBkZXBsb3ltZW50VHlwZTogdGhpcy5wcm9wcy5tdWx0aUFaID8gJ01VTFRJX0FaXzEnIDogJ1NJTkdMRV9BWl8yJyxcbiAgICAgICAgcHJlZmVycmVkU3VibmV0SWQ6IHRoaXMucHJvcHMubXVsdGlBWiA/IHN1Ym5ldHNbMF0gOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgY29uc3Qgc2cgPSBuZXcgZWMyLlNlY3VyaXR5R3JvdXAodGhpcywgaWQgKyAnLUZTeFNHJywge1xuICAgICAgdnBjOiB0aGlzLnByb3BzLnZwYyxcbiAgICB9KTtcblxuICAgIC8vIEFsbG93IGFjY2VzcyBmcm9tIGluc2lkZSB0aGUgVlBDXG4gICAgc2cuYWRkSW5ncmVzc1J1bGUoZWMyLlBlZXIuaXB2NChwcm9wcy52cGMudnBjQ2lkckJsb2NrKSwgZWMyLlBvcnQuYWxsVGNwKCkpO1xuXG4gICAgY29uc3QgZnN4X3Byb3BzOiBhd3NfZnN4LkNmbkZpbGVTeXN0ZW1Qcm9wcyA9IHtcbiAgICAgIGZpbGVTeXN0ZW1UeXBlOiAnV0lORE9XUycsXG4gICAgICBzdWJuZXRJZHM6IHByb3BzLm11bHRpQVogPyBbc3VibmV0c1swXSwgc3VibmV0c1sxXV0gOiBbc3VibmV0c1swXV0sXG4gICAgICB3aW5kb3dzQ29uZmlndXJhdGlvbjogd2luZG93c19jb25maWd1cmF0aW9uLFxuICAgICAgc3RvcmFnZUNhcGFjaXR5OiBwcm9wcy5maWxlU3lzdGVtU2l6ZSxcbiAgICAgIHNlY3VyaXR5R3JvdXBJZHM6IFtzZy5zZWN1cml0eUdyb3VwSWRdLFxuICAgIH07XG5cbiAgICB0aGlzLmZzeE9iamVjdCA9IG5ldyBhd3NfZnN4LkNmbkZpbGVTeXN0ZW0oXG4gICAgICB0aGlzLFxuICAgICAgKGlkID0gaWQgKyAnLUZTeE9iamVjdCcpLFxuICAgICAgZnN4X3Byb3BzLFxuICAgICk7XG5cbiAgICBuZXcgYXdzX3NzbS5TdHJpbmdQYXJhbWV0ZXIodGhpcywgJ3NzbS1kbnMtZnN4RW5kcG9pbnQnLCB7XG4gICAgICBwYXJhbWV0ZXJOYW1lOiBgLyR7dGhpcy5zc21QYXJhbWV0ZXJzLm5hbWVzcGFjZX0vJHt0aGlzLnNzbVBhcmFtZXRlcnMuZG5zRW5kcG9pbnR9YCxcbiAgICAgIHN0cmluZ1ZhbHVlOiB0aGlzLmZzeE9iamVjdC5nZXRBdHQoJ0ROU05hbWUnKS50b1N0cmluZygpLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlV29ya2VyKGRvbWFpbk5hbWU6IHN0cmluZywgZG9tYWluUGFzc3dvcmQ6IElTZWNyZXQpOiBEb21haW5XaW5kb3dzTm9kZSB7XG4gICAgcmV0dXJuIG5ldyBEb21haW5XaW5kb3dzTm9kZSh0aGlzLCAnRlN4V2luZG93c1dvcmtlcicsIHtcbiAgICAgIHZwYzogdGhpcy5wcm9wcy52cGMsXG4gICAgICBpbnN0YW5jZVR5cGU6ICd0My5zbWFsbCcsXG4gICAgICBpYW1NYW5hZ2VkUG9saWNpZXNMaXN0OiBbXG4gICAgICAgIGF3c19pYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoXG4gICAgICAgICAgJ0FtYXpvblNTTU1hbmFnZWRJbnN0YW5jZUNvcmUnLFxuICAgICAgICApLFxuICAgICAgICBhd3NfaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFxuICAgICAgICAgICdTZWNyZXRzTWFuYWdlclJlYWRXcml0ZScsXG4gICAgICAgICksXG4gICAgICAgIGF3c19pYW0uTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoXG4gICAgICAgICAgJ0FtYXpvbkZTeFJlYWRPbmx5QWNjZXNzJyxcbiAgICAgICAgKSxcbiAgICAgIF0sXG4gICAgICBkb21haW5OYW1lOiBkb21haW5OYW1lLFxuICAgICAgcGFzc3dvcmRPYmplY3Q6IGRvbWFpblBhc3N3b3JkLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlRm9sZGVyKFxuICAgIHdvcmtlcjogRG9tYWluV2luZG93c05vZGUsXG4gICAgZm9sZGVyTmFtZTogc3RyaW5nLFxuICAgIHNlY3JldE5hbWU6IElTZWNyZXQsXG4gICkge1xuICAgIHdvcmtlci5zdGFydEluc3RhbmNlKCk7XG4gICAgd29ya2VyLnJ1blBTd2l0aERvbWFpbkFkbWluKFxuICAgICAgW1xuICAgICAgICBgJEZTWCA9ICcke3RoaXMuZnN4T2JqZWN0XG4gICAgICAgICAgLmdldEF0dCgnRE5TTmFtZScpXG4gICAgICAgICAgLnRvU3RyaW5nKCl9JyAjIyBBbWF6b24gRlN4IEROUyBOYW1lYCxcbiAgICAgICAgJyRGU3hQUyA9IChHZXQtRlNYRmlsZVN5c3RlbSB8ID8geyRfLkROU05hbWUgLWNvbnRhaW5zICRGU1h9KS5XaW5kb3dzQ29uZmlndXJhdGlvbi5SZW1vdGVBZG1pbmlzdHJhdGlvbkVuZHBvaW50JyxcbiAgICAgICAgYCRGb2xkZXJOYW1lID0gJyR7Zm9sZGVyTmFtZX0nYCxcbiAgICAgICAgYFtzdHJpbmddJFNlY3JldEFEICA9ICcke3NlY3JldE5hbWV9J2AsXG4gICAgICAgICckU2VjcmV0T2JqID0gR2V0LVNFQ1NlY3JldFZhbHVlIC1TZWNyZXRJZCAkU2VjcmV0QUQnLFxuICAgICAgICAnW1BTQ3VzdG9tT2JqZWN0XSRTZWNyZXQgPSAoJFNlY3JldE9iai5TZWNyZXRTdHJpbmcgIHwgQ29udmVydEZyb20tSnNvbiknLFxuICAgICAgICAnJHBhc3N3b3JkICAgPSAkU2VjcmV0LlBhc3N3b3JkIHwgQ29udmVydFRvLVNlY3VyZVN0cmluZyAtYXNQbGFpblRleHQgLUZvcmNlJyxcbiAgICAgICAgXCIgJHVzZXJuYW1lICAgPSAkU2VjcmV0LkRvbWFpbiArICdcXFxcJyArICRTZWNyZXQuVXNlcklEIFwiLFxuICAgICAgICAnJGRvbWFpbl9hZG1pbl9jcmVkZW50aWFsID0gTmV3LU9iamVjdCBTeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLlBTQ3JlZGVudGlhbCgkdXNlcm5hbWUsJHBhc3N3b3JkKScsXG4gICAgICAgICcjIENyZWF0ZSB0aGUgZm9sZGVyICh0aGUgc2hhcmVkIGRyaXZlciB0byB0aGUgaG9zdHMpJyxcbiAgICAgICAgJ05ldy1JdGVtIC1JdGVtVHlwZSBEaXJlY3RvcnkgLU5hbWUgJEZvbGRlck5hbWUgLVBhdGggXFxcXFxcXFwkRlNYXFxcXEQkXFxcXCcsXG4gICAgICAgICcjIFNldCBOVEZTIFBlcm1pc3Npb25zJyxcbiAgICAgICAgJyMgQUNMJyxcbiAgICAgICAgJyRBQ0wgPSBHZXQtQWNsIFxcXFxcXFxcJEZTeFxcXFxEJFxcXFwkRm9sZGVyTmFtZScsXG4gICAgICAgICckcGVybWlzc2lvbiA9IFwiTlQgQVVUSE9SSVRZXFxcXEF1dGhlbnRpY2F0ZWQgVXNlcnNcIixcIkZ1bGxDb250cm9sXCIsXCJBbGxvd1wiJyxcbiAgICAgICAgJyRBciA9IE5ldy1PYmplY3QgU3lzdGVtLlNlY3VyaXR5LkFjY2Vzc0NvbnRyb2wuRmlsZVN5c3RlbUFjY2Vzc1J1bGUgJHBlcm1pc3Npb24nLFxuICAgICAgICAnJEFDTC5TZXRBY2Nlc3NSdWxlKCRBciknLFxuICAgICAgICAnU2V0LUFjbCBcXFxcXFxcXCRGU1hcXFxcRCRcXFxcJEZvbGRlck5hbWUgJEFDTCcsXG4gICAgICAgICcjIENyZWF0ZSB0aGUgU2hhcmUgYW5kIHNldCB0aGUgc2hhcmUgcGVybWlzc2lvbnMnLFxuICAgICAgICAnJFNlc3Npb24gPSBOZXctUFNTZXNzaW9uIC1Db21wdXRlck5hbWUgJEZTeFBTIC1Db25maWd1cmF0aW9uTmFtZSBGc3hSZW1vdGVBZG1pbicsXG4gICAgICAgICdJbXBvcnQtUHNTZXNzaW9uICRTZXNzaW9uJyxcbiAgICAgICAgJ05ldy1GU3hTbWJTaGFyZSAtTmFtZSAkRm9sZGVyTmFtZSAtUGF0aCBcIkQ6XFxcXCRGb2xkZXJOYW1lXCIgLURlc2NyaXB0aW9uIFwiU2hhcmVkIGZvbGRlciB3aXRoIGdNU0EgYWNjZXNzXCIgLUNyZWRlbnRpYWwgJGRvbWFpbl9hZG1pbl9jcmVkZW50aWFsIC1Gb2xkZXJFbnVtZXJhdGlvbk1vZGUgQWNjZXNzQmFzZWQnLFxuICAgICAgICAnJGFjY2Vzc0xpc3Q9XCJOVCBBVVRIT1JJVFlcXFxcQXV0aGVudGljYXRlZCBVc2Vyc1wiJyxcbiAgICAgICAgJ0dyYW50LUZTeFNtYlNoYXJlYWNjZXNzIC1OYW1lICRGb2xkZXJOYW1lIC1BY2NvdW50TmFtZSAkYWNjZXNzTGlzdCAtYWNjZXNzUmlnaHQgRnVsbCAtQ29uZmlybTokZmFsc2UnLFxuICAgICAgICAnRGlzY29ubmVjdC1QU1Nlc3Npb24gLVNlc3Npb24gJFNlc3Npb24nLFxuICAgICAgICAnU3RvcC1Db21wdXRlciAtQ29tcHV0ZXJOYW1lIGxvY2FsaG9zdCcsXG4gICAgICBdLFxuICAgICAgJ2NyZWF0ZUZvbGRlcicsXG4gICAgKTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './fsx-windows';
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./fsx-windows"), exports);
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2t5bGlnaHQtc3RvcmFnZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQThCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9mc3gtd2luZG93cyc7Il19
|