@fishawack/lab-env 2.0.2 → 3.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.
@@ -23,9 +23,12 @@ const colorize = module.exports.colorize = (str, type) => {
23
23
  }
24
24
  };
25
25
 
26
+ let latestSpinner = null;
27
+
26
28
  module.exports.Spinner = class Spinner {
27
- constructor(startMessage) {
28
- this.ora = ora(colorize(startMessage, 'info')).start();
29
+ constructor(startMessage, simple = false) {
30
+ this.ora = ora(simple ? startMessage : colorize(startMessage, 'info')).start();
31
+ latestSpinner = this;
29
32
  }
30
33
 
31
34
  update(message, status) {
@@ -37,6 +40,50 @@ module.exports.Spinner = class Spinner {
37
40
  this.ora.succeed(colorize(message, status || 'success'));
38
41
  }
39
42
  }
43
+
44
+ action(message, action, success, failure) {
45
+ return new Promise(async (resolve, reject) => {
46
+ let instance = new this.constructor(message);
47
+ let res;
48
+
49
+ try {
50
+ res = await action();
51
+
52
+ instance.update(success);
53
+ } catch (e){
54
+ instance.update(failure, 'fail');
55
+ reject(e);
56
+ }
57
+
58
+ resolve(res);
59
+ });
60
+ }
61
+
62
+ simple(message, action) {
63
+ return new Promise(async (resolve, reject) => {
64
+ let instance = new this.constructor(message, true);
65
+ let res;
66
+
67
+ try {
68
+ res = await action();
69
+
70
+ instance.ora.succeed();
71
+ } catch (e){
72
+ instance.ora.fail();
73
+ reject(e);
74
+ }
75
+
76
+ resolve(res);
77
+ });
78
+ }
79
+
80
+ ping(){
81
+ latestSpinner.ora.color = latestSpinner.ora.color === 'cyan' ? 'magenta' : 'cyan';
82
+ let message = ' - check: ';
83
+ let split = latestSpinner.ora.text.split(message);
84
+ let iteration = split[1] && +split[1].split(':')[0] || 0;
85
+ latestSpinner.ora.text = `${split[0]}${message}${iteration+1}`;
86
+ }
40
87
  };
41
88
 
42
89
  module.exports.encode = (username, password) => {
@@ -0,0 +1,295 @@
1
+ const { CloudFrontClient, CreateDistributionWithTagsCommand, CreateCloudFrontOriginAccessIdentityCommand, DeleteDistributionCommand , DeleteCloudFrontOriginAccessIdentityCommand, GetDistributionCommand, UpdateDistributionCommand, GetCloudFrontOriginAccessIdentityCommand, CreateFunctionCommand, GetFunctionCommand, UpdateFunctionCommand, PublishFunctionCommand, DeleteFunctionCommand, DescribeFunctionCommand } = require("@aws-sdk/client-cloudfront");
2
+ const fs = require('fs');
3
+ const { Spinner } = require('../../libs/utilities');
4
+ const { createClient } = require('./misc.js');
5
+
6
+ module.exports.createCloudFrontDistribution = async (name, account, tags = [], FunctionARN = null, region = 'us-east-1') => {
7
+ const client = createClient(CloudFrontClient, account, region);
8
+
9
+ let OAI = await Spinner.prototype.simple(`Creating CloudFront OAI`, () => {
10
+ return client.send(
11
+ new CreateCloudFrontOriginAccessIdentityCommand({
12
+ CloudFrontOriginAccessIdentityConfig: {
13
+ CallerReference: name,
14
+ Comment: `lab-env provisioned CloudFront OAI for s3 bucket ${name}`,
15
+ }
16
+ })
17
+ )
18
+ });
19
+
20
+ let res;
21
+
22
+ try {
23
+ res = await Spinner.prototype.simple(`Creating CloudFront distribution with CloudFront OAI and tags`, () => {
24
+ return client.send(
25
+ new CreateDistributionWithTagsCommand({
26
+ DistributionConfigWithTags: {
27
+ DistributionConfig: {
28
+ Enabled: true,
29
+ CallerReference: name,
30
+ Comment: `lab-env provisioned CloudFront distribution for project ${name}`,
31
+ CustomErrorResponses: {
32
+ Items: [
33
+ {
34
+ ErrorCachingMinTTL: 0,
35
+ ErrorCode: 403,
36
+ ResponseCode: 200,
37
+ ResponsePagePath: '/index.html'
38
+ }
39
+ ],
40
+ Quantity: 1
41
+ },
42
+ DefaultCacheBehavior: {
43
+ Compress: true,
44
+ TargetOriginId: `${name}.s3.${region}.amazonaws.com`,
45
+ ViewerProtocolPolicy: 'redirect-to-https',
46
+ CachePolicyId: '658327ea-f89d-4fab-a63d-7e88639e58f6', // Built in, Managed AWS Policy - Cache Optimized
47
+ FunctionAssociations: FunctionARN && {
48
+ Items: [
49
+ {
50
+ EventType: 'viewer-request',
51
+ FunctionARN
52
+ }
53
+ ],
54
+ Quantity: 1
55
+ }
56
+ },
57
+ Origins: {
58
+ Items: [
59
+ {
60
+ DomainName: `${name}.s3.${region}.amazonaws.com`,
61
+ Id: `${name}.s3.${region}.amazonaws.com`,
62
+ S3OriginConfig: {
63
+ OriginAccessIdentity: `origin-access-identity/cloudfront/${OAI.CloudFrontOriginAccessIdentity.Id}`
64
+ }
65
+ }
66
+ ],
67
+ Quantity: 1
68
+ }
69
+ },
70
+ Tags: {
71
+ Items: [{Key: 'client', Value: account}].concat(tags)
72
+ }
73
+ }
74
+ })
75
+ )
76
+ });
77
+
78
+ await Spinner.prototype.simple(`Waiting for CloudFront distribution to deploy`, () => {
79
+ return module.exports.waitForCloudFrontDistribution(res.Distribution.Id, account);
80
+ });
81
+ } catch(e){
82
+ let Id = e.message.split(' ')[e.message.split(' ').length - 1];
83
+
84
+ res = await Spinner.prototype.simple(`Retrieving the already existing CloudFront distribution`, () => {
85
+ return client.send(
86
+ new GetDistributionCommand({ Id })
87
+ );
88
+ });
89
+ }
90
+
91
+ return res;
92
+ }
93
+
94
+ module.exports.removeCloudFrontDistribution = async (Id, account) => {
95
+ const client = createClient(CloudFrontClient, account);
96
+
97
+ let res = await Spinner.prototype.simple(`Retrieving the CloudFront distribution ${Id}`, () => {
98
+ return client.send(
99
+ new GetDistributionCommand({ Id })
100
+ );
101
+ });
102
+
103
+ let OAI = res.Distribution.DistributionConfig.Origins.Items[0].S3OriginConfig.OriginAccessIdentity.split('origin-access-identity/cloudfront/')[1];
104
+
105
+ res.Distribution.DistributionConfig.Enabled = false;
106
+
107
+ res = await Spinner.prototype.simple(`Disabling the CloudFront distribution`, () => {
108
+ return client.send(
109
+ new UpdateDistributionCommand({ DistributionConfig: res.Distribution.DistributionConfig, Id, IfMatch: res.ETag })
110
+ );
111
+ });
112
+
113
+ await Spinner.prototype.simple(`Waiting for CloudFront distribution to deploy`, () => {
114
+ return module.exports.waitForCloudFrontDistribution(res.Distribution.Id, account);
115
+ });
116
+
117
+ res = await Spinner.prototype.simple(`Deleting the CloudFront distribution`, () => {
118
+ return client.send(
119
+ new DeleteDistributionCommand({ Id, IfMatch: res.ETag })
120
+ );
121
+ });
122
+
123
+ res = await Spinner.prototype.simple(`Retrieving the CloudFront OAI`, () => {
124
+ return client.send(
125
+ new GetCloudFrontOriginAccessIdentityCommand({ Id: OAI })
126
+ );
127
+ });
128
+
129
+ res = await Spinner.prototype.simple(`Deleting the CloudFront OAI`, () => {
130
+ return client.send(
131
+ new DeleteCloudFrontOriginAccessIdentityCommand({ Id: OAI, IfMatch: res.ETag })
132
+ );
133
+ });
134
+ }
135
+
136
+ module.exports.waitForCloudFrontDistribution = async (Id, account) => {
137
+ const client = createClient(CloudFrontClient, account);
138
+
139
+ let status;
140
+
141
+ do{
142
+ await new Promise((resolve) => setTimeout(() => resolve(), 5000));
143
+
144
+ await Spinner.prototype.ping();
145
+
146
+ let check = await client.send(
147
+ new GetDistributionCommand({ Id })
148
+ );
149
+
150
+ status = check.Distribution.Status;
151
+ } while(status !== 'Deployed')
152
+ }
153
+
154
+ module.exports.createCloudFrontFunction = async (name, account, fn, config) => {
155
+ const client = createClient(CloudFrontClient, account);
156
+
157
+ let FunctionConfig = {
158
+ Comment: `lab-env provisioned cloudfront function for project ${name} using code snippet ${fn}.js`,
159
+ Runtime: `cloudfront-js-1.0`
160
+ };
161
+
162
+ let res;
163
+
164
+ try{
165
+ res = await Spinner.prototype.simple(`Creating CloudFront function`, () => {
166
+ return client.send(
167
+ new CreateFunctionCommand({
168
+ Name: name,
169
+ FunctionCode: new TextEncoder().encode(" "),
170
+ FunctionConfig
171
+ })
172
+ );
173
+ });
174
+ } catch (e){
175
+ res = await Spinner.prototype.simple(`Retrieving the already existing CloudFront function`, () => {
176
+ return client.send(
177
+ new GetFunctionCommand({
178
+ Name: name
179
+ })
180
+ );
181
+ });
182
+ }
183
+
184
+ let processedFn = fs.readFileSync(`${__dirname}/../../libs/${fn}.js`).toString();
185
+ processedFn = processedFn.replace(/<%=.*%>/g, (el) => JSON.stringify(config[el.slice(3, el.length - 2).trim()], null, 4));
186
+
187
+ res = await Spinner.prototype.simple(`Updating CloudFront function with ${fn}.js code`, () => {
188
+ return client.send(
189
+ new UpdateFunctionCommand({
190
+ Name: name,
191
+ FunctionCode: new TextEncoder().encode(processedFn),
192
+ FunctionConfig,
193
+ IfMatch: res.ETag
194
+ })
195
+ );
196
+ });
197
+
198
+ res = await Spinner.prototype.simple(`Publishing CloudFront function`, () => {
199
+ return client.send(
200
+ new PublishFunctionCommand({
201
+ Name: name,
202
+ IfMatch: res.ETag
203
+ })
204
+ );
205
+ });
206
+
207
+ return res;
208
+ }
209
+
210
+ module.exports.removeCloudFrontFunction = async (name, account) => {
211
+ const client = createClient(CloudFrontClient, account);
212
+
213
+ let res = await Spinner.prototype.simple(`Retrieving CloudFront function`, () => {
214
+ return client.send(
215
+ new GetFunctionCommand({
216
+ Name: name
217
+ })
218
+ );
219
+ });
220
+
221
+ res = await Spinner.prototype.simple(`Deleting CloudFront function`, () => {
222
+ return client.send(
223
+ new DeleteFunctionCommand({
224
+ Name: name,
225
+ IfMatch: res.ETag
226
+ })
227
+ );
228
+ });
229
+
230
+ return res;
231
+ }
232
+
233
+ module.exports.setCloudFrontFunctionAssociation = async (Id, account) => {
234
+ const client = createClient(CloudFrontClient, account);
235
+
236
+ let res = await Spinner.prototype.simple(`Retrieving CloudFront distribution`, () => {
237
+ return client.send(
238
+ new GetDistributionCommand({ Id })
239
+ );
240
+ });
241
+
242
+ let { FunctionSummary: { FunctionMetadata: { FunctionARN } } } = await Spinner.prototype.simple(`Retrieving CloudFront function`, () => {
243
+ return client.send(
244
+ new DescribeFunctionCommand({
245
+ Name: res.Distribution.DistributionConfig.CallerReference,
246
+ Stage: 'LIVE'
247
+ })
248
+ );
249
+ });
250
+
251
+ res.Distribution.DistributionConfig.DefaultCacheBehavior.FunctionAssociations = {
252
+ Items: [
253
+ {
254
+ EventType: 'viewer-request',
255
+ FunctionARN: FunctionARN
256
+ }
257
+ ],
258
+ Quantity: 1
259
+ };
260
+
261
+ res = await Spinner.prototype.simple(`Adding CloudFront function to CloudFront distribution`, () => {
262
+ return client.send(
263
+ new UpdateDistributionCommand({ DistributionConfig: res.Distribution.DistributionConfig, Id, IfMatch: res.ETag })
264
+ );
265
+ });
266
+
267
+ await Spinner.prototype.simple(`Waiting for CloudFront distribution to deploy`, () => {
268
+ return module.exports.waitForCloudFrontDistribution(res.Distribution.Id, account);
269
+ });
270
+ };
271
+
272
+ module.exports.removeCloudFrontFunctionAssociation = async (Id, account) => {
273
+ const client = createClient(CloudFrontClient, account);
274
+
275
+ let res = await Spinner.prototype.simple(`Retrieving CloudFront distribution`, () => {
276
+ return client.send(
277
+ new GetDistributionCommand({ Id })
278
+ );
279
+ });
280
+
281
+ res.Distribution.DistributionConfig.DefaultCacheBehavior.FunctionAssociations = {
282
+ Items: [],
283
+ Quantity: 0
284
+ };
285
+
286
+ res = await Spinner.prototype.simple(`Removing CloudFront function from CloudFront distribution`, () => {
287
+ return client.send(
288
+ new UpdateDistributionCommand({ DistributionConfig: res.Distribution.DistributionConfig, Id, IfMatch: res.ETag })
289
+ );
290
+ });
291
+
292
+ await Spinner.prototype.simple(`Waiting for CloudFront distribution to deploy`, () => {
293
+ return module.exports.waitForCloudFrontDistribution(res.Distribution.Id, account);
294
+ });
295
+ };
@@ -0,0 +1,170 @@
1
+ const { IAMClient, CreateUserCommand, GetUserCommand, DeleteUserCommand, AttachUserPolicyCommand, ListAttachedUserPoliciesCommand, DetachUserPolicyCommand, CreateAccessKeyCommand, DeleteAccessKeyCommand, ListAccessKeysCommand } = require("@aws-sdk/client-iam");
2
+ const { Spinner } = require('../../libs/utilities');
3
+ const { createClient } = require('./misc.js');
4
+
5
+ module.exports.createIAMUser = async (UserName, account) => {
6
+ const client = createClient(IAMClient, account);
7
+
8
+ let res;
9
+
10
+ try{
11
+ res = await Spinner.prototype.simple(`Creating IAM user ${UserName}`, () => {
12
+ return client.send(
13
+ new CreateUserCommand({ UserName })
14
+ );
15
+ });
16
+ } catch(e){
17
+ res = await Spinner.prototype.simple(`Retrieving the already existing IAM user ${UserName}`, () => {
18
+ return client.send(
19
+ new GetUserCommand({ UserName })
20
+ );
21
+ });
22
+ }
23
+
24
+ return res;
25
+ };
26
+
27
+ module.exports.createFWIAMUser = async (UserName, account) => {
28
+ await module.exports.createIAMUser(UserName, account);
29
+
30
+ await module.exports.syncFWIAMPolicies(UserName, account);
31
+
32
+ let res = await module.exports.createAccessKeySafe(UserName, account);
33
+
34
+ return res;
35
+ };
36
+
37
+ module.exports.removeIAMUser = async (UserName, account) => {
38
+ const client = createClient(IAMClient, account);
39
+
40
+ let res;
41
+
42
+ try{
43
+ await Spinner.prototype.simple(`Checking if IAM user ${UserName} exists`, () => {
44
+ return client.send(
45
+ new GetUserCommand({ UserName })
46
+ );
47
+ });
48
+
49
+ await module.exports.removeAllIAMPolicies(UserName, account);
50
+
51
+ await module.exports.removeAllAccessKeys(UserName, account);
52
+
53
+ res = await Spinner.prototype.simple(`Removing IAM user ${UserName}`, () => {
54
+ return client.send(
55
+ new DeleteUserCommand({ UserName })
56
+ );
57
+ });
58
+ } catch(e){
59
+ }
60
+
61
+ return res;
62
+ };
63
+
64
+ module.exports.attachIAMPolicy = async (UserName, account, policy) => {
65
+ const client = createClient(IAMClient, account);
66
+
67
+ let res = await Spinner.prototype.simple(`Attaching IAM policy ${policy}`, () => {
68
+ return client.send(
69
+ new AttachUserPolicyCommand({ UserName, PolicyArn: policy })
70
+ );
71
+ });
72
+
73
+ return res;
74
+ };
75
+
76
+ module.exports.syncFWIAMPolicies = async (UserName, account) => {
77
+ await module.exports.removeAllIAMPolicies(UserName, account);
78
+ await module.exports.attachIAMPolicy(UserName, account, 'arn:aws:iam::aws:policy/AmazonS3FullAccess');
79
+ await module.exports.attachIAMPolicy(UserName, account, 'arn:aws:iam::aws:policy/CloudFrontFullAccess');
80
+ };
81
+
82
+ module.exports.removeIAMPolicy = async (UserName, account, policy) => {
83
+ const client = createClient(IAMClient, account);
84
+
85
+ let res = await Spinner.prototype.simple(`Detaching IAM policy ${policy}`, () => {
86
+ return client.send(
87
+ new DetachUserPolicyCommand({ UserName, PolicyArn: policy })
88
+ );
89
+ });
90
+
91
+ return res;
92
+ };
93
+
94
+ module.exports.listIAMPolicies = async (UserName, account) => {
95
+ const client = createClient(IAMClient, account);
96
+
97
+ let res = await Spinner.prototype.simple(`Listing IAM policies`, () => {
98
+ return client.send(
99
+ new ListAttachedUserPoliciesCommand({ UserName })
100
+ );
101
+ });
102
+
103
+ return res;
104
+ };
105
+
106
+ module.exports.removeAllIAMPolicies = async (UserName, account) => {
107
+ let res = await module.exports.listIAMPolicies(UserName, account);
108
+
109
+ for(let i = 0; i < res.AttachedPolicies.length; i++){
110
+ await module.exports.removeIAMPolicy(UserName, account, res.AttachedPolicies[i].PolicyArn);
111
+ }
112
+
113
+ return res;
114
+ };
115
+
116
+ module.exports.createAccessKey = async (UserName, account) => {
117
+ const client = createClient(IAMClient, account);
118
+
119
+ let res = await Spinner.prototype.simple(`Creating access key`, () => {
120
+ return client.send(
121
+ new CreateAccessKeyCommand({ UserName })
122
+ );
123
+ });
124
+
125
+ return res;
126
+ };
127
+
128
+ module.exports.removeAccessKey = async (UserName, account, AccessKeyId) => {
129
+ const client = createClient(IAMClient, account);
130
+
131
+ let res = await Spinner.prototype.simple(`Removing access key ${AccessKeyId}`, () => {
132
+ return client.send(
133
+ new DeleteAccessKeyCommand({ AccessKeyId, UserName })
134
+ );
135
+ });
136
+
137
+ return res;
138
+ };
139
+
140
+ module.exports.listAccessKeys = async (UserName, account) => {
141
+ const client = createClient(IAMClient, account);
142
+
143
+ let res = await Spinner.prototype.simple(`Listing access keys`, () => {
144
+ return client.send(
145
+ new ListAccessKeysCommand({ UserName })
146
+ );
147
+ });
148
+
149
+ return res;
150
+ };
151
+
152
+ module.exports.removeAllAccessKeys = async (UserName, account) => {
153
+ let res = await module.exports.listAccessKeys(UserName, account);
154
+
155
+ for(let i = 0; i < res.AccessKeyMetadata.length; i++){
156
+ await module.exports.removeAccessKey(UserName, account, res.AccessKeyMetadata[i].AccessKeyId);
157
+ }
158
+
159
+ return res;
160
+ };
161
+
162
+ module.exports.createAccessKeySafe = async (UserName, account) => {
163
+ let res = await module.exports.listAccessKeys(UserName, account);
164
+
165
+ if(!res.AccessKeyMetadata.length){
166
+ res = await module.exports.createAccessKey(UserName, account);
167
+ }
168
+
169
+ return res;
170
+ };
@@ -0,0 +1,25 @@
1
+ module.exports.s3 = require("./s3.js");
2
+ module.exports.cloudfront = require("./cloudfront.js");
3
+ module.exports.iam = require("./iam.js");
4
+
5
+ module.exports.slug = (repo, client, branch) => `fw-auto-${client}-${repo}-${branch}`;
6
+
7
+ module.exports.clients = ['fishawack', 'abbvie', 'sanofigenzyme', 'gsk', 'janssen', 'astrazeneca', 'ptc', 'jazz', 'pfizer', 'heron', 'novartis', 'training'];
8
+
9
+ module.exports.static = async (name, account, tags = [], credentials = []) => {
10
+ let s3 = await module.exports.s3.createS3Bucket(name, account, tags);
11
+
12
+ let cloudfrontFunction = await module.exports.cloudfront.createCloudFrontFunction(name, account, credentials.length ? 'aws-cloudfront-auth' : 'aws-cloudfront-simple', {credentials: credentials.map(d => `Basic ${Buffer.from(`${d.username}:${d.password}`).toString('base64')}`)});
13
+
14
+ let cloudfront = await module.exports.cloudfront.createCloudFrontDistribution(name, account, tags, cloudfrontFunction.FunctionSummary.FunctionMetadata.FunctionARN);
15
+
16
+ await module.exports.s3.setS3BucketPolicy(name, account, cloudfront.Distribution.DistributionConfig.Origins.Items[0].S3OriginConfig.OriginAccessIdentity.split('origin-access-identity/cloudfront/')[1]);
17
+
18
+ let config = {
19
+ "bucket": s3.Location,
20
+ "url": `https://${cloudfront.Distribution.DomainName}`,
21
+ "cloudfront": cloudfront.Distribution.Id,
22
+ };
23
+
24
+ return config;
25
+ }
@@ -0,0 +1,9 @@
1
+ module.exports.createClient = (client, account, region = 'us-east-1') => {
2
+ delete process.env.AWS_PROFILE;
3
+
4
+ if(account){
5
+ process.env.AWS_PROFILE = account;
6
+ }
7
+
8
+ return new client({ region });
9
+ }
@@ -0,0 +1,109 @@
1
+ const { S3Client, CreateBucketCommand, DeleteBucketCommand, ListBucketsCommand, PutPublicAccessBlockCommand, PutBucketTaggingCommand, PutBucketPolicyCommand, PutObjectCommand, DeleteObjectCommand } = require("@aws-sdk/client-s3");
2
+ const { Spinner } = require('../../libs/utilities');
3
+ const { createClient } = require('./misc.js');
4
+
5
+ module.exports.createS3Bucket = async (bucket, account, tags = []) => {
6
+ const client = createClient(S3Client, account);
7
+
8
+ let res = await Spinner.prototype.simple(`Creating s3 bucket ${bucket}`, () => {
9
+ return client.send(
10
+ new CreateBucketCommand({ Bucket: bucket })
11
+ );
12
+ });
13
+
14
+ await Spinner.prototype.simple(`Blocking all public access to s3 bucket`, () => {
15
+ return client.send(
16
+ new PutPublicAccessBlockCommand({ Bucket: bucket, PublicAccessBlockConfiguration: { BlockPublicAcls: true, BlockPublicPolicy: true, IgnorePublicAcls: true, RestrictPublicBuckets: true } })
17
+ );
18
+ });
19
+
20
+ await Spinner.prototype.simple(`Adding tags to s3 bucket`, () => {
21
+ return client.send(
22
+ new PutBucketTaggingCommand({ Bucket: bucket, Tagging: {TagSet: [{Key: 'client', Value: account}].concat(tags)} })
23
+ );
24
+ });
25
+
26
+ return res;
27
+ }
28
+
29
+ module.exports.listS3Buckets = async (account) => {
30
+ const client = createClient(S3Client, account);
31
+
32
+ let res = await Spinner.prototype.simple(`Listing s3 buckets`, () => {
33
+ return client.send(
34
+ new ListBucketsCommand({})
35
+ );
36
+ });
37
+
38
+ return res;
39
+ }
40
+
41
+ module.exports.removeS3Bucket = async (bucket, account) => {
42
+ const client = createClient(S3Client, account);
43
+
44
+ await Spinner.prototype.simple(`Removing s3 bucket ${bucket}`, () => {
45
+ return client.send(
46
+ new DeleteBucketCommand({ Bucket: bucket })
47
+ );
48
+ });
49
+ }
50
+
51
+ module.exports.setS3BucketPolicy = async (bucket, account, OAI) => {
52
+ const client = createClient(S3Client, account);
53
+
54
+ let res = await Spinner.prototype.simple(`Updating s3 bucket policy`, () => {
55
+ return client.send(
56
+ new PutBucketPolicyCommand({
57
+ Bucket: bucket,
58
+ Policy: JSON.stringify({
59
+ "Version": "2008-10-17",
60
+ "Id": "PolicyForCloudFrontPrivateContent",
61
+ "Statement": [
62
+ {
63
+ "Sid": "1",
64
+ "Effect": "Allow",
65
+ "Principal": {
66
+ "AWS": `arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${OAI}`
67
+ },
68
+ "Action": "s3:GetObject",
69
+ "Resource": `arn:aws:s3:::${bucket}/*`
70
+ }
71
+ ]
72
+ })
73
+ })
74
+ );
75
+ });
76
+
77
+ return res;
78
+ }
79
+
80
+ module.exports.addFileToS3Bucket = async (bucket, account, filepath, file) => {
81
+ const client = createClient(S3Client, account);
82
+
83
+ let res = await Spinner.prototype.simple(`Adding file to s3 bucket`, () => {
84
+ return client.send(
85
+ new PutObjectCommand({
86
+ Bucket: bucket,
87
+ Body: file,
88
+ Key: filepath
89
+ })
90
+ );
91
+ });
92
+
93
+ return res;
94
+ };
95
+
96
+ module.exports.removeFileToS3Bucket = async (bucket, account, filepath) => {
97
+ const client = createClient(S3Client, account);
98
+
99
+ let res = await Spinner.prototype.simple(`Removing file from s3 bucket`, () => {
100
+ return client.send(
101
+ new DeleteObjectCommand({
102
+ Bucket: bucket,
103
+ Key: filepath
104
+ })
105
+ );
106
+ });
107
+
108
+ return res;
109
+ }
@@ -194,6 +194,19 @@ module.exports.preset = async () => {
194
194
  return inputs.preset;
195
195
  }
196
196
 
197
+ module.exports.gitlabSkip = async () => {
198
+ let inputs = await inquirer.prompt([
199
+ {
200
+ type: 'confirm',
201
+ name: 'confirm',
202
+ message: 'Do you want to test gitlab setup? (VPN required)',
203
+ default: true
204
+ }
205
+ ]);
206
+
207
+ return !inputs.confirm;
208
+ }
209
+
197
210
  module.exports.config = async () => {
198
211
  let inputs = await inquirer.prompt([
199
212
  {