eoapi-cdk 5.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.
Files changed (67) hide show
  1. package/.devcontainer/devcontainer.json +4 -0
  2. package/.github/workflows/build.yaml +73 -0
  3. package/.github/workflows/conventional-pr.yaml +26 -0
  4. package/.github/workflows/distribute.yaml +45 -0
  5. package/.github/workflows/docs.yaml +26 -0
  6. package/.github/workflows/test.yaml +13 -0
  7. package/.github/workflows/tox.yaml +24 -0
  8. package/.jsii +5058 -0
  9. package/.nvmrc +1 -0
  10. package/CHANGELOG.md +195 -0
  11. package/README.md +50 -0
  12. package/diagrams/bastion_diagram.excalidraw +1416 -0
  13. package/diagrams/bastion_diagram.png +0 -0
  14. package/diagrams/ingestor_diagram.excalidraw +2274 -0
  15. package/diagrams/ingestor_diagram.png +0 -0
  16. package/lib/bastion-host/index.d.ts +117 -0
  17. package/lib/bastion-host/index.js +162 -0
  18. package/lib/bootstrapper/index.d.ts +57 -0
  19. package/lib/bootstrapper/index.js +73 -0
  20. package/lib/bootstrapper/runtime/Dockerfile +18 -0
  21. package/lib/bootstrapper/runtime/handler.py +235 -0
  22. package/lib/database/index.d.ts +60 -0
  23. package/lib/database/index.js +84 -0
  24. package/lib/database/instance-memory.json +525 -0
  25. package/lib/index.d.ts +6 -0
  26. package/lib/index.js +19 -0
  27. package/lib/ingestor-api/index.d.ts +54 -0
  28. package/lib/ingestor-api/index.js +147 -0
  29. package/lib/ingestor-api/runtime/dev_requirements.txt +2 -0
  30. package/lib/ingestor-api/runtime/requirements.txt +12 -0
  31. package/lib/ingestor-api/runtime/src/__init__.py +0 -0
  32. package/lib/ingestor-api/runtime/src/collection.py +36 -0
  33. package/lib/ingestor-api/runtime/src/config.py +46 -0
  34. package/lib/ingestor-api/runtime/src/dependencies.py +94 -0
  35. package/lib/ingestor-api/runtime/src/handler.py +9 -0
  36. package/lib/ingestor-api/runtime/src/ingestor.py +82 -0
  37. package/lib/ingestor-api/runtime/src/loader.py +21 -0
  38. package/lib/ingestor-api/runtime/src/main.py +125 -0
  39. package/lib/ingestor-api/runtime/src/schemas.py +148 -0
  40. package/lib/ingestor-api/runtime/src/services.py +44 -0
  41. package/lib/ingestor-api/runtime/src/utils.py +52 -0
  42. package/lib/ingestor-api/runtime/src/validators.py +72 -0
  43. package/lib/ingestor-api/runtime/tests/__init__.py +0 -0
  44. package/lib/ingestor-api/runtime/tests/conftest.py +271 -0
  45. package/lib/ingestor-api/runtime/tests/test_collection.py +35 -0
  46. package/lib/ingestor-api/runtime/tests/test_collection_endpoint.py +41 -0
  47. package/lib/ingestor-api/runtime/tests/test_ingestor.py +60 -0
  48. package/lib/ingestor-api/runtime/tests/test_registration.py +198 -0
  49. package/lib/ingestor-api/runtime/tests/test_utils.py +35 -0
  50. package/lib/stac-api/index.d.ts +50 -0
  51. package/lib/stac-api/index.js +60 -0
  52. package/lib/stac-api/runtime/requirements.txt +8 -0
  53. package/lib/stac-api/runtime/src/__init__.py +0 -0
  54. package/lib/stac-api/runtime/src/app.py +58 -0
  55. package/lib/stac-api/runtime/src/config.py +96 -0
  56. package/lib/stac-api/runtime/src/handler.py +9 -0
  57. package/lib/titiler-pgstac-api/index.d.ts +33 -0
  58. package/lib/titiler-pgstac-api/index.js +67 -0
  59. package/lib/titiler-pgstac-api/runtime/Dockerfile +20 -0
  60. package/lib/titiler-pgstac-api/runtime/dev_requirements.txt +1 -0
  61. package/lib/titiler-pgstac-api/runtime/requirements.txt +3 -0
  62. package/lib/titiler-pgstac-api/runtime/src/__init__.py +3 -0
  63. package/lib/titiler-pgstac-api/runtime/src/handler.py +23 -0
  64. package/lib/titiler-pgstac-api/runtime/src/utils.py +26 -0
  65. package/package.json +81 -0
  66. package/tox.ini +52 -0
  67. package/tsconfig.tsbuildinfo +18116 -0
