magic-pocket-cli 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. magic_pocket_cli-0.2.0.dist-info/METADATA +14 -0
  2. magic_pocket_cli-0.2.0.dist-info/RECORD +65 -0
  3. magic_pocket_cli-0.2.0.dist-info/WHEEL +4 -0
  4. magic_pocket_cli-0.2.0.dist-info/entry_points.txt +2 -0
  5. pocket_cli/__init__.py +0 -0
  6. pocket_cli/cli/__init__.py +0 -0
  7. pocket_cli/cli/aws_auth.py +48 -0
  8. pocket_cli/cli/awscontainer_cli.py +328 -0
  9. pocket_cli/cli/cloudfront_cli.py +116 -0
  10. pocket_cli/cli/cloudfront_keys_cli.py +68 -0
  11. pocket_cli/cli/cloudfront_waf_cli.py +68 -0
  12. pocket_cli/cli/deploy_cli.py +274 -0
  13. pocket_cli/cli/destroy_cli.py +358 -0
  14. pocket_cli/cli/dsql_cli.py +60 -0
  15. pocket_cli/cli/main_cli.py +91 -0
  16. pocket_cli/cli/migrate_cli.py +148 -0
  17. pocket_cli/cli/neon_cli.py +97 -0
  18. pocket_cli/cli/permissions_cli.py +46 -0
  19. pocket_cli/cli/rds_cli.py +63 -0
  20. pocket_cli/cli/runtime_config_cli.py +185 -0
  21. pocket_cli/cli/s3_cli.py +69 -0
  22. pocket_cli/cli/status_cli.py +56 -0
  23. pocket_cli/cli/tidb_cli.py +73 -0
  24. pocket_cli/cli/vpc_cli.py +92 -0
  25. pocket_cli/cli/waf_cli.py +182 -0
  26. pocket_cli/django_cli.py +412 -0
  27. pocket_cli/mediator.py +220 -0
  28. pocket_cli/resources/__init__.py +0 -0
  29. pocket_cli/resources/aws/__init__.py +0 -0
  30. pocket_cli/resources/aws/builders/__init__.py +57 -0
  31. pocket_cli/resources/aws/builders/codebuild.py +363 -0
  32. pocket_cli/resources/aws/builders/depot.py +84 -0
  33. pocket_cli/resources/aws/builders/docker.py +34 -0
  34. pocket_cli/resources/aws/builders/dockerignore.py +44 -0
  35. pocket_cli/resources/aws/cloudformation.py +790 -0
  36. pocket_cli/resources/aws/ecr.py +145 -0
  37. pocket_cli/resources/aws/efs.py +138 -0
  38. pocket_cli/resources/aws/lambdahandler.py +182 -0
  39. pocket_cli/resources/aws/s3_utils.py +58 -0
  40. pocket_cli/resources/aws/state.py +74 -0
  41. pocket_cli/resources/awscontainer.py +265 -0
  42. pocket_cli/resources/cloudfront.py +491 -0
  43. pocket_cli/resources/cloudfront_acm.py +55 -0
  44. pocket_cli/resources/cloudfront_keys.py +81 -0
  45. pocket_cli/resources/cloudfront_waf.py +67 -0
  46. pocket_cli/resources/dsql.py +142 -0
  47. pocket_cli/resources/neon.py +353 -0
  48. pocket_cli/resources/rds.py +680 -0
  49. pocket_cli/resources/s3.py +307 -0
  50. pocket_cli/resources/tidb.py +298 -0
  51. pocket_cli/resources/upstash.py +152 -0
  52. pocket_cli/resources/vpc.py +67 -0
  53. pocket_cli/templates/cloudformation/awscontainer.yaml +516 -0
  54. pocket_cli/templates/cloudformation/cf_function_api_host.js +5 -0
  55. pocket_cli/templates/cloudformation/cf_function_spa_auth.js +28 -0
  56. pocket_cli/templates/cloudformation/cf_function_spa_fallback.js +8 -0
  57. pocket_cli/templates/cloudformation/cloudfront.yaml +309 -0
  58. pocket_cli/templates/cloudformation/cloudfront_acm.yaml +43 -0
  59. pocket_cli/templates/cloudformation/cloudfront_keys.yaml +32 -0
  60. pocket_cli/templates/cloudformation/cloudfront_waf.yaml +97 -0
  61. pocket_cli/templates/cloudformation/vpc.yaml +213 -0
  62. pocket_cli/templates/init/django-dotenv.env +3 -0
  63. pocket_cli/templates/init/django-settings.py +140 -0
  64. pocket_cli/templates/init/pocket.Dockerfile +26 -0
  65. pocket_cli/templates/init/pocket_simple.toml +31 -0