Binary file
@@ -0,0 +1,117 @@
1
+ import { aws_ec2 as ec2, aws_rds as rds } from "aws-cdk-lib";
2
+ import { Construct } from "constructs";
3
+ /**
4
+ * The database is located in an isolated subnet, meaning that it is not accessible from the public internet. As such, to interact with the database directly, a user must tunnel through a bastion host.
5
+ *
6
+ * ### Configuring
7
+ *
8
+ * This codebase controls _who_ is allowed to connect to the bastion host. This requires two steps:
9
+ *
10
+ * 1. Adding the IP address from which you are connecting to the `ipv4Allowlist` array
11
+ * 1. Creating a bastion host system user by adding the user's configuration inform to `userdata.yaml`
12
+ *
13
+ * #### Adding an IP address to the `ipv4Allowlist` array
14
+ *
15
+ * The `BastionHost` construct takes in an `ipv4Allowlist` array as an argument. Find your IP address (eg `curl api.ipify.org`) and add that to the array along with the trailing CIDR block (likely `/32` to indicate that you are adding a single IP address).
16
+ *
17
+ * #### Creating a user via `userdata.yaml`
18
+ *
19
+ * Add an entry to the `users` array with a username (likely matching your local systems username, which you can get by running the `whoami` command in your terminal) and a public key (likely your default public key, which you can get by running `cat ~/.ssh/id_*.pub` in your terminal).
20
+ *
21
+ * #### Tips & Tricks when using the Bastion Host
22
+ *
23
+ * **Connecting to RDS Instance via SSM**
24
+ *
25
+ * ```sh
26
+ * aws ssm start-session --target $INSTANCE_ID \
27
+ * --document-name AWS-StartPortForwardingSessionToRemoteHost \
28
+ * --parameters '{
29
+ * "host": [
30
+ * "example-db.c5abcdefghij.us-west-2.rds.amazonaws.com"
31
+ * ],
32
+ * "portNumber": [
33
+ * "5432"
34
+ * ],
35
+ * "localPortNumber": [
36
+ * "9999"
37
+ * ]
38
+ * }' \
39
+ * --profile $AWS_PROFILE
40
+ * ```
41
+ *
42
+ * ```sh
43
+ * psql -h localhost -p 9999 # continue adding username (-U) and db (-d) here...
44
+ * ```
45
+ *
46
+ * Connect directly to Bastion Host:
47
+ *
48
+ * ```sh
49
+ * aws ssm start-session --target $INSTANCE_ID --profile $AWS_PROFILE
50
+ * ```
51
+ *
52
+ * **Setting up an SSH tunnel**
53
+ *
54
+ * In your `~/.ssh/config` file, add an entry like:
55
+ *
56
+ * ```
57
+ * Host db-tunnel
58
+ * Hostname {the-bastion-host-address}
59
+ * LocalForward 9999 {the-db-hostname}:5432
60
+ * ```
61
+ *
62
+ * Then a tunnel can be opened via:
63
+ *
64
+ * ```
65
+ * ssh -N db-tunnel
66
+ * ```
67
+ *
68
+ * And a connection to the DB can be made via:
69
+ *
70
+ * ```
71
+ * psql -h 127.0.0.1 -p 9999 -U {username} -d {database}
72
+ * ```
73
+ *
74
+ * **Handling `REMOTE HOST IDENTIFICATION HAS CHANGED!` error**
75
+ *
76
+ * If you've redeployed a bastion host that you've previously connected to, you may see an error like:
77
+ *
78
+ * ```
79
+ * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
80
+ * @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
81
+ * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
82
+ * IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
83
+ * Someone could be eavesdropping on you right now (man-in-the-middle attack)!
84
+ * It is also possible that a host key has just been changed.
85
+ * The fingerprint for the ECDSA key sent by the remote host is
86
+ * SHA256:mPnxAOXTpb06PFgI1Qc8TMQ2e9b7goU8y2NdS5hzIr8.
87
+ * Please contact your system administrator.
88
+ * Add correct host key in /Users/username/.ssh/known_hosts to get rid of this message.
89
+ * Offending ECDSA key in /Users/username/.ssh/known_hosts:28
90
+ * ECDSA host key for ec2-12-34-56-789.us-west-2.compute.amazonaws.com has changed and you have requested strict checking.
91
+ * Host key verification failed.
92
+ * ```
93
+ *
94
+ * This is due to the server's fingerprint changing. We can scrub the fingerprint from our system with a command like:
95
+ *
96
+ * ```
97
+ * ssh-keygen -R 12.34.56.789
98
+ * ```
99
+ *
100
+ */
101
+ export declare class BastionHost extends Construct {
102
+ instance: ec2.Instance;
103
+ constructor(scope: Construct, id: string, props: BastionHostProps);
104
+ }
105
+ export interface BastionHostProps {
106
+ readonly vpc: ec2.IVpc;
107
+ readonly db: rds.IDatabaseInstance;
108
+ readonly userData: ec2.UserData;
109
+ readonly ipv4Allowlist: string[];
110
+ readonly sshPort?: number;
111
+ /**
112
+ * Whether or not an elastic IP should be created for the bastion host.
113
+ *
114
+ * @default false
115
+ */
116
+ readonly createElasticIp?: boolean;
117
+ }
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.BastionHost = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const constructs_1 = require("constructs");
8
+ /**
9
+ * The database is located in an isolated subnet, meaning that it is not accessible from the public internet. As such, to interact with the database directly, a user must tunnel through a bastion host.
10
+ *
11
+ * ### Configuring
12
+ *
13
+ * This codebase controls _who_ is allowed to connect to the bastion host. This requires two steps:
14
+ *
15
+ * 1. Adding the IP address from which you are connecting to the `ipv4Allowlist` array
16
+ * 1. Creating a bastion host system user by adding the user's configuration inform to `userdata.yaml`
17
+ *
18
+ * #### Adding an IP address to the `ipv4Allowlist` array
19
+ *
20
+ * The `BastionHost` construct takes in an `ipv4Allowlist` array as an argument. Find your IP address (eg `curl api.ipify.org`) and add that to the array along with the trailing CIDR block (likely `/32` to indicate that you are adding a single IP address).
21
+ *
22
+ * #### Creating a user via `userdata.yaml`
23
+ *
24
+ * Add an entry to the `users` array with a username (likely matching your local systems username, which you can get by running the `whoami` command in your terminal) and a public key (likely your default public key, which you can get by running `cat ~/.ssh/id_*.pub` in your terminal).
25
+ *
26
+ * #### Tips & Tricks when using the Bastion Host
27
+ *
28
+ * **Connecting to RDS Instance via SSM**
29
+ *
30
+ * ```sh
31
+ * aws ssm start-session --target $INSTANCE_ID \
32
+ * --document-name AWS-StartPortForwardingSessionToRemoteHost \
33
+ * --parameters '{
34
+ * "host": [
35
+ * "example-db.c5abcdefghij.us-west-2.rds.amazonaws.com"
36
+ * ],
37
+ * "portNumber": [
38
+ * "5432"
39
+ * ],
40
+ * "localPortNumber": [
41
+ * "9999"
42
+ * ]
43
+ * }' \
44
+ * --profile $AWS_PROFILE
45
+ * ```
46
+ *
47
+ * ```sh
48
+ * psql -h localhost -p 9999 # continue adding username (-U) and db (-d) here...
49
+ * ```
50
+ *
51
+ * Connect directly to Bastion Host:
52
+ *
53
+ * ```sh
54
+ * aws ssm start-session --target $INSTANCE_ID --profile $AWS_PROFILE
55
+ * ```
56
+ *
57
+ * **Setting up an SSH tunnel**
58
+ *
59
+ * In your `~/.ssh/config` file, add an entry like:
60
+ *
61
+ * ```
62
+ * Host db-tunnel
63
+ * Hostname {the-bastion-host-address}
64
+ * LocalForward 9999 {the-db-hostname}:5432
65
+ * ```
66
+ *
67
+ * Then a tunnel can be opened via:
68
+ *
69
+ * ```
70
+ * ssh -N db-tunnel
71
+ * ```
72
+ *
73
+ * And a connection to the DB can be made via:
74
+ *
75
+ * ```
76
+ * psql -h 127.0.0.1 -p 9999 -U {username} -d {database}
77
+ * ```
78
+ *
79
+ * **Handling `REMOTE HOST IDENTIFICATION HAS CHANGED!` error**
80
+ *
81
+ * If you've redeployed a bastion host that you've previously connected to, you may see an error like:
82
+ *
83
+ * ```
84
+ * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
85
+ * @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
86
+ * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
87
+ * IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
88
+ * Someone could be eavesdropping on you right now (man-in-the-middle attack)!
89
+ * It is also possible that a host key has just been changed.
90
+ * The fingerprint for the ECDSA key sent by the remote host is
91
+ * SHA256:mPnxAOXTpb06PFgI1Qc8TMQ2e9b7goU8y2NdS5hzIr8.
92
+ * Please contact your system administrator.
93
+ * Add correct host key in /Users/username/.ssh/known_hosts to get rid of this message.
94
+ * Offending ECDSA key in /Users/username/.ssh/known_hosts:28
95
+ * ECDSA host key for ec2-12-34-56-789.us-west-2.compute.amazonaws.com has changed and you have requested strict checking.
96
+ * Host key verification failed.
97
+ * ```
98
+ *
99
+ * This is due to the server's fingerprint changing. We can scrub the fingerprint from our system with a command like:
100
+ *
101
+ * ```
102
+ * ssh-keygen -R 12.34.56.789
103
+ * ```
104
+ *
105
+ */
106
+ class BastionHost extends constructs_1.Construct {
107
+ constructor(scope, id, props) {
108
+ super(scope, id);
109
+ const { stackName } = aws_cdk_lib_1.Stack.of(this);
110
+ // Build ec2 instance
111
+ this.instance = new aws_cdk_lib_1.aws_ec2.Instance(this, "bastion-host", {
112
+ vpc: props.vpc,
113
+ vpcSubnets: { subnetType: aws_cdk_lib_1.aws_ec2.SubnetType.PUBLIC },
114
+ instanceName: `${stackName} bastion host`,
115
+ instanceType: aws_cdk_lib_1.aws_ec2.InstanceType.of(aws_cdk_lib_1.aws_ec2.InstanceClass.BURSTABLE4_GRAVITON, aws_cdk_lib_1.aws_ec2.InstanceSize.NANO),
116
+ machineImage: aws_cdk_lib_1.aws_ec2.MachineImage.latestAmazonLinux({
117
+ generation: aws_cdk_lib_1.aws_ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
118
+ cpuType: aws_cdk_lib_1.aws_ec2.AmazonLinuxCpuType.ARM_64,
119
+ }),
120
+ userData: props.userData,
121
+ userDataCausesReplacement: true,
122
+ });
123
+ // Assign elastic IP
124
+ if (props.createElasticIp ?? true) {
125
+ new aws_cdk_lib_1.aws_ec2.CfnEIP(this, "IP", {
126
+ instanceId: this.instance.instanceId,
127
+ tags: [{ key: "Name", value: stackName }],
128
+ });
129
+ }
130
+ // Allow bastion host to connect to db
131
+ this.instance.connections.allowTo(props.db.connections.securityGroups[0], aws_cdk_lib_1.aws_ec2.Port.tcp(5432), "Allow connection from bastion host");
132
+ // Allow IP access to bastion host
133
+ for (const ipv4 of props.ipv4Allowlist) {
134
+ this.instance.connections.allowFrom(aws_cdk_lib_1.aws_ec2.Peer.ipv4(ipv4), aws_cdk_lib_1.aws_ec2.Port.tcp(props.sshPort || 22), "SSH Access");
135
+ }
136
+ // Integrate with SSM
137
+ this.instance.addToRolePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
138
+ actions: [
139
+ "ssmmessages:*",
140
+ "ssm:UpdateInstanceInformation",
141
+ "ec2messages:*",
142
+ ],
143
+ resources: ["*"],
144
+ }));
145
+ new aws_cdk_lib_1.CfnOutput(this, "instance-id-output", {
146
+ value: this.instance.instanceId,
147
+ exportName: `${stackName}-instance-id`,
148
+ });
149
+ new aws_cdk_lib_1.CfnOutput(this, "instance-public-ip-output", {
150
+ value: this.instance.instancePublicIp,
151
+ exportName: `${stackName}-instance-public-ip`,
152
+ });
153
+ new aws_cdk_lib_1.CfnOutput(this, "instance-public-dns-name-output", {
154
+ value: this.instance.instancePublicDnsName,
155
+ exportName: `${stackName}-public-dns-name`,
156
+ });
157
+ }
158
+ }
159
+ exports.BastionHost = BastionHost;
160
+ _a = JSII_RTTI_SYMBOL_1;
161
+ BastionHost[_a] = { fqn: "eoapi-cdk.BastionHost", version: "5.0.0" };
162
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQU1xQjtBQUNyQiwyQ0FBdUM7QUFFdkM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpR0c7QUFDSCxNQUFhLFdBQVksU0FBUSxzQkFBUztJQUd4QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXVCO1FBQy9ELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXJDLHFCQUFxQjtRQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUkscUJBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRTtZQUNyRCxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7WUFDZCxVQUFVLEVBQUUsRUFBRSxVQUFVLEVBQUUscUJBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFO1lBQ2pELFlBQVksRUFBRSxHQUFHLFNBQVMsZUFBZTtZQUN6QyxZQUFZLEVBQUUscUJBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUMvQixxQkFBRyxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsRUFDckMscUJBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUN0QjtZQUNELFlBQVksRUFBRSxxQkFBRyxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQztnQkFDL0MsVUFBVSxFQUFFLHFCQUFHLENBQUMscUJBQXFCLENBQUMsY0FBYztnQkFDcEQsT0FBTyxFQUFFLHFCQUFHLENBQUMsa0JBQWtCLENBQUMsTUFBTTthQUN2QyxDQUFDO1lBQ0YsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLHlCQUF5QixFQUFFLElBQUk7U0FDaEMsQ0FBQyxDQUFDO1FBRUgsb0JBQW9CO1FBQ3BCLElBQUksS0FBSyxDQUFDLGVBQWUsSUFBSSxJQUFJLEVBQUU7WUFDakMsSUFBSSxxQkFBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFO2dCQUN6QixVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVO2dCQUNwQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxDQUFDO2FBQzFDLENBQUMsQ0FBQztTQUNKO1FBRUQsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FDL0IsS0FBSyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUN0QyxxQkFBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQ2xCLG9DQUFvQyxDQUNyQyxDQUFDO1FBRUYsa0NBQWtDO1FBQ2xDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxDQUFDLGFBQWEsRUFBRTtZQUN0QyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQ2pDLHFCQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFDbkIscUJBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLEVBQ2pDLFlBQVksQ0FDYixDQUFDO1NBQ0g7UUFFRCxxQkFBcUI7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQzNCLElBQUkscUJBQUcsQ0FBQyxlQUFlLENBQUM7WUFDdEIsT0FBTyxFQUFFO2dCQUNQLGVBQWU7Z0JBQ2YsK0JBQStCO2dCQUMvQixlQUFlO2FBQ2hCO1lBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO1NBQ2pCLENBQUMsQ0FDSCxDQUFDO1FBRUYsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxvQkFBb0IsRUFBRTtZQUN4QyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVO1lBQy9CLFVBQVUsRUFBRSxHQUFHLFNBQVMsY0FBYztTQUN2QyxDQUFDLENBQUM7UUFDSCxJQUFJLHVCQUFTLENBQUMsSUFBSSxFQUFFLDJCQUEyQixFQUFFO1lBQy9DLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQjtZQUNyQyxVQUFVLEVBQUUsR0FBRyxTQUFTLHFCQUFxQjtTQUM5QyxDQUFDLENBQUM7UUFDSCxJQUFJLHVCQUFTLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxFQUFFO1lBQ3JELEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLHFCQUFxQjtZQUMxQyxVQUFVLEVBQUUsR0FBRyxTQUFTLGtCQUFrQjtTQUMzQyxDQUFDLENBQUM7SUFDTCxDQUFDOztBQXpFSCxrQ0EwRUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBTdGFjayxcbiAgYXdzX2VjMiBhcyBlYzIsXG4gIGF3c19pYW0gYXMgaWFtLFxuICBhd3NfcmRzIGFzIHJkcyxcbiAgQ2ZuT3V0cHV0LFxufSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5cbi8qKlxuICogVGhlIGRhdGFiYXNlIGlzIGxvY2F0ZWQgaW4gYW4gaXNvbGF0ZWQgc3VibmV0LCBtZWFuaW5nIHRoYXQgaXQgaXMgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgcHVibGljIGludGVybmV0LiBBcyBzdWNoLCB0byBpbnRlcmFjdCB3aXRoIHRoZSBkYXRhYmFzZSBkaXJlY3RseSwgYSB1c2VyIG11c3QgdHVubmVsIHRocm91Z2ggYSBiYXN0aW9uIGhvc3QuXG4gKlxuICogIyMjIENvbmZpZ3VyaW5nXG4gKlxuICogVGhpcyBjb2RlYmFzZSBjb250cm9scyBfd2hvXyBpcyBhbGxvd2VkIHRvIGNvbm5lY3QgdG8gdGhlIGJhc3Rpb24gaG9zdC4gVGhpcyByZXF1aXJlcyB0d28gc3RlcHM6XG4gKlxuICogMS4gQWRkaW5nIHRoZSBJUCBhZGRyZXNzIGZyb20gd2hpY2ggeW91IGFyZSBjb25uZWN0aW5nIHRvIHRoZSBgaXB2NEFsbG93bGlzdGAgYXJyYXlcbiAqIDEuIENyZWF0aW5nIGEgYmFzdGlvbiBob3N0IHN5c3RlbSB1c2VyIGJ5IGFkZGluZyB0aGUgdXNlcidzIGNvbmZpZ3VyYXRpb24gaW5mb3JtIHRvIGB1c2VyZGF0YS55YW1sYFxuICpcbiAqICMjIyMgQWRkaW5nIGFuIElQIGFkZHJlc3MgdG8gdGhlIGBpcHY0QWxsb3dsaXN0YCBhcnJheVxuICpcbiAqIFRoZSBgQmFzdGlvbkhvc3RgIGNvbnN0cnVjdCB0YWtlcyBpbiBhbiBgaXB2NEFsbG93bGlzdGAgYXJyYXkgYXMgYW4gYXJndW1lbnQuIEZpbmQgeW91ciBJUCBhZGRyZXNzIChlZyBgY3VybCBhcGkuaXBpZnkub3JnYCkgYW5kIGFkZCB0aGF0IHRvIHRoZSBhcnJheSBhbG9uZyB3aXRoIHRoZSB0cmFpbGluZyBDSURSIGJsb2NrIChsaWtlbHkgYC8zMmAgdG8gaW5kaWNhdGUgdGhhdCB5b3UgYXJlIGFkZGluZyBhIHNpbmdsZSBJUCBhZGRyZXNzKS5cbiAqXG4gKiAjIyMjIENyZWF0aW5nIGEgdXNlciB2aWEgYHVzZXJkYXRhLnlhbWxgXG4gKlxuICogQWRkIGFuIGVudHJ5IHRvIHRoZSBgdXNlcnNgIGFycmF5IHdpdGggYSB1c2VybmFtZSAobGlrZWx5IG1hdGNoaW5nIHlvdXIgbG9jYWwgc3lzdGVtcyB1c2VybmFtZSwgd2hpY2ggeW91IGNhbiBnZXQgYnkgcnVubmluZyB0aGUgYHdob2FtaWAgY29tbWFuZCBpbiB5b3VyIHRlcm1pbmFsKSBhbmQgYSBwdWJsaWMga2V5IChsaWtlbHkgeW91ciBkZWZhdWx0IHB1YmxpYyBrZXksIHdoaWNoIHlvdSBjYW4gZ2V0IGJ5IHJ1bm5pbmcgYGNhdCB+Ly5zc2gvaWRfKi5wdWJgIGluIHlvdXIgdGVybWluYWwpLlxuICpcbiAqICMjIyMgVGlwcyAmIFRyaWNrcyB3aGVuIHVzaW5nIHRoZSBCYXN0aW9uIEhvc3RcbiAqXG4gKiAqKkNvbm5lY3RpbmcgdG8gUkRTIEluc3RhbmNlIHZpYSBTU00qKlxuICpcbiAqIGBgYHNoXG4gKiBhd3Mgc3NtIHN0YXJ0LXNlc3Npb24gLS10YXJnZXQgJElOU1RBTkNFX0lEIFxcXG4gKiAtLWRvY3VtZW50LW5hbWUgQVdTLVN0YXJ0UG9ydEZvcndhcmRpbmdTZXNzaW9uVG9SZW1vdGVIb3N0IFxcXG4gKiAtLXBhcmFtZXRlcnMgJ3tcbiAqIFwiaG9zdFwiOiBbXG4gKiBcImV4YW1wbGUtZGIuYzVhYmNkZWZnaGlqLnVzLXdlc3QtMi5yZHMuYW1hem9uYXdzLmNvbVwiXG4gKiBdLFxuICogXCJwb3J0TnVtYmVyXCI6IFtcbiAqIFwiNTQzMlwiXG4gKiBdLFxuICogXCJsb2NhbFBvcnROdW1iZXJcIjogW1xuICogXCI5OTk5XCJcbiAqIF1cbiAqIH0nIFxcXG4gKiAtLXByb2ZpbGUgJEFXU19QUk9GSUxFXG4gKiBgYGBcbiAqXG4gKiBgYGBzaFxuICogcHNxbCAtaCBsb2NhbGhvc3QgLXAgOTk5OSAjIGNvbnRpbnVlIGFkZGluZyB1c2VybmFtZSAoLVUpIGFuZCBkYiAoLWQpIGhlcmUuLi5cbiAqIGBgYFxuICpcbiAqIENvbm5lY3QgZGlyZWN0bHkgdG8gQmFzdGlvbiBIb3N0OlxuICpcbiAqIGBgYHNoXG4gKiBhd3Mgc3NtIHN0YXJ0LXNlc3Npb24gLS10YXJnZXQgJElOU1RBTkNFX0lEIC0tcHJvZmlsZSAkQVdTX1BST0ZJTEVcbiAqIGBgYFxuICpcbiAqICoqU2V0dGluZyB1cCBhbiBTU0ggdHVubmVsKipcbiAqXG4gKiBJbiB5b3VyIGB+Ly5zc2gvY29uZmlnYCBmaWxlLCBhZGQgYW4gZW50cnkgbGlrZTpcbiAqXG4gKiBgYGBcbiAqIEhvc3QgZGItdHVubmVsXG4gKiBIb3N0bmFtZSB7dGhlLWJhc3Rpb24taG9zdC1hZGRyZXNzfVxuICogTG9jYWxGb3J3YXJkIDk5OTkge3RoZS1kYi1ob3N0bmFtZX06NTQzMlxuICogYGBgXG4gKlxuICogVGhlbiBhIHR1bm5lbCBjYW4gYmUgb3BlbmVkIHZpYTpcbiAqXG4gKiBgYGBcbiAqIHNzaCAtTiBkYi10dW5uZWxcbiAqIGBgYFxuICpcbiAqIEFuZCBhIGNvbm5lY3Rpb24gdG8gdGhlIERCIGNhbiBiZSBtYWRlIHZpYTpcbiAqXG4gKiBgYGBcbiAqIHBzcWwgLWggMTI3LjAuMC4xIC1wIDk5OTkgLVUge3VzZXJuYW1lfSAtZCB7ZGF0YWJhc2V9XG4gKiBgYGBcbiAqXG4gKiAqKkhhbmRsaW5nIGBSRU1PVEUgSE9TVCBJREVOVElGSUNBVElPTiBIQVMgQ0hBTkdFRCFgIGVycm9yKipcbiAqXG4gKiBJZiB5b3UndmUgcmVkZXBsb3llZCBhIGJhc3Rpb24gaG9zdCB0aGF0IHlvdSd2ZSBwcmV2aW91c2x5IGNvbm5lY3RlZCB0bywgeW91IG1heSBzZWUgYW4gZXJyb3IgbGlrZTpcbiAqXG4gKiBgYGBcbiAqIEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAXG4gKiBAICAgIFdBUk5JTkc6IFJFTU9URSBIT1NUIElERU5USUZJQ0FUSU9OIEhBUyBDSEFOR0VEISAgICAgQFxuICogQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBcbiAqIElUIElTIFBPU1NJQkxFIFRIQVQgU09NRU9ORSBJUyBET0lORyBTT01FVEhJTkcgTkFTVFkhXG4gKiBTb21lb25lIGNvdWxkIGJlIGVhdmVzZHJvcHBpbmcgb24geW91IHJpZ2h0IG5vdyAobWFuLWluLXRoZS1taWRkbGUgYXR0YWNrKSFcbiAqIEl0IGlzIGFsc28gcG9zc2libGUgdGhhdCBhIGhvc3Qga2V5IGhhcyBqdXN0IGJlZW4gY2hhbmdlZC5cbiAqIFRoZSBmaW5nZXJwcmludCBmb3IgdGhlIEVDRFNBIGtleSBzZW50IGJ5IHRoZSByZW1vdGUgaG9zdCBpc1xuICogU0hBMjU2Om1QbnhBT1hUcGIwNlBGZ0kxUWM4VE1RMmU5Yjdnb1U4eTJOZFM1aHpJcjguXG4gKiBQbGVhc2UgY29udGFjdCB5b3VyIHN5c3RlbSBhZG1pbmlzdHJhdG9yLlxuICogQWRkIGNvcnJlY3QgaG9zdCBrZXkgaW4gL1VzZXJzL3VzZXJuYW1lLy5zc2gva25vd25faG9zdHMgdG8gZ2V0IHJpZCBvZiB0aGlzIG1lc3NhZ2UuXG4gKiBPZmZlbmRpbmcgRUNEU0Ega2V5IGluIC9Vc2Vycy91c2VybmFtZS8uc3NoL2tub3duX2hvc3RzOjI4XG4gKiBFQ0RTQSBob3N0IGtleSBmb3IgZWMyLTEyLTM0LTU2LTc4OS51cy13ZXN0LTIuY29tcHV0ZS5hbWF6b25hd3MuY29tIGhhcyBjaGFuZ2VkIGFuZCB5b3UgaGF2ZSByZXF1ZXN0ZWQgc3RyaWN0IGNoZWNraW5nLlxuICogSG9zdCBrZXkgdmVyaWZpY2F0aW9uIGZhaWxlZC5cbiAqIGBgYFxuICpcbiAqIFRoaXMgaXMgZHVlIHRvIHRoZSBzZXJ2ZXIncyBmaW5nZXJwcmludCBjaGFuZ2luZy4gV2UgY2FuIHNjcnViIHRoZSBmaW5nZXJwcmludCBmcm9tIG91ciBzeXN0ZW0gd2l0aCBhIGNvbW1hbmQgbGlrZTpcbiAqXG4gKiBgYGBcbiAqIHNzaC1rZXlnZW4gLVIgMTIuMzQuNTYuNzg5XG4gKiBgYGBcbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBCYXN0aW9uSG9zdCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIGluc3RhbmNlOiBlYzIuSW5zdGFuY2U7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEJhc3Rpb25Ib3N0UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgeyBzdGFja05hbWUgfSA9IFN0YWNrLm9mKHRoaXMpO1xuXG4gICAgLy8gQnVpbGQgZWMyIGluc3RhbmNlXG4gICAgdGhpcy5pbnN0YW5jZSA9IG5ldyBlYzIuSW5zdGFuY2UodGhpcywgXCJiYXN0aW9uLWhvc3RcIiwge1xuICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICB2cGNTdWJuZXRzOiB7IHN1Ym5ldFR5cGU6IGVjMi5TdWJuZXRUeXBlLlBVQkxJQyB9LFxuICAgICAgaW5zdGFuY2VOYW1lOiBgJHtzdGFja05hbWV9IGJhc3Rpb24gaG9zdGAsXG4gICAgICBpbnN0YW5jZVR5cGU6IGVjMi5JbnN0YW5jZVR5cGUub2YoXG4gICAgICAgIGVjMi5JbnN0YW5jZUNsYXNzLkJVUlNUQUJMRTRfR1JBVklUT04sXG4gICAgICAgIGVjMi5JbnN0YW5jZVNpemUuTkFOT1xuICAgICAgKSxcbiAgICAgIG1hY2hpbmVJbWFnZTogZWMyLk1hY2hpbmVJbWFnZS5sYXRlc3RBbWF6b25MaW51eCh7XG4gICAgICAgIGdlbmVyYXRpb246IGVjMi5BbWF6b25MaW51eEdlbmVyYXRpb24uQU1BWk9OX0xJTlVYXzIsXG4gICAgICAgIGNwdVR5cGU6IGVjMi5BbWF6b25MaW51eENwdVR5cGUuQVJNXzY0LFxuICAgICAgfSksXG4gICAgICB1c2VyRGF0YTogcHJvcHMudXNlckRhdGEsXG4gICAgICB1c2VyRGF0YUNhdXNlc1JlcGxhY2VtZW50OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgLy8gQXNzaWduIGVsYXN0aWMgSVBcbiAgICBpZiAocHJvcHMuY3JlYXRlRWxhc3RpY0lwID8/IHRydWUpIHtcbiAgICAgIG5ldyBlYzIuQ2ZuRUlQKHRoaXMsIFwiSVBcIiwge1xuICAgICAgICBpbnN0YW5jZUlkOiB0aGlzLmluc3RhbmNlLmluc3RhbmNlSWQsXG4gICAgICAgIHRhZ3M6IFt7IGtleTogXCJOYW1lXCIsIHZhbHVlOiBzdGFja05hbWUgfV0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBbGxvdyBiYXN0aW9uIGhvc3QgdG8gY29ubmVjdCB0byBkYlxuICAgIHRoaXMuaW5zdGFuY2UuY29ubmVjdGlvbnMuYWxsb3dUbyhcbiAgICAgIHByb3BzLmRiLmNvbm5lY3Rpb25zLnNlY3VyaXR5R3JvdXBzWzBdLFxuICAgICAgZWMyLlBvcnQudGNwKDU0MzIpLFxuICAgICAgXCJBbGxvdyBjb25uZWN0aW9uIGZyb20gYmFzdGlvbiBob3N0XCJcbiAgICApO1xuXG4gICAgLy8gQWxsb3cgSVAgYWNjZXNzIHRvIGJhc3Rpb24gaG9zdFxuICAgIGZvciAoY29uc3QgaXB2NCBvZiBwcm9wcy5pcHY0QWxsb3dsaXN0KSB7XG4gICAgICB0aGlzLmluc3RhbmNlLmNvbm5lY3Rpb25zLmFsbG93RnJvbShcbiAgICAgICAgZWMyLlBlZXIuaXB2NChpcHY0KSxcbiAgICAgICAgZWMyLlBvcnQudGNwKHByb3BzLnNzaFBvcnQgfHwgMjIpLFxuICAgICAgICBcIlNTSCBBY2Nlc3NcIlxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBJbnRlZ3JhdGUgd2l0aCBTU01cbiAgICB0aGlzLmluc3RhbmNlLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgIFwic3NtbWVzc2FnZXM6KlwiLFxuICAgICAgICAgIFwic3NtOlVwZGF0ZUluc3RhbmNlSW5mb3JtYXRpb25cIixcbiAgICAgICAgICBcImVjMm1lc3NhZ2VzOipcIixcbiAgICAgICAgXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgfSlcbiAgICApO1xuXG4gICAgbmV3IENmbk91dHB1dCh0aGlzLCBcImluc3RhbmNlLWlkLW91dHB1dFwiLCB7XG4gICAgICB2YWx1ZTogdGhpcy5pbnN0YW5jZS5pbnN0YW5jZUlkLFxuICAgICAgZXhwb3J0TmFtZTogYCR7c3RhY2tOYW1lfS1pbnN0YW5jZS1pZGAsXG4gICAgfSk7XG4gICAgbmV3IENmbk91dHB1dCh0aGlzLCBcImluc3RhbmNlLXB1YmxpYy1pcC1vdXRwdXRcIiwge1xuICAgICAgdmFsdWU6IHRoaXMuaW5zdGFuY2UuaW5zdGFuY2VQdWJsaWNJcCxcbiAgICAgIGV4cG9ydE5hbWU6IGAke3N0YWNrTmFtZX0taW5zdGFuY2UtcHVibGljLWlwYCxcbiAgICB9KTtcbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIFwiaW5zdGFuY2UtcHVibGljLWRucy1uYW1lLW91dHB1dFwiLCB7XG4gICAgICB2YWx1ZTogdGhpcy5pbnN0YW5jZS5pbnN0YW5jZVB1YmxpY0Ruc05hbWUsXG4gICAgICBleHBvcnROYW1lOiBgJHtzdGFja05hbWV9LXB1YmxpYy1kbnMtbmFtZWAsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYXN0aW9uSG9zdFByb3BzIHtcbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcbiAgcmVhZG9ubHkgZGI6IHJkcy5JRGF0YWJhc2VJbnN0YW5jZTtcbiAgcmVhZG9ubHkgdXNlckRhdGE6IGVjMi5Vc2VyRGF0YTtcbiAgcmVhZG9ubHkgaXB2NEFsbG93bGlzdDogc3RyaW5nW107XG4gIHJlYWRvbmx5IHNzaFBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IGFuIGVsYXN0aWMgSVAgc2hvdWxkIGJlIGNyZWF0ZWQgZm9yIHRoZSBiYXN0aW9uIGhvc3QuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVFbGFzdGljSXA/OiBib29sZWFuO1xufVxuIl19
@@ -0,0 +1,57 @@
1
+ import { aws_ec2, aws_rds, aws_secretsmanager } from "aws-cdk-lib";
2
+ import { Construct } from "constructs";
3
+ /**
4
+ * Bootstraps a database instance, installing pgSTAC onto the database.
5
+ */
6
+ export declare class BootstrapPgStac extends Construct {
7
+ secret: aws_secretsmanager.ISecret;
8
+ constructor(scope: Construct, id: string, props: BootstrapPgStacProps);
9
+ }
10
+ export interface BootstrapPgStacProps {
11
+ /**
12
+ * VPC in which the database resides.
13
+ *
14
+ * Note - Must be explicitely set if the `database` only conforms to the
15
+ * `aws_rds.IDatabaseInstace` interface (ie it is a reference to a database instance
16
+ * rather than a database instance.)
17
+ *
18
+ * @default - `vpc` property of the `database` instance provided.
19
+ */
20
+ readonly vpc?: aws_ec2.IVpc;
21
+ /**
22
+ * Database onto which pgSTAC should be installed.
23
+ */
24
+ readonly database: aws_rds.DatabaseInstance | aws_rds.IDatabaseInstance;
25
+ /**
26
+ * Secret containing valid connection details for the database instance. Secret must
27
+ * conform to the format of CDK's `DatabaseInstance` (i.e. a JSON object containing a
28
+ * `username`, `password`, `host`, `port`, and optionally a `dbname`). If a `dbname`
29
+ * property is not specified within the secret, the bootstrapper will attempt to
30
+ * connect to a database with the name of `"postgres"`.
31
+ */
32
+ readonly dbSecret: aws_secretsmanager.ISecret;
33
+ /**
34
+ * Name of database that is to be created and onto which pgSTAC will be installed.
35
+ *
36
+ * @default pgstac
37
+ */
38
+ readonly pgstacDbName?: string;
39
+ /**
40
+ * Name of user that will be generated for connecting to the pgSTAC database.
41
+ *
42
+ * @default pgstac_user
43
+ */
44
+ readonly pgstacUsername?: string;
45
+ /**
46
+ * pgSTAC version to be installed.
47
+ *
48
+ * @default 0.6.8
49
+ */
50
+ readonly pgstacVersion?: string;
51
+ /**
52
+ * Prefix to assign to the generated `secrets_manager.Secret`
53
+ *
54
+ * @default pgstac
55
+ */
56
+ readonly secretsPrefix?: string;
57
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.BootstrapPgStac = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const constructs_1 = require("constructs");
8
+ function hasVpc(instance) {
9
+ return instance.vpc !== undefined;
10
+ }
11
+ const DEFAULT_PGSTAC_VERSION = "0.6.13";
12
+ /**
13
+ * Bootstraps a database instance, installing pgSTAC onto the database.
14
+ */
15
+ class BootstrapPgStac extends constructs_1.Construct {
16
+ constructor(scope, id, props) {
17
+ super(scope, id);
18
+ const { pgstacVersion = DEFAULT_PGSTAC_VERSION } = props;
19
+ const handler = new aws_cdk_lib_1.aws_lambda.Function(this, "lambda", {
20
+ handler: "handler.handler",
21
+ runtime: aws_cdk_lib_1.aws_lambda.Runtime.PYTHON_3_8,
22
+ code: aws_cdk_lib_1.aws_lambda.Code.fromDockerBuild(__dirname, {
23
+ file: "runtime/Dockerfile",
24
+ buildArgs: { PGSTAC_VERSION: pgstacVersion },
25
+ }),
26
+ timeout: aws_cdk_lib_1.Duration.minutes(2),
27
+ vpc: hasVpc(props.database) ? props.database.vpc : props.vpc,
28
+ logRetention: aws_cdk_lib_1.aws_logs.RetentionDays.ONE_WEEK,
29
+ });
30
+ this.secret = new aws_cdk_lib_1.aws_secretsmanager.Secret(this, "secret", {
31
+ secretName: [
32
+ props.secretsPrefix || "pgstac",
33
+ id,
34
+ this.node.addr.slice(-8),
35
+ ].join("/"),
36
+ generateSecretString: {
37
+ secretStringTemplate: JSON.stringify({
38
+ dbname: props.pgstacDbName || "pgstac",
39
+ engine: "postgres",
40
+ port: 5432,
41
+ host: props.database.instanceEndpoint.hostname,
42
+ username: props.pgstacUsername || "pgstac_user",
43
+ }),
44
+ generateStringKey: "password",
45
+ excludePunctuation: true,
46
+ },
47
+ description: `PgSTAC database bootstrapped by ${aws_cdk_lib_1.Stack.of(this).stackName}`,
48
+ });
49
+ // Allow lambda to...
50
+ // read new user secret
51
+ this.secret.grantRead(handler);
52
+ // read database secret
53
+ props.dbSecret.grantRead(handler);
54
+ // connect to database
55
+ props.database.connections.allowFrom(handler, aws_cdk_lib_1.aws_ec2.Port.tcp(5432));
56
+ // this.connections = props.database.connections;
57
+ new aws_cdk_lib_1.CustomResource(this, "bootstrapper", {
58
+ serviceToken: handler.functionArn,
59
+ properties: {
60
+ // By setting pgstac_version in the properties assures
61
+ // that Create/Update events will be passed to the service token
62
+ pgstac_version: pgstacVersion,
63
+ conn_secret_arn: props.dbSecret.secretArn,
64
+ new_user_secret_arn: this.secret.secretArn,
65
+ },
66
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.RETAIN,
67
+ });
68
+ }
69
+ }
70
+ exports.BootstrapPgStac = BootstrapPgStac;
71
+ _a = JSII_RTTI_SYMBOL_1;
72
+ BootstrapPgStac[_a] = { fqn: "eoapi-cdk.BootstrapPgStac", version: "5.0.0" };
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQVVxQjtBQUNyQiwyQ0FBdUM7QUFFdkMsU0FBUyxNQUFNLENBQ2IsUUFBOEQ7SUFFOUQsT0FBUSxRQUFxQyxDQUFDLEdBQUcsS0FBSyxTQUFTLENBQUM7QUFDbEUsQ0FBQztBQUVELE1BQU0sc0JBQXNCLEdBQUcsUUFBUSxDQUFDO0FBRXhDOztHQUVHO0FBQ0gsTUFBYSxlQUFnQixTQUFRLHNCQUFTO0lBRzVDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMkI7UUFDbkUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQUUsYUFBYSxHQUFHLHNCQUFzQixFQUFFLEdBQUcsS0FBSyxDQUFDO1FBQ3pELE1BQU0sT0FBTyxHQUFHLElBQUksd0JBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRTtZQUN0RCxPQUFPLEVBQUUsaUJBQWlCO1lBQzFCLE9BQU8sRUFBRSx3QkFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVO1lBQ3RDLElBQUksRUFBRSx3QkFBVSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUFFO2dCQUMvQyxJQUFJLEVBQUUsb0JBQW9CO2dCQUMxQixTQUFTLEVBQUUsRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFO2FBQzdDLENBQUM7WUFDRixPQUFPLEVBQUUsc0JBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQzVCLEdBQUcsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDNUQsWUFBWSxFQUFFLHNCQUFRLENBQUMsYUFBYSxDQUFDLFFBQVE7U0FDOUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLGdDQUFrQixDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFO1lBQzFELFVBQVUsRUFBRTtnQkFDVixLQUFLLENBQUMsYUFBYSxJQUFJLFFBQVE7Z0JBQy9CLEVBQUU7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3pCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUNYLG9CQUFvQixFQUFFO2dCQUNwQixvQkFBb0IsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDO29CQUNuQyxNQUFNLEVBQUUsS0FBSyxDQUFDLFlBQVksSUFBSSxRQUFRO29CQUN0QyxNQUFNLEVBQUUsVUFBVTtvQkFDbEIsSUFBSSxFQUFFLElBQUk7b0JBQ1YsSUFBSSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsUUFBUTtvQkFDOUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxjQUFjLElBQUksYUFBYTtpQkFDaEQsQ0FBQztnQkFDRixpQkFBaUIsRUFBRSxVQUFVO2dCQUM3QixrQkFBa0IsRUFBRSxJQUFJO2FBQ3pCO1lBQ0QsV0FBVyxFQUFFLG1DQUNYLG1CQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQ2pCLEVBQUU7U0FDSCxDQUFDLENBQUM7UUFFSCxxQkFBcUI7UUFDckIsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9CLHVCQUF1QjtRQUN2QixLQUFLLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNsQyxzQkFBc0I7UUFDdEIsS0FBSyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxxQkFBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUV0RSxpREFBaUQ7UUFDakQsSUFBSSw0QkFBYyxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUU7WUFDdkMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxXQUFXO1lBQ2pDLFVBQVUsRUFBRTtnQkFDVixzREFBc0Q7Z0JBQ3RELGdFQUFnRTtnQkFDaEUsY0FBYyxFQUFFLGFBQWE7Z0JBQzdCLGVBQWUsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLFNBQVM7Z0JBQ3pDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUzthQUMzQztZQUNELGFBQWEsRUFBRSwyQkFBYSxDQUFDLE1BQU07U0FDcEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUE3REgsMENBOERDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgYXdzX2VjMixcbiAgYXdzX3JkcyxcbiAgYXdzX2xhbWJkYSxcbiAgYXdzX2xvZ3MsXG4gIGF3c19zZWNyZXRzbWFuYWdlcixcbiAgQ3VzdG9tUmVzb3VyY2UsXG4gIER1cmF0aW9uLFxuICBTdGFjayxcbiAgUmVtb3ZhbFBvbGljeSxcbn0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG5mdW5jdGlvbiBoYXNWcGMoXG4gIGluc3RhbmNlOiBhd3NfcmRzLkRhdGFiYXNlSW5zdGFuY2UgfCBhd3NfcmRzLklEYXRhYmFzZUluc3RhbmNlXG4pOiBpbnN0YW5jZSBpcyBhd3NfcmRzLkRhdGFiYXNlSW5zdGFuY2Uge1xuICByZXR1cm4gKGluc3RhbmNlIGFzIGF3c19yZHMuRGF0YWJhc2VJbnN0YW5jZSkudnBjICE9PSB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IERFRkFVTFRfUEdTVEFDX1ZFUlNJT04gPSBcIjAuNi4xM1wiO1xuXG4vKipcbiAqIEJvb3RzdHJhcHMgYSBkYXRhYmFzZSBpbnN0YW5jZSwgaW5zdGFsbGluZyBwZ1NUQUMgb250byB0aGUgZGF0YWJhc2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBCb290c3RyYXBQZ1N0YWMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBzZWNyZXQ6IGF3c19zZWNyZXRzbWFuYWdlci5JU2VjcmV0O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBCb290c3RyYXBQZ1N0YWNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCB7IHBnc3RhY1ZlcnNpb24gPSBERUZBVUxUX1BHU1RBQ19WRVJTSU9OIH0gPSBwcm9wcztcbiAgICBjb25zdCBoYW5kbGVyID0gbmV3IGF3c19sYW1iZGEuRnVuY3Rpb24odGhpcywgXCJsYW1iZGFcIiwge1xuICAgICAgaGFuZGxlcjogXCJoYW5kbGVyLmhhbmRsZXJcIixcbiAgICAgIHJ1bnRpbWU6IGF3c19sYW1iZGEuUnVudGltZS5QWVRIT05fM184LFxuICAgICAgY29kZTogYXdzX2xhbWJkYS5Db2RlLmZyb21Eb2NrZXJCdWlsZChfX2Rpcm5hbWUsIHtcbiAgICAgICAgZmlsZTogXCJydW50aW1lL0RvY2tlcmZpbGVcIixcbiAgICAgICAgYnVpbGRBcmdzOiB7IFBHU1RBQ19WRVJTSU9OOiBwZ3N0YWNWZXJzaW9uIH0sXG4gICAgICB9KSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMiksXG4gICAgICB2cGM6IGhhc1ZwYyhwcm9wcy5kYXRhYmFzZSkgPyBwcm9wcy5kYXRhYmFzZS52cGMgOiBwcm9wcy52cGMsXG4gICAgICBsb2dSZXRlbnRpb246IGF3c19sb2dzLlJldGVudGlvbkRheXMuT05FX1dFRUssXG4gICAgfSk7XG5cbiAgICB0aGlzLnNlY3JldCA9IG5ldyBhd3Nfc2VjcmV0c21hbmFnZXIuU2VjcmV0KHRoaXMsIFwic2VjcmV0XCIsIHtcbiAgICAgIHNlY3JldE5hbWU6IFtcbiAgICAgICAgcHJvcHMuc2VjcmV0c1ByZWZpeCB8fCBcInBnc3RhY1wiLFxuICAgICAgICBpZCxcbiAgICAgICAgdGhpcy5ub2RlLmFkZHIuc2xpY2UoLTgpLFxuICAgICAgXS5qb2luKFwiL1wiKSxcbiAgICAgIGdlbmVyYXRlU2VjcmV0U3RyaW5nOiB7XG4gICAgICAgIHNlY3JldFN0cmluZ1RlbXBsYXRlOiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgZGJuYW1lOiBwcm9wcy5wZ3N0YWNEYk5hbWUgfHwgXCJwZ3N0YWNcIixcbiAgICAgICAgICBlbmdpbmU6IFwicG9zdGdyZXNcIixcbiAgICAgICAgICBwb3J0OiA1NDMyLFxuICAgICAgICAgIGhvc3Q6IHByb3BzLmRhdGFiYXNlLmluc3RhbmNlRW5kcG9pbnQuaG9zdG5hbWUsXG4gICAgICAgICAgdXNlcm5hbWU6IHByb3BzLnBnc3RhY1VzZXJuYW1lIHx8IFwicGdzdGFjX3VzZXJcIixcbiAgICAgICAgfSksXG4gICAgICAgIGdlbmVyYXRlU3RyaW5nS2V5OiBcInBhc3N3b3JkXCIsXG4gICAgICAgIGV4Y2x1ZGVQdW5jdHVhdGlvbjogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICBkZXNjcmlwdGlvbjogYFBnU1RBQyBkYXRhYmFzZSBib290c3RyYXBwZWQgYnkgJHtcbiAgICAgICAgU3RhY2sub2YodGhpcykuc3RhY2tOYW1lXG4gICAgICB9YCxcbiAgICB9KTtcblxuICAgIC8vIEFsbG93IGxhbWJkYSB0by4uLlxuICAgIC8vIHJlYWQgbmV3IHVzZXIgc2VjcmV0XG4gICAgdGhpcy5zZWNyZXQuZ3JhbnRSZWFkKGhhbmRsZXIpO1xuICAgIC8vIHJlYWQgZGF0YWJhc2Ugc2VjcmV0XG4gICAgcHJvcHMuZGJTZWNyZXQuZ3JhbnRSZWFkKGhhbmRsZXIpO1xuICAgIC8vIGNvbm5lY3QgdG8gZGF0YWJhc2VcbiAgICBwcm9wcy5kYXRhYmFzZS5jb25uZWN0aW9ucy5hbGxvd0Zyb20oaGFuZGxlciwgYXdzX2VjMi5Qb3J0LnRjcCg1NDMyKSk7XG5cbiAgICAvLyB0aGlzLmNvbm5lY3Rpb25zID0gcHJvcHMuZGF0YWJhc2UuY29ubmVjdGlvbnM7XG4gICAgbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsIFwiYm9vdHN0cmFwcGVyXCIsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogaGFuZGxlci5mdW5jdGlvbkFybixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgLy8gQnkgc2V0dGluZyBwZ3N0YWNfdmVyc2lvbiBpbiB0aGUgcHJvcGVydGllcyBhc3N1cmVzXG4gICAgICAgIC8vIHRoYXQgQ3JlYXRlL1VwZGF0ZSBldmVudHMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHNlcnZpY2UgdG9rZW5cbiAgICAgICAgcGdzdGFjX3ZlcnNpb246IHBnc3RhY1ZlcnNpb24sXG4gICAgICAgIGNvbm5fc2VjcmV0X2FybjogcHJvcHMuZGJTZWNyZXQuc2VjcmV0QXJuLFxuICAgICAgICBuZXdfdXNlcl9zZWNyZXRfYXJuOiB0aGlzLnNlY3JldC5zZWNyZXRBcm4sXG4gICAgICB9LFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5SRVRBSU4sIC8vIFRoaXMgcmV0YWlucyB0aGUgY3VzdG9tIHJlc291cmNlICh3aGljaCBkb2Vzbid0IHJlYWxseSBleGlzdCksIG5vdCB0aGUgZGF0YWJhc2VcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvb3RzdHJhcFBnU3RhY1Byb3BzIHtcbiAgLyoqXG4gICAqIFZQQyBpbiB3aGljaCB0aGUgZGF0YWJhc2UgcmVzaWRlcy5cbiAgICpcbiAgICogTm90ZSAtIE11c3QgYmUgZXhwbGljaXRlbHkgc2V0IGlmIHRoZSBgZGF0YWJhc2VgIG9ubHkgY29uZm9ybXMgdG8gdGhlXG4gICAqIGBhd3NfcmRzLklEYXRhYmFzZUluc3RhY2VgIGludGVyZmFjZSAoaWUgaXQgaXMgYSByZWZlcmVuY2UgdG8gYSBkYXRhYmFzZSBpbnN0YW5jZVxuICAgKiByYXRoZXIgdGhhbiBhIGRhdGFiYXNlIGluc3RhbmNlLilcbiAgICpcbiAgICogQGRlZmF1bHQgLSBgdnBjYCBwcm9wZXJ0eSBvZiB0aGUgYGRhdGFiYXNlYCBpbnN0YW5jZSBwcm92aWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHZwYz86IGF3c19lYzIuSVZwYztcblxuICAvKipcbiAgICogRGF0YWJhc2Ugb250byB3aGljaCBwZ1NUQUMgc2hvdWxkIGJlIGluc3RhbGxlZC5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGFiYXNlOiBhd3NfcmRzLkRhdGFiYXNlSW5zdGFuY2UgfCBhd3NfcmRzLklEYXRhYmFzZUluc3RhbmNlO1xuXG4gIC8qKlxuICAgKiBTZWNyZXQgY29udGFpbmluZyB2YWxpZCBjb25uZWN0aW9uIGRldGFpbHMgZm9yIHRoZSBkYXRhYmFzZSBpbnN0YW5jZS4gU2VjcmV0IG11c3RcbiAgICogY29uZm9ybSB0byB0aGUgZm9ybWF0IG9mIENESydzIGBEYXRhYmFzZUluc3RhbmNlYCAoaS5lLiBhIEpTT04gb2JqZWN0IGNvbnRhaW5pbmcgYVxuICAgKiBgdXNlcm5hbWVgLCBgcGFzc3dvcmRgLCBgaG9zdGAsIGBwb3J0YCwgYW5kIG9wdGlvbmFsbHkgYSBgZGJuYW1lYCkuIElmIGEgYGRibmFtZWBcbiAgICogcHJvcGVydHkgaXMgbm90IHNwZWNpZmllZCB3aXRoaW4gdGhlIHNlY3JldCwgdGhlIGJvb3RzdHJhcHBlciB3aWxsIGF0dGVtcHQgdG9cbiAgICogY29ubmVjdCB0byBhIGRhdGFiYXNlIHdpdGggdGhlIG5hbWUgb2YgYFwicG9zdGdyZXNcImAuXG4gICAqL1xuICByZWFkb25seSBkYlNlY3JldDogYXdzX3NlY3JldHNtYW5hZ2VyLklTZWNyZXQ7XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgZGF0YWJhc2UgdGhhdCBpcyB0byBiZSBjcmVhdGVkIGFuZCBvbnRvIHdoaWNoIHBnU1RBQyB3aWxsIGJlIGluc3RhbGxlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgcGdzdGFjXG4gICAqL1xuICByZWFkb25seSBwZ3N0YWNEYk5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdXNlciB0aGF0IHdpbGwgYmUgZ2VuZXJhdGVkIGZvciBjb25uZWN0aW5nIHRvIHRoZSBwZ1NUQUMgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IHBnc3RhY191c2VyXG4gICAqL1xuICByZWFkb25seSBwZ3N0YWNVc2VybmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogcGdTVEFDIHZlcnNpb24gdG8gYmUgaW5zdGFsbGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAwLjYuOFxuICAgKi9cbiAgcmVhZG9ubHkgcGdzdGFjVmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogUHJlZml4IHRvIGFzc2lnbiB0byB0aGUgZ2VuZXJhdGVkIGBzZWNyZXRzX21hbmFnZXIuU2VjcmV0YFxuICAgKlxuICAgKiBAZGVmYXVsdCBwZ3N0YWNcbiAgICovXG4gIHJlYWRvbmx5IHNlY3JldHNQcmVmaXg/OiBzdHJpbmc7XG59XG4iXX0=
@@ -0,0 +1,18 @@
1
+ FROM lambci/lambda:build-python3.8
2
+
3
+ ARG PGSTAC_VERSION
4
+ RUN echo "Using PGSTAC Version ${PGSTAC_VERSION}"
5
+
6
+ WORKDIR /tmp
7
+
8
+ RUN pip install httpx psycopg[binary,pool] pypgstac==${PGSTAC_VERSION} -t /asset
9
+
10
+ COPY runtime/handler.py /asset/handler.py
11
+
12
+ # https://stackoverflow.com/a/61746719
13
+ # Tip from eoAPI: turns out, asyncio is part of python
14
+ RUN rm -rf /asset/asyncio*
15
+
16
+ # A command must be present avoid the following error on CDK deploy:
17
+ # Error response from daemon: No command specified
18
+ CMD [ "echo", "ready to go!" ]