@@ -0,0 +1,516 @@
1
+ AWSTemplateFormatVersion: "2010-09-09"
2
+ Description: lambda configuration for webapp
3
+
4
+ Resources:
5
+ LambdaRole:
6
+ # This role must be created before the lambda function.
7
+ # https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html
8
+ # When you change Role, you must delete function and role.
9
+ # https://www.lastweekinaws.com/blog/the-sneaky-weakness-behind-aws-managed-kms-keys/
10
+ Type: AWS::IAM::Role
11
+ Properties:
12
+ AssumeRolePolicyDocument:
13
+ Statement:
14
+ - Effect: Allow
15
+ Principal:
16
+ Service: lambda.amazonaws.com
17
+ Action: "sts:AssumeRole"
18
+ ManagedPolicyArns:
19
+ - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
20
+ # {% if vpc %}
21
+ - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
22
+ # {% endif %}
23
+ # {% if use_ses %}
24
+ - arn:aws:iam::aws:policy/AmazonSESFullAccess
25
+ # {% endif %}
26
+ # {% if use_s3 %}
27
+ - arn:aws:iam::aws:policy/AmazonS3FullAccess
28
+ # {% endif %}
29
+ # {% if use_route53 %}
30
+ - arn:aws:iam::aws:policy/AmazonRoute53FullAccess
31
+ # {% endif %}
32
+ # {% if use_sqs %}
33
+ - arn:aws:iam::aws:policy/AmazonSQSFullAccess
34
+ # {% endif %}
35
+ # {% if use_efs %}
36
+ - arn:aws:iam::aws:policy/AmazonElasticFileSystemFullAccess
37
+ # {% endif %}
38
+ # {% for arn in iam.managed_policy_arns %}
39
+ - "{{ arn }}"
40
+ # {% endfor %}
41
+ Policies:
42
+ # {% if secrets and secrets.allowed_sm_resources %}
43
+ - PolicyName: "{{ resource_prefix }}access-secretsmanager"
44
+ PolicyDocument:
45
+ Version: "2012-10-17"
46
+ Statement:
47
+ - Effect: "Allow"
48
+ Action:
49
+ - "secretsmanager:GetSecretValue"
50
+ Resource:
51
+ # {% for value in secrets.allowed_sm_resources %}
52
+ - Fn::Sub: "{{ value }}"
53
+ # {% endfor %}
54
+ # {% if secrets.require_list_secrets %}
55
+ - Effect: "Allow"
56
+ Action:
57
+ - "secretsmanager:ListSecrets"
58
+ Resource:
59
+ - "*"
60
+ # {% endif %}
61
+ # {% endif %}
62
+ # {% if secrets and secrets.allowed_ssm_resources %}
63
+ - PolicyName: "{{ resource_prefix }}access-ssm"
64
+ PolicyDocument:
65
+ Version: "2012-10-17"
66
+ Statement:
67
+ - Effect: "Allow"
68
+ Action:
69
+ - "ssm:GetParameter"
70
+ - "ssm:GetParameters"
71
+ - "ssm:GetParametersByPath"
72
+ Resource:
73
+ # {% for value in secrets.allowed_ssm_resources %}
74
+ - Fn::Sub: "{{ value }}"
75
+ # {% endfor %}
76
+ # {% endif %}
77
+ # {% if rds_secret_arn %}
78
+ - PolicyName: "{{ resource_prefix }}access-rds-secret"
79
+ PolicyDocument:
80
+ Version: "2012-10-17"
81
+ Statement:
82
+ - Effect: "Allow"
83
+ Action:
84
+ - "secretsmanager:GetSecretValue"
85
+ Resource:
86
+ - "{{ rds_secret_arn }}"
87
+ # {% if rds_kms_key_id %}
88
+ - Effect: "Allow"
89
+ Action:
90
+ - "kms:Decrypt"
91
+ Resource:
92
+ - "{{ rds_kms_key_id }}"
93
+ # {% endif %}
94
+ # {% endif %}
95
+ # {% if rds_ssm_param_arn %}
96
+ - PolicyName: "{{ resource_prefix }}access-rds-ssm"
97
+ PolicyDocument:
98
+ Version: "2012-10-17"
99
+ Statement:
100
+ - Effect: "Allow"
101
+ Action:
102
+ - "ssm:GetParameter"
103
+ Resource:
104
+ - Fn::Sub: "{{ rds_ssm_param_arn }}"
105
+ # {% endif %}
106
+ # {% if use_dsql %}
107
+ - PolicyName: "{{ resource_prefix }}access-dsql"
108
+ PolicyDocument:
109
+ Version: "2012-10-17"
110
+ Statement:
111
+ - Effect: "Allow"
112
+ Action:
113
+ - "dsql:DbConnectAdmin"
114
+ Resource:
115
+ - "{{ dsql_cluster_arn }}"
116
+ # {% endif %}
117
+ - PolicyName:
118
+ Fn::Sub: "{{ resource_prefix }}access-cloudformation"
119
+ PolicyDocument:
120
+ Version: "2012-10-17"
121
+ Statement:
122
+ - Effect: "Allow"
123
+ Action:
124
+ - "cloudformation:DescribeStacks"
125
+ Resource:
126
+ - Fn::Sub: "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/{{ slug }}-*"
127
+ # {% for name, doc in iam.inline_policies.items() %}
128
+ - PolicyName: "{{ resource_prefix }}{{ name }}"
129
+ PolicyDocument: {{ doc | tojson }}
130
+ # {% endfor %}
131
+ RoleName: "lambda-{{ slug }}-{{ namespace }}"
132
+ # {% if permissions_boundary %}
133
+ PermissionsBoundary: "{{ permissions_boundary }}"
134
+ # {% endif %}
135
+
136
+ # {% if vpc %}
137
+ LambdaSecurityGroup:
138
+ Type: AWS::EC2::SecurityGroup
139
+ Properties:
140
+ GroupDescription: "{{ resource_prefix }}lambda"
141
+ GroupName: "{{ resource_prefix }}lambda"
142
+ SecurityGroupEgress:
143
+ - CidrIp: 0.0.0.0/0
144
+ Description: Allow all outbound traffic by default
145
+ IpProtocol: "-1"
146
+ Tags:
147
+ - Key: Name
148
+ Value: "{{ resource_prefix }}lambda"
149
+ VpcId:
150
+ Fn::ImportValue: "{{ export.vpc_id }}"
151
+ # {% endif %}
152
+
153
+ # {% for handler in handlers.values() %}
154
+ "{{ handler.key|capitalize }}LambdaFunction":
155
+ Type: AWS::Lambda::Function
156
+ Properties:
157
+ FunctionName: "{{ handler.function_name }}"
158
+ PackageType: Image
159
+ MemorySize: "{{ handler.memory_size }}"
160
+ Timeout: "{{ handler.timeout }}"
161
+ # {% if handler.reserved_concurrency %}
162
+ ReservedConcurrentExecutions: "{{ handler.reserved_concurrency }}"
163
+ # {% endif %}
164
+ Role:
165
+ Fn::GetAtt: LambdaRole.Arn
166
+ Code:
167
+ ImageUri:
168
+ Fn::Sub: "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/{{ ecr_name }}:{{ stage }}"
169
+ ImageConfig:
170
+ Command:
171
+ - "{{ handler.command }}"
172
+ Environment:
173
+ Variables:
174
+ "POCKET_STAGE": "{{ stage }}"
175
+ # {% for env_key, value in envs.items() %}
176
+ "{{ env_key }}": "{{ value }}"
177
+ # {% endfor %}
178
+ # {% for env_key, import_name in signing_key_imports.items() %}
179
+ "{{ env_key }}":
180
+ Fn::ImportValue: "{{ import_name }}"
181
+ # {% endfor %}
182
+ # {% if rds_secret_arn %}
183
+ "POCKET_RDS_SECRET_ARN": "{{ rds_secret_arn }}"
184
+ "POCKET_RDS_ENDPOINT": "{{ rds_endpoint }}"
185
+ "POCKET_RDS_PORT": "{{ rds_port }}"
186
+ "POCKET_RDS_DBNAME": "{{ rds_dbname }}"
187
+ # {% endif %}
188
+ # {% if rds_ssm_param_name %}
189
+ "POCKET_RDS_SECRET_STORE": "ssm"
190
+ "POCKET_RDS_SSM_PARAM": "{{ rds_ssm_param_name }}"
191
+ "POCKET_RDS_ENDPOINT": "{{ rds_endpoint }}"
192
+ "POCKET_RDS_PORT": "{{ rds_port }}"
193
+ "POCKET_RDS_DBNAME": "{{ rds_dbname }}"
194
+ # {% endif %}
195
+ # {% if use_dsql %}
196
+ "POCKET_DSQL_ENDPOINT": "{{ dsql_endpoint }}"
197
+ "POCKET_DSQL_REGION": "{{ dsql_region }}"
198
+ # {% endif %}
199
+ # {% if vpc %}
200
+ VpcConfig:
201
+ SecurityGroupIds:
202
+ - Ref: LambdaSecurityGroup
203
+ SubnetIds:
204
+ # {% for zone in vpc.zones %}
205
+ - Fn::ImportValue: "{{ export.private_subnet_ }}{{ loop.index }}"
206
+ # {% endfor %}
207
+ # {% endif %}
208
+ # {% if use_efs %}
209
+ FileSystemConfigs:
210
+ - Arn:
211
+ Fn::ImportValue: "{{ export.efs_access_point_arn }}"
212
+ LocalMountPath: "{{ efs_local_mount_path }}"
213
+ # {% endif %}
214
+ # {% endfor %}
215
+
216
+ # {% for handler in handlers.values() %}
217
+ # {% if handler.apigateway %}
218
+ "{{ handler.key|capitalize }}ApigatewayCloudWatchLogsGroup":
219
+ Type: AWS::Logs::LogGroup
220
+ Properties:
221
+ LogGroupName: "{{ slug }}-{{ handler.key }}-apigateway"
222
+ RetentionInDays: 365
223
+
224
+ "{{ handler.key|capitalize }}Api":
225
+ Type: AWS::ApiGatewayV2::Api
226
+ Properties:
227
+ Name: "{{ slug }}-{{ handler.key }}"
228
+ ProtocolType: HTTP
229
+ Target:
230
+ Fn::GetAtt: "{{ handler.key|capitalize }}LambdaFunction.Arn"
231
+ DisableExecuteApiEndpoint: "{{ handler.apigateway.disable_execute_api_endpoint }}"
232
+
233
+ "{{ handler.key|capitalize }}ApiGatewayManagedOverrides":
234
+ Type: AWS::ApiGatewayV2::ApiGatewayManagedOverrides
235
+ Properties:
236
+ ApiId:
237
+ Ref: "{{ handler.key|capitalize }}Api"
238
+ Stage:
239
+ AutoDeploy: true
240
+ AccessLogSettings:
241
+ DestinationArn:
242
+ Fn::GetAtt: "{{ handler.key|capitalize }}ApigatewayCloudWatchLogsGroup.Arn"
243
+ Format: >-
244
+ {"requestTime": "$context.requestTime",
245
+ "requestId": "$context.requestId",
246
+ "httpMethod": "$context.httpMethod",
247
+ "path": "$context.path",
248
+ "routeKey": "$context.routeKey",
249
+ "status": $context.status,
250
+ "responseLatency": $context.responseLatency,
251
+ "integrationRequestId": "$context.integration.requestId",
252
+ "functionResponseStatus": "$context.integration.status",
253
+ "integrationLatency": "$context.integration.latency",
254
+ "integrationServiceStatus": "$context.integration.integrationStatus",
255
+ "integrationErrorMessage": "$context.integrationErrorMessage",
256
+ "ip": "$context.identity.sourceIp",
257
+ "userAgent": "$context.identity.userAgent"}
258
+
259
+ "{{ handler.key|capitalize }}Route":
260
+ Type: AWS::ApiGatewayV2::Route
261
+ DependsOn:
262
+ - "{{ handler.key|capitalize }}Integration"
263
+ Properties:
264
+ ApiId:
265
+ Ref: "{{ handler.key|capitalize }}Api"
266
+ RouteKey: "ANY /{proxy+}"
267
+ Target:
268
+ Fn::Join:
269
+ - /
270
+ - - integrations
271
+ - Ref: "{{ handler.key|capitalize }}Integration"
272
+
273
+ "{{ handler.key|capitalize }}Integration":
274
+ Type: AWS::ApiGatewayV2::Integration
275
+ Properties:
276
+ ApiId:
277
+ Ref: "{{ handler.key|capitalize }}Api"
278
+ IntegrationType: AWS_PROXY
279
+ IntegrationUri:
280
+ Fn::Join:
281
+ - ""
282
+ - - "arn:"
283
+ - Ref: "AWS::Partition"
284
+ - ":apigateway:"
285
+ - Ref: "AWS::Region"
286
+ - ":lambda:path/2015-03-31/functions/"
287
+ - Fn::GetAtt: "{{ handler.key|capitalize }}LambdaFunction.Arn"
288
+ - /invocations
289
+ PayloadFormatVersion: "2.0"
290
+
291
+ "{{ handler.key|capitalize }}Permission":
292
+ Type: AWS::Lambda::Permission
293
+ Properties:
294
+ FunctionName:
295
+ Ref: "{{ handler.key|capitalize }}LambdaFunction"
296
+ Action: lambda:InvokeFunction
297
+ Principal: apigateway.amazonaws.com
298
+ SourceArn:
299
+ Fn::Join:
300
+ - ""
301
+ - - "arn:"
302
+ - Ref: "AWS::Partition"
303
+ - ":execute-api:"
304
+ - Ref: "AWS::Region"
305
+ - ":"
306
+ - Ref: "AWS::AccountId"
307
+ - ":"
308
+ - Ref: "{{ handler.key|capitalize }}Api"
309
+ - "/*/*"
310
+ # {% endif %}
311
+
312
+ # {% if handler.apigateway.domain %}
313
+ "{{ handler.cloudformation_cert_ref_name }}":
314
+ Type: AWS::CertificateManager::Certificate
315
+ Properties:
316
+ DomainName: "{{ handler.apigateway.domain }}"
317
+ # {% if handler.apigateway.create_records %}
318
+ DomainValidationOptions:
319
+ - DomainName: "{{ handler.apigateway.domain }}"
320
+ HostedZoneId: "{{ handler.apigateway.hosted_zone_id }}"
321
+ # {% endif %}
322
+ Tags:
323
+ - Key: Name
324
+ Value: "{{ slug }}-{{ handler.key }}-cert"
325
+ ValidationMethod: DNS
326
+
327
+ ##### Warning #####
328
+ # Api Gateway does not support http, so you must use http.
329
+ # Moreover you can not just redirect http to https.
330
+ # - https://stackoverflow.com/a/58683733
331
+ # - https://stackoverflow.com/q/47311081
332
+ ###################
333
+ "{{ handler.key|capitalize }}ApiGatewayDomainName":
334
+ Type: AWS::ApiGatewayV2::DomainName
335
+ Properties:
336
+ DomainName: "{{ handler.apigateway.domain }}"
337
+ DomainNameConfigurations:
338
+ - CertificateArn:
339
+ Ref: "{{ handler.cloudformation_cert_ref_name }}"
340
+
341
+ # {% if handler.apigateway.create_records %}
342
+ "{{ handler.key|capitalize }}DNSRecord":
343
+ Type: AWS::Route53::RecordSet
344
+ Properties:
345
+ HostedZoneId: "{{ handler.apigateway.hosted_zone_id }}"
346
+ Name: "{{ handler.apigateway.domain }}"
347
+ Type: A
348
+ AliasTarget:
349
+ HostedZoneId:
350
+ Fn::GetAtt: "{{ handler.key|capitalize }}ApiGatewayDomainName.RegionalHostedZoneId"
351
+ DNSName:
352
+ Fn::GetAtt: "{{ handler.key|capitalize }}ApiGatewayDomainName.RegionalDomainName"
353
+ # {% endif %}
354
+
355
+ "{{ handler.key|capitalize }}ApiGatewayApiMapping":
356
+ DependsOn:
357
+ - "{{ handler.key|capitalize }}ApiGatewayDomainName"
358
+ Type: "AWS::ApiGatewayV2::ApiMapping"
359
+ Properties:
360
+ DomainName: "{{ handler.apigateway.domain }}"
361
+ ApiId:
362
+ Ref: "{{ handler.key|capitalize }}Api"
363
+ Stage: "$default"
364
+ # {% endif %}
365
+ # {% endfor %}
366
+
367
+ # {% for handler in handlers.values() %}
368
+ # {% if handler.sqs %}
369
+ "{{ handler.key|capitalize }}SqsQueue":
370
+ Type: AWS::SQS::Queue
371
+ Properties:
372
+ QueueName:
373
+ Fn::Sub: "{{ handler.sqs.name }}"
374
+ RedrivePolicy:
375
+ deadLetterTargetArn:
376
+ Fn::GetAtt: "{{ handler.key|capitalize }}DeadLetterQueue.Arn"
377
+ maxReceiveCount: "{{ handler.sqs.dead_letter_max_receive_count }}"
378
+ VisibilityTimeout: "{{ handler.sqs.visibility_timeout }}"
379
+ # default 4 days
380
+ MessageRetentionPeriod: "{{ handler.sqs.message_retention_period }}"
381
+
382
+ "{{ handler.key|capitalize }}DeadLetterQueue":
383
+ Type: AWS::SQS::Queue
384
+ Properties:
385
+ QueueName:
386
+ Fn::Sub: "{{ handler.sqs.name }}-dead-letter"
387
+ # max 14 days
388
+ MessageRetentionPeriod: "{{ handler.sqs.dead_letter_message_retention_period }}"
389
+
390
+ "{{ handler.key|capitalize }}SqsEventSourceMapping":
391
+ DependsOn:
392
+ - "{{ handler.key|capitalize }}SqsQueue"
393
+ - "{{ handler.key|capitalize }}LambdaFunction"
394
+ Type: AWS::Lambda::EventSourceMapping
395
+ Properties:
396
+ EventSourceArn:
397
+ Fn::GetAtt: "{{ handler.key|capitalize }}SqsQueue.Arn"
398
+ FunctionName:
399
+ Ref: "{{ handler.key|capitalize }}LambdaFunction"
400
+ BatchSize: "{{ handler.sqs.batch_size }}"
401
+ ScalingConfig:
402
+ MaximumConcurrency: "{{ handler.sqs.maximum_concurrency }}"
403
+ # {% if handler.sqs.report_batch_item_failures %}
404
+ FunctionResponseTypes:
405
+ - "ReportBatchItemFailures"
406
+ # {% endif %}
407
+ # {% endif %}
408
+ # {% endfor %}
409
+
410
+ # {% if scheduler and scheduler.has_schedules %}
411
+ SchedulerExecutionRole:
412
+ Type: AWS::IAM::Role
413
+ Properties:
414
+ RoleName: "{{ scheduler.role_name }}"
415
+ AssumeRolePolicyDocument:
416
+ Version: "2012-10-17"
417
+ Statement:
418
+ - Effect: Allow
419
+ Principal:
420
+ Service: scheduler.amazonaws.com
421
+ Action: "sts:AssumeRole"
422
+ Policies:
423
+ - PolicyName: invoke-handlers
424
+ PolicyDocument:
425
+ Version: "2012-10-17"
426
+ Statement:
427
+ - Effect: Allow
428
+ Action:
429
+ - "lambda:InvokeFunction"
430
+ Resource:
431
+ # {% for arn in scheduler.invoked_function_arns %}
432
+ - Fn::Sub: "{{ arn }}"
433
+ # {% endfor %}
434
+
435
+ # {% for entry in scheduler.schedules %}
436
+ "{{ entry.yaml_key }}Schedule":
437
+ Type: AWS::Scheduler::Schedule
438
+ DependsOn:
439
+ - "{{ entry.handler|capitalize }}LambdaFunction"
440
+ - SchedulerExecutionRole
441
+ Properties:
442
+ Name: "{{ entry.name }}"
443
+ ScheduleExpression: "{{ entry.schedule_expression }}"
444
+ FlexibleTimeWindow:
445
+ Mode: "OFF"
446
+ Target:
447
+ Arn:
448
+ Fn::GetAtt: "{{ entry.handler|capitalize }}LambdaFunction.Arn"
449
+ RoleArn:
450
+ Fn::GetAtt: SchedulerExecutionRole.Arn
451
+ Input: {{ entry.input_json|tojson }}
452
+ # {% endfor %}
453
+ # {% endif %}
454
+
455
+ # {% if use_efs %}
456
+ LambdaEFSAccess:
457
+ Type: AWS::EC2::SecurityGroupIngress
458
+ Properties:
459
+ GroupId:
460
+ Fn::ImportValue: "{{ export.efs_security_group }}"
461
+ SourceSecurityGroupId:
462
+ Ref: LambdaSecurityGroup
463
+ IpProtocol: tcp
464
+ FromPort: 2049
465
+ ToPort: 2049
466
+ # {% endif %}
467
+
468
+ # {% if use_rds %}
469
+ LambdaRDSAccess:
470
+ Type: AWS::EC2::SecurityGroupIngress
471
+ Properties:
472
+ GroupId: "{{ rds_security_group_id }}"
473
+ SourceSecurityGroupId:
474
+ Ref: LambdaSecurityGroup
475
+ IpProtocol: tcp
476
+ FromPort: 5432
477
+ ToPort: 5432
478
+ # {% endif %}
479
+
480
+ # {% if handlers %}
481
+ Outputs:
482
+ # {% for handler in handlers.values() %}
483
+ "{{ handler.key|capitalize }}LambdaFunction":
484
+ Value:
485
+ Fn::GetAtt: "{{ handler.key|capitalize }}LambdaFunction.Arn"
486
+ # {% if handler.export_api_domain %}
487
+ "{{ handler.key|capitalize }}ApiDomain":
488
+ Value:
489
+ Fn::Sub:
490
+ - "${ApiId}.execute-api.${AWS::Region}.amazonaws.com"
491
+ - ApiId:
492
+ Ref: "{{ handler.key|capitalize }}Api"
493
+ Export:
494
+ Name: "{{ handler.export_api_domain }}"
495
+ # {% endif %}
496
+ # {% if handler.apigateway %}
497
+ "{{ handler.key|capitalize }}ApiEndpoint":
498
+ Value:
499
+ # {% if handler.apigateway.domain %}
500
+ Fn::Join:
501
+ - ""
502
+ - - "https://{{ handler.apigateway.domain }}/"
503
+ # {% else %}
504
+ Fn::GetAtt: "{{ handler.key|capitalize }}Api.ApiEndpoint"
505
+ # {% endif %}
506
+ # {% if handler.apigateway.domain %}
507
+ "{{ handler.key|capitalize }}RegionalDomainName":
508
+ Value:
509
+ Fn::GetAtt: "{{ handler.key|capitalize }}ApiGatewayDomainName.RegionalDomainName"
510
+ "{{ handler.key|capitalize }}RegionalHostedZoneId":
511
+ Value:
512
+ Fn::GetAtt: "{{ handler.key|capitalize }}ApiGatewayDomainName.RegionalHostedZoneId"
513
+ # {% endif %}
514
+ # {% endif %}
515
+ # {% endfor %}
516
+ # {% endif %}
@@ -0,0 +1,5 @@
1
+ function handler(event) {
2
+ var request = event.request;
3
+ request.headers['x-forwarded-host'] = { value: request.headers.host.value };
4
+ return request;
5
+ }
@@ -0,0 +1,28 @@
1
+ import cf from 'cloudfront';
2
+ var crypto = require('crypto');
3
+ const kvsHandle = cf.kvs('${TokenKvs}');
4
+ async function handler(event) {
5
+ var request = event.request;
6
+ var originalUri = request.uri;
7
+ var lastItem = request.uri.split('/').pop();
8
+ if (!lastItem.includes('.')) { request.uri = '{{ fallback_uri }}'; }
9
+ var cookie = request.cookies['pocket-spa-token'];
10
+ if (!cookie) { return _redirect(originalUri); }
11
+ var parts = cookie.value.split(':');
12
+ if (parts.length !== 3) { return _redirect(originalUri); }
13
+ var expiry = parseInt(parts[1], 10);
14
+ if (Math.floor(Date.now() / 1000) > expiry) { return _redirect(originalUri); }
15
+ var secret;
16
+ try { secret = await kvsHandle.get('token_secret'); }
17
+ catch (e) { return _redirect(originalUri); }
18
+ var msg = parts[0] + ':' + parts[1];
19
+ var hmac = crypto.createHmac('sha256', Buffer.from(secret, 'hex'));
20
+ var sig = hmac.update(msg).digest('hex');
21
+ if (sig !== parts[2]) { return _redirect(originalUri); }
22
+ return request;
23
+ }
24
+ function _redirect(uri) {
25
+ var next = encodeURIComponent(uri);
26
+ return { statusCode: 302, statusDescription: 'Found',
27
+ headers: { location: { value: '{{ login_path }}?next=' + next } } };
28
+ }
@@ -0,0 +1,8 @@
1
+ function handler(event) {
2
+ var request = event.request;
3
+ var lastItem = request.uri.split('/').pop();
4
+ if (!lastItem.includes('.')) {
5
+ request.uri = '{{ fallback_uri }}';
6
+ }
7
+ return request;
8
+ }