cdk-rds-sql 8.1.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.
@@ -0,0 +1,2053 @@
1
+ r'''
2
+ # About
3
+
4
+ This CDK construct library makes it possible to create databases,
5
+ schemas, and roles in an Aurora Serverless v2, RDS Database Cluster,
6
+ Database Instance, or AWS DSQL clusters. PostgreSQL, MySQL, and DSQL
7
+ databases are supported.
8
+
9
+ This construct library is intended to be used in enterprise
10
+ environments, and works in isolated subnets.
11
+
12
+ <p align="left">
13
+ <a href="https://github.com/semantic-release/semantic-release"><img src="https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release" alt=semantic-release: angular"></a>
14
+ <a href="https://github.com/berenddeboer/cdk-rds-sql/actions/workflows/release.yml"><img src="https://github.com/berenddeboer/cdk-rds-sql/actions/workflows/release.yml/badge.svg" alt="Release badge"></a>
15
+ </p>
16
+
17
+ # Requirements
18
+
19
+ * CDK v2.
20
+
21
+ # Installation
22
+
23
+ ```
24
+ npm i cdk-rds-sql
25
+ ```
26
+
27
+ # Usage
28
+
29
+ ## Provider
30
+
31
+ First setup your VPC and create your cluster:
32
+
33
+ ```python
34
+ import { Duration, RemovalPolicy } from "aws-cdk-lib"
35
+ import * as ec2 from "aws-cdk-lib/aws-ec2"
36
+ import * as rds from "aws-cdk-lib/aws-rds"
37
+
38
+ const vpc = ec2.Vpc.fromLookup(this, "Vpc", {
39
+ vpcId: this.node.tryGetContext("vpc-id"),
40
+ })
41
+
42
+ const cluster = new rds.ServerlessCluster(this, "Cluster", {
43
+ vpc: vpc,
44
+ vpcSubnets: {
45
+ subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
46
+ },
47
+ engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,
48
+ parameterGroup: rds.ParameterGroup.fromParameterGroupName(
49
+ this,
50
+ "ParameterGroup",
51
+ "default.aurora-postgresql11"
52
+ ),
53
+ removalPolicy: RemovalPolicy.DESTROY,
54
+ scaling: {
55
+ autoPause: Duration.minutes(60),
56
+ minCapacity: rds.AuroraCapacityUnit.ACU_2,
57
+ maxCapacity: rds.AuroraCapacityUnit.ACU_2,
58
+ },
59
+ })
60
+ ```
61
+
62
+ Then create a provider which will connect to your database. For a cluster:
63
+
64
+ ```python
65
+ import { Provider } from "cdk-rds-sql"
66
+
67
+ const provider = new Provider(this, "Provider", {
68
+ vpc: vpc,
69
+ cluster: cluster,
70
+ secret: cluster.secret!,
71
+ })
72
+ ```
73
+
74
+ For an instance:
75
+
76
+ ```python
77
+ import { Provider } from "cdk-rds-sql"
78
+
79
+ const provider = new Provider(this, "Provider", {
80
+ vpc: vpc,
81
+ instance: instance,
82
+ secret: cluster.secret!,
83
+ })
84
+ ```
85
+
86
+ The provider will setup a lambda, which normally lives in the same VPC
87
+ as the database. You can give a different VPC, as long as that VPC has
88
+ access to the VPC of the database. Only the provider lambda will talk
89
+ to your database.
90
+
91
+ The provider will by default use the private isolated subnet of the
92
+ VPC. Your isolated network must have a VPC endpoint to AWS Secrets Manager
93
+ and possibly KMS as well. If you want to use a subnet with egress
94
+ access in case you have no such VPC endpoints, specify the subnet as
95
+ follows:
96
+
97
+ ```python
98
+ import { Provider } from "cdk-rds-sql"
99
+
100
+ const provider = new Provider(this, "Provider", {
101
+ vpc: vpc,
102
+ vpcSubnets: {
103
+ subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
104
+ },
105
+ cluster: cluster,
106
+ secret: cluster.secret!,
107
+ })
108
+ ```
109
+
110
+ ## Roles
111
+
112
+ Create a postgres role (or mysql user) for a cluster as follows:
113
+
114
+ ```python
115
+ import { Role } from "cdk-rds-sql"
116
+
117
+ const role = new Role(this, "Role", {
118
+ provider: provider,
119
+ roleName: "myrole",
120
+ databaseName: "mydb",
121
+ })
122
+ ```
123
+
124
+ This will automatically create a secret just like `ServerlessCluster`
125
+ does, with all the connection info needed for this user. It's secret
126
+ value is a JSON like:
127
+
128
+ ```json
129
+ {
130
+ "dbClusterIdentifier": "teststack-clustereb1186t9-sh4wpqfdyfvu",
131
+ "password": "very-long-and-boring",
132
+ "dbname": "mydb",
133
+ "engine": "postgres",
134
+ "port": 5432,
135
+ "host": "teststack-clustereb1186t9-sh4wpqfdyfvu.cluster-cgudolabssna.us-east-1.rds.amazonaws.com",
136
+ "username": "myrole"
137
+ }
138
+ ```
139
+
140
+ You can access the secret via `role.secret`.
141
+
142
+ Instead of `databaseName` you can also specify `database` to reference
143
+ an existing database. The role will not be created until the database
144
+ has been created.
145
+
146
+ If you want to make the role the owner of a new database, just specify
147
+ the `databaseName` here, and create the database later.
148
+
149
+ ### IAM Authentication
150
+
151
+ Instead of password-based authentication, you can create roles that
152
+ use AWS IAM database authentication. This eliminates the need to store
153
+ database passwords and provides enhanced security through AWS IAM
154
+ policies.
155
+
156
+ ```python
157
+ import { Role } from "cdk-rds-sql"
158
+
159
+ const iamRole = new Role(this, "IamRole", {
160
+ provider: provider,
161
+ roleName: "myiamrole",
162
+ databaseName: "mydb",
163
+ enableIamAuth: true,
164
+ })
165
+ ```
166
+
167
+ When `enableIamAuth` is set to `true`:
168
+
169
+ * **No secret is created** - the `role.secret` property will be `undefined`
170
+ * The database role is created without a password
171
+ * Your application must generate an IAM authentication token at runtime
172
+
173
+ This is the same behavior as DSQL clusters, which always use IAM authentication.
174
+
175
+ **Requirements for IAM Authentication:**
176
+
177
+ * SSL connections are required (enabled by default in this library)
178
+ * Your application must have IAM permissions to connect to the database
179
+ * The database user/role name must match the IAM identity
180
+
181
+ **IAM Policy Example:**
182
+
183
+ Your application will need an IAM policy like this to connect:
184
+
185
+ ```json
186
+ {
187
+ "Version": "2012-10-17",
188
+ "Statement": [
189
+ {
190
+ "Effect": "Allow",
191
+ "Action": ["rds-db:connect"],
192
+ "Resource": [
193
+ "arn:aws:rds-db:region:account-id:dbuser:cluster-resource-id/myiamrole"
194
+ ]
195
+ }
196
+ ]
197
+ }
198
+ ```
199
+
200
+ **Generating an IAM Authentication Token:**
201
+
202
+ At runtime, your application needs to generate an authentication token
203
+ using the AWS SDK. Here's an example using the AWS SDK for JavaScript:
204
+
205
+ ```python
206
+ import { Signer } from "@aws-sdk/rds-signer"
207
+ import { Client } from "pg"
208
+
209
+ const signer = new Signer({
210
+ hostname: "your-cluster.cluster-xxxxx.us-east-1.rds.amazonaws.com",
211
+ port: 5432,
212
+ username: "myiamrole",
213
+ region: "us-east-1",
214
+ })
215
+
216
+ const token = await signer.getAuthToken()
217
+
218
+ const client = new Client({
219
+ host: "your-cluster.cluster-xxxxx.us-east-1.rds.amazonaws.com",
220
+ port: 5432,
221
+ user: "myiamrole",
222
+ database: "mydb",
223
+ password: token,
224
+ ssl: { rejectUnauthorized: true },
225
+ })
226
+
227
+ await client.connect()
228
+ ```
229
+
230
+ Both PostgreSQL and MySQL databases support IAM authentication. For more details, see the [AWS RDS IAM Database Authentication documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html).
231
+
232
+ ### MySQL support
233
+
234
+ In MySQL users are created with '%' as value for the host. It is hard
235
+ to do this better:
236
+
237
+ * Determine the CIDR blocks used by a VPC is not trivial.
238
+ * For imported VPCs you cannot specify the IPv6 CIDR.
239
+ * CIDRs might change without the system knowing, meaning applications
240
+ could lose access to the database at random times, such as when a
241
+ container is restarted.
242
+
243
+ ## Database
244
+
245
+ Create a database as follows:
246
+
247
+ ```python
248
+ import { Database } from "cdk-rds-sql"
249
+
250
+ const database = new Database(this, "Database", {
251
+ provider: provider,
252
+ databaseName: "mydb",
253
+ })
254
+ ```
255
+
256
+ You can provide an owner, which makes it easy to create database owned
257
+ by a new user:
258
+
259
+ ```python
260
+ const database = new Database(this, "Database", {
261
+ provider: provider,
262
+ databaseName: "mydb",
263
+ owner: role,
264
+ })
265
+ ```
266
+
267
+ ## Schema
268
+
269
+ Create a schema in the default database as follows:
270
+
271
+ ```python
272
+ import { Schema } from "cdk-rds-sql"
273
+
274
+ new Schema(this, "Schema", {
275
+ provider: provider,
276
+ schemaName: "myschema",
277
+ })
278
+ ```
279
+
280
+ Or in another database:
281
+
282
+ ```python
283
+ const database = new Database(this, "Database", {
284
+ provider: provider,
285
+ databaseName: "mydb",
286
+ })
287
+
288
+ new Schema(this, "Schema", {
289
+ provider: provider,
290
+ schemaName: "myschema",
291
+ databaseName: database.databaseName,
292
+ })
293
+ ```
294
+
295
+ One may need a role permitted for using schema:
296
+
297
+ ```python
298
+ new Schema(this, "Schema", {
299
+ provider: provider,
300
+ schemaName: "myschema",
301
+ databaseName: database.databaseName,
302
+ role: role,
303
+ })
304
+ ```
305
+
306
+ ## Sql
307
+
308
+ You can insert arbitrary SQL into your database with the `Sql` construct:
309
+
310
+ ```python
311
+ import { Sql } from "cdk-rds-sql"
312
+
313
+ const sql = new Sql(this, "Sql", {
314
+ provider: provider,
315
+ database: database,
316
+ statement: "create table t (i int)",
317
+ })
318
+ ```
319
+
320
+ Create a table if it does not exist, and grant a role privileges:
321
+
322
+ ```python
323
+ const sql = new Sql(this, "Sql", {
324
+ provider: provider,
325
+ database: database,
326
+ statement: `
327
+ create table if not exists t (i int);
328
+ grant select on t to myrole;
329
+ `,
330
+ })
331
+ ```
332
+
333
+ Rollback sql on stack deletion:
334
+
335
+ ```python
336
+ const sql = new Sql(this, "Sql", {
337
+ provider: provider,
338
+ database: database,
339
+ statement: `
340
+ create table if not exists t (i int);
341
+ grant select on t to myrole;
342
+ `,
343
+ rollback: `
344
+ DO $$BEGIN
345
+ IF EXISTS (select from pg_database WHERE datname = 't') THEN
346
+ IF EXISTS (select from pg_catalog.pg_roles WHERE rolname = 'myrole') THEN
347
+ revoke select t from myrole;
348
+ END IF;
349
+ drop table t;
350
+ END IF;
351
+ END$$;
352
+ `,
353
+ })
354
+ ```
355
+
356
+ Note that there is no synchronisation between various `Sql`
357
+ constructs, in particular the order in your code does not determine
358
+ the order in which your SQL is executed. This happens in parallel,
359
+ unless you specify an explicit dependency via `sql.node.addDepency()`.
360
+
361
+ There are a lot of concerns when using `Sql`:
362
+
363
+ * When you update your Sql, your previous Sql is not "rolled back",
364
+ the new Sql is simply executed again.
365
+ * When you delete your `Sql` construct the rollback is executed if specified
366
+ * When permission are granted via `Sql` they must be removed via
367
+ rollback to succesfully remove the role
368
+ * Currently the `Sql` constructs has less than 5 minutes to execute
369
+ its work.
370
+ * It is unknown how large your SQL can be.
371
+
372
+ # Parameters
373
+
374
+ Some lambda constructs, in particular [Bref](https://bref.sh/), do not
375
+ support secrets out of the box. Use the `parameterPrefix` property to
376
+ create SSM parameters in addition to a secret:
377
+
378
+ ```python
379
+ const role = new Role(this, "Role", {
380
+ provider: provider,
381
+ roleName: "myrole",
382
+ databaseName: "mydb",
383
+ parameterPrefix: "/my-app/",
384
+ })
385
+ ```
386
+
387
+ This will create `/my-app/username`, `/my-app/password` and such.
388
+
389
+ To access parameters you will need IAM permissions such as:
390
+
391
+ ```python
392
+ initialPolicy: [
393
+ new iam.PolicyStatement({
394
+ actions: ["ssm:GetParameter", "ssm:GetParameters"],
395
+ resources: [
396
+ // Grant access to all parameters under the base path
397
+ `arn:aws:ssm:${this.region}:${this.account}:parameter/my-app/*`,
398
+ ],
399
+ effect: iam.Effect.ALLOW,
400
+ })
401
+ ],
402
+ ```
403
+
404
+ Note that your VPC will need an SSM Parameters interface endpoint to support this.
405
+
406
+ # AWS DSQL Support
407
+
408
+ This construct also supports AWS DSQL. DSQL is a great number of
409
+ limitations around it's postgresql support, so there is some learing
410
+ curve. This library supports creating roles, schemas, and executing
411
+ SQL on DSQL clusters. Creating databases is not supported by DSQL.
412
+
413
+ ## DSQL Provider Setup
414
+
415
+ DSQL clusters don't require a VPC or secrets since they use IAM authentication:
416
+
417
+ ```python
418
+ import * as dsql from "aws-cdk-lib/aws-dsql"
419
+ import { Provider } from "cdk-rds-sql"
420
+
421
+ const dsqlCluster = new dsql.CfnCluster(this, "DsqlCluster", {
422
+ deletionProtectionEnabled: false,
423
+ })
424
+
425
+ const provider = new Provider(this, "Provider", {
426
+ cluster: dsqlCluster,
427
+ // No VPC or secret needed for DSQL
428
+ })
429
+ ```
430
+
431
+ You can access DSQL from within a VPC, but cdk-rds-sql has not been
432
+ specifically tested with that scenario.
433
+
434
+ ## DSQL Roles
435
+
436
+ DSQL always uses IAM authentication, so the `enableIamAuth` property is ignored:
437
+
438
+ ```python
439
+ import { Role } from "cdk-rds-sql"
440
+
441
+ const role = new Role(this, "Role", {
442
+ provider: provider,
443
+ roleName: "myrole",
444
+ })
445
+ ```
446
+
447
+ ## Using DSQL
448
+
449
+ Connecting to DSQL requires a couple of things:
450
+
451
+ 1. Your IAM role needs the `dsql:DbConnect` IAM permission to connect to the cluster.
452
+ 2. You probably want a normal postgres role (not "admin") to use from your apps.
453
+ 3. Your IAM role needs to be connected to your postgres role: use the `IamGrant` construct for that:
454
+
455
+ ```python
456
+ new IamGrant(this, "LambdaIamGrant", {
457
+ provider: provider,
458
+ roleName: role.roleName,
459
+ resourceArn: queryLambda.role!.roleArn,
460
+ })
461
+ ```
462
+ 4. From your code use the Dsql signer to create the password:
463
+
464
+ ```python
465
+ import { DsqlSigner } from "@aws-sdk/dsql-signer"
466
+ import { Client } from "pg"
467
+
468
+ const region =
469
+ process.env["AWS_REGION"] || process.env["AWS_DEFAULT_REGION"] || "us-west-2"
470
+
471
+ // Generate DSQL auth token using AWS SDK
472
+ const signer = new DsqlSigner({
473
+ hostname: host,
474
+ region,
475
+ })
476
+
477
+ const authToken = await signer.getDbConnectAuthToken()
478
+
479
+ const client = new Client({
480
+ host,
481
+ port: 5432,
482
+ user: dbUser,
483
+ database: dbName,
484
+ password: authToken,
485
+ ssl: { rejectUnauthorized: false },
486
+ })
487
+
488
+ await client.connect()
489
+ ```
490
+
491
+ # IPv6
492
+
493
+ If you use the provider in an IPv6 subnet you probably need these settings:
494
+
495
+ ```python
496
+ import { Provider } from "cdk-rds-sql"
497
+
498
+ const provider = new Provider(this, "Provider", {
499
+ ...
500
+ functionProps: {
501
+ ipv6AllowedForDualStack: true,
502
+ allowAllIpv6Outbound: true,
503
+ },
504
+ }
505
+ ```
506
+
507
+ # Disabling SSL
508
+
509
+ The default connection to RDS is ssl enabled. You can disable ssl by
510
+ setting the `ssl` option to `false`:
511
+
512
+ ```python
513
+ const provider = new Provider(this, "Provider", {
514
+ vpc: vpc,
515
+ instance: instance,
516
+ secret: cluster.secret!,
517
+ ssl: false, // default is true
518
+ })
519
+ ```
520
+
521
+ # Working on this code
522
+
523
+ This code is managed by
524
+ [projen](https://github.com/projen/projen/blob/main/README.md). In
525
+ addition [pre-commit](https://pre-commit.com/) is used.
526
+
527
+ So after git clone and `pnpm install` you would do:
528
+
529
+ ```
530
+ pre-commit install --install-hooks --hook-type commit-msg --hook-type pre-commit
531
+ ```
532
+
533
+ to install the pre-commit hooks.
534
+
535
+ ## Testing
536
+
537
+ Test code via projen with:
538
+
539
+ ```
540
+ pnpm exec projen test
541
+ ```
542
+
543
+ You can run the PostgreSQL sample stack with:
544
+
545
+ ```
546
+ pnpm exec projen integ:deploy:postgresql:serverless
547
+ ```
548
+
549
+ If you want to use an existing vpc:
550
+
551
+ ```
552
+ pnpm exec cdk deploy --context vpc-id=vpc-0123456789 TestRdsSqlServerlessV2Stack
553
+ ```
554
+
555
+ You can also test DSQL support with:
556
+
557
+ ```
558
+ pnpm exec projen integ:deploy:dsql
559
+ ```
560
+
561
+ # To do
562
+
563
+ * Update role: will not revoke connect to previous database if database name has changed.
564
+ '''
565
+ from pkgutil import extend_path
566
+ __path__ = extend_path(__path__, __name__)
567
+
568
+ import abc
569
+ import builtins
570
+ import datetime
571
+ import enum
572
+ import typing
573
+
574
+ import jsii
575
+ import publication
576
+ import typing_extensions
577
+
578
+ import typeguard
579
+ from importlib.metadata import version as _metadata_package_version
580
+ TYPEGUARD_MAJOR_VERSION = int(_metadata_package_version('typeguard').split('.')[0])
581
+
582
+ def check_type(argname: str, value: object, expected_type: typing.Any) -> typing.Any:
583
+ if TYPEGUARD_MAJOR_VERSION <= 2:
584
+ return typeguard.check_type(argname=argname, value=value, expected_type=expected_type) # type:ignore
585
+ else:
586
+ if isinstance(value, jsii._reference_map.InterfaceDynamicProxy): # pyright: ignore [reportAttributeAccessIssue]
587
+ pass
588
+ else:
589
+ if TYPEGUARD_MAJOR_VERSION == 3:
590
+ typeguard.config.collection_check_strategy = typeguard.CollectionCheckStrategy.ALL_ITEMS # type:ignore
591
+ typeguard.check_type(value=value, expected_type=expected_type) # type:ignore
592
+ else:
593
+ typeguard.check_type(value=value, expected_type=expected_type, collection_check_strategy=typeguard.CollectionCheckStrategy.ALL_ITEMS) # type:ignore
594
+
595
+ from ._jsii import *
596
+
597
+ import aws_cdk as _aws_cdk_ceddda9d
598
+ import aws_cdk.aws_dsql as _aws_cdk_aws_dsql_ceddda9d
599
+ import aws_cdk.aws_ec2 as _aws_cdk_aws_ec2_ceddda9d
600
+ import aws_cdk.aws_kms as _aws_cdk_aws_kms_ceddda9d
601
+ import aws_cdk.aws_lambda as _aws_cdk_aws_lambda_ceddda9d
602
+ import aws_cdk.aws_lambda_nodejs as _aws_cdk_aws_lambda_nodejs_ceddda9d
603
+ import aws_cdk.aws_rds as _aws_cdk_aws_rds_ceddda9d
604
+ import aws_cdk.aws_secretsmanager as _aws_cdk_aws_secretsmanager_ceddda9d
605
+ import constructs as _constructs_77d1e7e8
606
+
607
+
608
+ @jsii.enum(jsii_type="cdk-rds-sql.DatabaseEngine")
609
+ class DatabaseEngine(enum.Enum):
610
+ '''Supported database engines.'''
611
+
612
+ POSTGRES = "POSTGRES"
613
+ MYSQL = "MYSQL"
614
+ DSQL = "DSQL"
615
+
616
+
617
+ @jsii.data_type(
618
+ jsii_type="cdk-rds-sql.DatabaseProps",
619
+ jsii_struct_bases=[],
620
+ name_mapping={
621
+ "database_name": "databaseName",
622
+ "provider": "provider",
623
+ "owner": "owner",
624
+ },
625
+ )
626
+ class DatabaseProps:
627
+ def __init__(
628
+ self,
629
+ *,
630
+ database_name: builtins.str,
631
+ provider: "IProvider",
632
+ owner: typing.Optional["Role"] = None,
633
+ ) -> None:
634
+ '''
635
+ :param database_name: Name of database to create.
636
+ :param provider: Provider.
637
+ :param owner: Optional database owner.
638
+ '''
639
+ if __debug__:
640
+ type_hints = typing.get_type_hints(_typecheckingstub__d02a87af93e26ceaf647662fc78818b2f43fe154b349df3c4f5752d22b61ea34)
641
+ check_type(argname="argument database_name", value=database_name, expected_type=type_hints["database_name"])
642
+ check_type(argname="argument provider", value=provider, expected_type=type_hints["provider"])
643
+ check_type(argname="argument owner", value=owner, expected_type=type_hints["owner"])
644
+ self._values: typing.Dict[builtins.str, typing.Any] = {
645
+ "database_name": database_name,
646
+ "provider": provider,
647
+ }
648
+ if owner is not None:
649
+ self._values["owner"] = owner
650
+
651
+ @builtins.property
652
+ def database_name(self) -> builtins.str:
653
+ '''Name of database to create.'''
654
+ result = self._values.get("database_name")
655
+ assert result is not None, "Required property 'database_name' is missing"
656
+ return typing.cast(builtins.str, result)
657
+
658
+ @builtins.property
659
+ def provider(self) -> "IProvider":
660
+ '''Provider.'''
661
+ result = self._values.get("provider")
662
+ assert result is not None, "Required property 'provider' is missing"
663
+ return typing.cast("IProvider", result)
664
+
665
+ @builtins.property
666
+ def owner(self) -> typing.Optional["Role"]:
667
+ '''Optional database owner.'''
668
+ result = self._values.get("owner")
669
+ return typing.cast(typing.Optional["Role"], result)
670
+
671
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
672
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
673
+
674
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
675
+ return not (rhs == self)
676
+
677
+ def __repr__(self) -> str:
678
+ return "DatabaseProps(%s)" % ", ".join(
679
+ k + "=" + repr(v) for k, v in self._values.items()
680
+ )
681
+
682
+
683
+ @jsii.interface(jsii_type="cdk-rds-sql.IDatabase")
684
+ class IDatabase(typing_extensions.Protocol):
685
+ @builtins.property
686
+ @jsii.member(jsii_name="databaseName")
687
+ def database_name(self) -> builtins.str:
688
+ ...
689
+
690
+
691
+ class _IDatabaseProxy:
692
+ __jsii_type__: typing.ClassVar[str] = "cdk-rds-sql.IDatabase"
693
+
694
+ @builtins.property
695
+ @jsii.member(jsii_name="databaseName")
696
+ def database_name(self) -> builtins.str:
697
+ return typing.cast(builtins.str, jsii.get(self, "databaseName"))
698
+
699
+ # Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
700
+ typing.cast(typing.Any, IDatabase).__jsii_proxy_class__ = lambda : _IDatabaseProxy
701
+
702
+
703
+ @jsii.interface(jsii_type="cdk-rds-sql.IProvider")
704
+ class IProvider(typing_extensions.Protocol):
705
+ @builtins.property
706
+ @jsii.member(jsii_name="engine")
707
+ def engine(self) -> builtins.str:
708
+ ...
709
+
710
+ @builtins.property
711
+ @jsii.member(jsii_name="handler")
712
+ def handler(self) -> "_aws_cdk_aws_lambda_ceddda9d.IFunction":
713
+ ...
714
+
715
+ @builtins.property
716
+ @jsii.member(jsii_name="serviceToken")
717
+ def service_token(self) -> builtins.str:
718
+ ...
719
+
720
+ @builtins.property
721
+ @jsii.member(jsii_name="cluster")
722
+ def cluster(
723
+ self,
724
+ ) -> typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]]:
725
+ ...
726
+
727
+ @builtins.property
728
+ @jsii.member(jsii_name="secret")
729
+ def secret(self) -> typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"]:
730
+ ...
731
+
732
+
733
+ class _IProviderProxy:
734
+ __jsii_type__: typing.ClassVar[str] = "cdk-rds-sql.IProvider"
735
+
736
+ @builtins.property
737
+ @jsii.member(jsii_name="engine")
738
+ def engine(self) -> builtins.str:
739
+ return typing.cast(builtins.str, jsii.get(self, "engine"))
740
+
741
+ @builtins.property
742
+ @jsii.member(jsii_name="handler")
743
+ def handler(self) -> "_aws_cdk_aws_lambda_ceddda9d.IFunction":
744
+ return typing.cast("_aws_cdk_aws_lambda_ceddda9d.IFunction", jsii.get(self, "handler"))
745
+
746
+ @builtins.property
747
+ @jsii.member(jsii_name="serviceToken")
748
+ def service_token(self) -> builtins.str:
749
+ return typing.cast(builtins.str, jsii.get(self, "serviceToken"))
750
+
751
+ @builtins.property
752
+ @jsii.member(jsii_name="cluster")
753
+ def cluster(
754
+ self,
755
+ ) -> typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]]:
756
+ return typing.cast(typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]], jsii.get(self, "cluster"))
757
+
758
+ @builtins.property
759
+ @jsii.member(jsii_name="secret")
760
+ def secret(self) -> typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"]:
761
+ return typing.cast(typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"], jsii.get(self, "secret"))
762
+
763
+ # Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
764
+ typing.cast(typing.Any, IProvider).__jsii_proxy_class__ = lambda : _IProviderProxy
765
+
766
+
767
+ class IamGrant(
768
+ _aws_cdk_ceddda9d.CustomResource,
769
+ metaclass=jsii.JSIIMeta,
770
+ jsii_type="cdk-rds-sql.IamGrant",
771
+ ):
772
+ def __init__(
773
+ self,
774
+ scope: "_constructs_77d1e7e8.Construct",
775
+ id: builtins.str,
776
+ *,
777
+ provider: "IProvider",
778
+ resource_arn: builtins.str,
779
+ role_name: builtins.str,
780
+ ) -> None:
781
+ '''
782
+ :param scope: -
783
+ :param id: -
784
+ :param provider: Provider.
785
+ :param resource_arn: IAM resource ARN (role, user, or other IAM principal).
786
+ :param role_name: Database role name to grant IAM access to.
787
+ '''
788
+ if __debug__:
789
+ type_hints = typing.get_type_hints(_typecheckingstub__ddc8001ac6195e8fb417d17f2106bdcd50800e6da2afb84794113f44cc6c18c9)
790
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
791
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
792
+ props = IamGrantProps(
793
+ provider=provider, resource_arn=resource_arn, role_name=role_name
794
+ )
795
+
796
+ jsii.create(self.__class__, self, [scope, id, props])
797
+
798
+
799
+ @jsii.data_type(
800
+ jsii_type="cdk-rds-sql.IamGrantProps",
801
+ jsii_struct_bases=[],
802
+ name_mapping={
803
+ "provider": "provider",
804
+ "resource_arn": "resourceArn",
805
+ "role_name": "roleName",
806
+ },
807
+ )
808
+ class IamGrantProps:
809
+ def __init__(
810
+ self,
811
+ *,
812
+ provider: "IProvider",
813
+ resource_arn: builtins.str,
814
+ role_name: builtins.str,
815
+ ) -> None:
816
+ '''
817
+ :param provider: Provider.
818
+ :param resource_arn: IAM resource ARN (role, user, or other IAM principal).
819
+ :param role_name: Database role name to grant IAM access to.
820
+ '''
821
+ if __debug__:
822
+ type_hints = typing.get_type_hints(_typecheckingstub__4887252bb5c41c89521a26b729d32055341e5bee89b4f65947a38d7c0aaf5dec)
823
+ check_type(argname="argument provider", value=provider, expected_type=type_hints["provider"])
824
+ check_type(argname="argument resource_arn", value=resource_arn, expected_type=type_hints["resource_arn"])
825
+ check_type(argname="argument role_name", value=role_name, expected_type=type_hints["role_name"])
826
+ self._values: typing.Dict[builtins.str, typing.Any] = {
827
+ "provider": provider,
828
+ "resource_arn": resource_arn,
829
+ "role_name": role_name,
830
+ }
831
+
832
+ @builtins.property
833
+ def provider(self) -> "IProvider":
834
+ '''Provider.'''
835
+ result = self._values.get("provider")
836
+ assert result is not None, "Required property 'provider' is missing"
837
+ return typing.cast("IProvider", result)
838
+
839
+ @builtins.property
840
+ def resource_arn(self) -> builtins.str:
841
+ '''IAM resource ARN (role, user, or other IAM principal).'''
842
+ result = self._values.get("resource_arn")
843
+ assert result is not None, "Required property 'resource_arn' is missing"
844
+ return typing.cast(builtins.str, result)
845
+
846
+ @builtins.property
847
+ def role_name(self) -> builtins.str:
848
+ '''Database role name to grant IAM access to.'''
849
+ result = self._values.get("role_name")
850
+ assert result is not None, "Required property 'role_name' is missing"
851
+ return typing.cast(builtins.str, result)
852
+
853
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
854
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
855
+
856
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
857
+ return not (rhs == self)
858
+
859
+ def __repr__(self) -> str:
860
+ return "IamGrantProps(%s)" % ", ".join(
861
+ k + "=" + repr(v) for k, v in self._values.items()
862
+ )
863
+
864
+
865
+ @jsii.implements(IProvider)
866
+ class Provider(
867
+ _constructs_77d1e7e8.Construct,
868
+ metaclass=jsii.JSIIMeta,
869
+ jsii_type="cdk-rds-sql.Provider",
870
+ ):
871
+ def __init__(
872
+ self,
873
+ scope: "_constructs_77d1e7e8.Construct",
874
+ id: builtins.str,
875
+ *,
876
+ cluster: typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"],
877
+ function_props: typing.Optional[typing.Union["_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps", typing.Dict[builtins.str, typing.Any]]] = None,
878
+ logger: typing.Optional[builtins.bool] = None,
879
+ secret: typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"] = None,
880
+ ssl: typing.Optional[builtins.bool] = None,
881
+ timeout: typing.Optional["_aws_cdk_ceddda9d.Duration"] = None,
882
+ vpc: typing.Optional["_aws_cdk_aws_ec2_ceddda9d.IVpc"] = None,
883
+ vpc_subnets: typing.Optional[typing.Union["_aws_cdk_aws_ec2_ceddda9d.SubnetSelection", typing.Dict[builtins.str, typing.Any]]] = None,
884
+ ) -> None:
885
+ '''
886
+ :param scope: -
887
+ :param id: -
888
+ :param cluster: Your database cluster or instance. Supports both traditional RDS/Aurora clusters and DSQL clusters. - For RDS/Aurora: security groups will be configured to allow access - For DSQL: IAM authentication will be used instead of secrets
889
+ :param function_props: Additional function customization. This enables additional function customization such as the log group. However, lambda function properties controlled by other {RdsSqlProps} parameters will trump opions set via this parameter. Default: - empty
890
+ :param logger: Log SQL statements. This includes passwords. Use only for debugging. Default: - false
891
+ :param secret: Secret that grants access to your database. Usually this is your cluster's master secret. Not required when relying on IAM authentication (such as DSQL). Default: - undefined for DSQL clusters using IAM authentication
892
+ :param ssl: Use SSL? Default: - true
893
+ :param timeout: Timeout for lambda to do its work. Default: - 5 minutes
894
+ :param vpc: VPC network to place the provider lambda. Normally this is the VPC of your database. Required when your database is only accessible in a VPC. Not required for DSQL as it uses public endpoints with IAM authentication. Default: - Function is not placed within a VPC.
895
+ :param vpc_subnets: Where to place the network provider lambda within the VPC. Default: - the isolated subnet if not specified
896
+ '''
897
+ if __debug__:
898
+ type_hints = typing.get_type_hints(_typecheckingstub__f569409e68b7292df1965d915629ef8c34532a3dcd05bea0032c564041e409e4)
899
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
900
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
901
+ props = RdsSqlProps(
902
+ cluster=cluster,
903
+ function_props=function_props,
904
+ logger=logger,
905
+ secret=secret,
906
+ ssl=ssl,
907
+ timeout=timeout,
908
+ vpc=vpc,
909
+ vpc_subnets=vpc_subnets,
910
+ )
911
+
912
+ jsii.create(self.__class__, self, [scope, id, props])
913
+
914
+ @jsii.member(jsii_name="fromProviderAttributes")
915
+ @builtins.classmethod
916
+ def from_provider_attributes(
917
+ cls,
918
+ scope: "_constructs_77d1e7e8.Construct",
919
+ id: builtins.str,
920
+ *,
921
+ engine: "DatabaseEngine",
922
+ cluster: typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]] = None,
923
+ function_arn: typing.Optional[builtins.str] = None,
924
+ function_name: typing.Optional[builtins.str] = None,
925
+ ) -> "IProvider":
926
+ '''Import an existing provider Lambda function.
927
+
928
+ :param scope: -
929
+ :param id: -
930
+ :param engine:
931
+ :param cluster: Optional cluster information for role creation. When importing a provider, cluster details are often not available. However, some operations like role creation require cluster endpoint information to build connection secrets. If you plan to create roles with the imported provider, you must provide the cluster reference. If you only plan to use existing roles, databases, schemas, or SQL operations, this can be omitted.
932
+ :param function_arn: Either the ARN or name of the Lambda function. Use functionArn for cross-account or cross-region scenarios. Use functionName for same-account, same-region scenarios.
933
+ :param function_name:
934
+ '''
935
+ if __debug__:
936
+ type_hints = typing.get_type_hints(_typecheckingstub__6447e54f3866ee95542c4c6e6f57beb9f77e9508347c20f14c7bb52a36c8133c)
937
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
938
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
939
+ attrs = ProviderAttributes(
940
+ engine=engine,
941
+ cluster=cluster,
942
+ function_arn=function_arn,
943
+ function_name=function_name,
944
+ )
945
+
946
+ return typing.cast("IProvider", jsii.sinvoke(cls, "fromProviderAttributes", [scope, id, attrs]))
947
+
948
+ @jsii.member(jsii_name="newCustomResourceHandler")
949
+ def _new_custom_resource_handler(
950
+ self,
951
+ scope: "_constructs_77d1e7e8.Construct",
952
+ id: builtins.str,
953
+ *,
954
+ cluster: typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"],
955
+ function_props: typing.Optional[typing.Union["_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps", typing.Dict[builtins.str, typing.Any]]] = None,
956
+ logger: typing.Optional[builtins.bool] = None,
957
+ secret: typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"] = None,
958
+ ssl: typing.Optional[builtins.bool] = None,
959
+ timeout: typing.Optional["_aws_cdk_ceddda9d.Duration"] = None,
960
+ vpc: typing.Optional["_aws_cdk_aws_ec2_ceddda9d.IVpc"] = None,
961
+ vpc_subnets: typing.Optional[typing.Union["_aws_cdk_aws_ec2_ceddda9d.SubnetSelection", typing.Dict[builtins.str, typing.Any]]] = None,
962
+ ) -> "_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunction":
963
+ '''
964
+ :param scope: -
965
+ :param id: -
966
+ :param cluster: Your database cluster or instance. Supports both traditional RDS/Aurora clusters and DSQL clusters. - For RDS/Aurora: security groups will be configured to allow access - For DSQL: IAM authentication will be used instead of secrets
967
+ :param function_props: Additional function customization. This enables additional function customization such as the log group. However, lambda function properties controlled by other {RdsSqlProps} parameters will trump opions set via this parameter. Default: - empty
968
+ :param logger: Log SQL statements. This includes passwords. Use only for debugging. Default: - false
969
+ :param secret: Secret that grants access to your database. Usually this is your cluster's master secret. Not required when relying on IAM authentication (such as DSQL). Default: - undefined for DSQL clusters using IAM authentication
970
+ :param ssl: Use SSL? Default: - true
971
+ :param timeout: Timeout for lambda to do its work. Default: - 5 minutes
972
+ :param vpc: VPC network to place the provider lambda. Normally this is the VPC of your database. Required when your database is only accessible in a VPC. Not required for DSQL as it uses public endpoints with IAM authentication. Default: - Function is not placed within a VPC.
973
+ :param vpc_subnets: Where to place the network provider lambda within the VPC. Default: - the isolated subnet if not specified
974
+ '''
975
+ if __debug__:
976
+ type_hints = typing.get_type_hints(_typecheckingstub__16aa0dc03b1ffdc1c49190bb39d545df3907972a07f344528a5a891c23d0f28c)
977
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
978
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
979
+ props = RdsSqlProps(
980
+ cluster=cluster,
981
+ function_props=function_props,
982
+ logger=logger,
983
+ secret=secret,
984
+ ssl=ssl,
985
+ timeout=timeout,
986
+ vpc=vpc,
987
+ vpc_subnets=vpc_subnets,
988
+ )
989
+
990
+ return typing.cast("_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunction", jsii.invoke(self, "newCustomResourceHandler", [scope, id, props]))
991
+
992
+ @builtins.property
993
+ @jsii.member(jsii_name="engine")
994
+ def engine(self) -> builtins.str:
995
+ '''The engine like "postgres" or "mysql".
996
+
997
+ :default: - if we cannot determine this "postgres"
998
+ '''
999
+ return typing.cast(builtins.str, jsii.get(self, "engine"))
1000
+
1001
+ @builtins.property
1002
+ @jsii.member(jsii_name="handler")
1003
+ def handler(self) -> "_aws_cdk_aws_lambda_ceddda9d.IFunction":
1004
+ return typing.cast("_aws_cdk_aws_lambda_ceddda9d.IFunction", jsii.get(self, "handler"))
1005
+
1006
+ @builtins.property
1007
+ @jsii.member(jsii_name="serviceToken")
1008
+ def service_token(self) -> builtins.str:
1009
+ return typing.cast(builtins.str, jsii.get(self, "serviceToken"))
1010
+
1011
+ @builtins.property
1012
+ @jsii.member(jsii_name="cluster")
1013
+ def cluster(
1014
+ self,
1015
+ ) -> typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]]:
1016
+ return typing.cast(typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]], jsii.get(self, "cluster"))
1017
+
1018
+ @builtins.property
1019
+ @jsii.member(jsii_name="secret")
1020
+ def secret(self) -> typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"]:
1021
+ return typing.cast(typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"], jsii.get(self, "secret"))
1022
+
1023
+
1024
+ @jsii.data_type(
1025
+ jsii_type="cdk-rds-sql.ProviderAttributes",
1026
+ jsii_struct_bases=[],
1027
+ name_mapping={
1028
+ "engine": "engine",
1029
+ "cluster": "cluster",
1030
+ "function_arn": "functionArn",
1031
+ "function_name": "functionName",
1032
+ },
1033
+ )
1034
+ class ProviderAttributes:
1035
+ def __init__(
1036
+ self,
1037
+ *,
1038
+ engine: "DatabaseEngine",
1039
+ cluster: typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]] = None,
1040
+ function_arn: typing.Optional[builtins.str] = None,
1041
+ function_name: typing.Optional[builtins.str] = None,
1042
+ ) -> None:
1043
+ '''
1044
+ :param engine:
1045
+ :param cluster: Optional cluster information for role creation. When importing a provider, cluster details are often not available. However, some operations like role creation require cluster endpoint information to build connection secrets. If you plan to create roles with the imported provider, you must provide the cluster reference. If you only plan to use existing roles, databases, schemas, or SQL operations, this can be omitted.
1046
+ :param function_arn: Either the ARN or name of the Lambda function. Use functionArn for cross-account or cross-region scenarios. Use functionName for same-account, same-region scenarios.
1047
+ :param function_name:
1048
+ '''
1049
+ if __debug__:
1050
+ type_hints = typing.get_type_hints(_typecheckingstub__38638fb01c5b5c1e90a480e969bec755370ee72cad8844940b704cff73c8057c)
1051
+ check_type(argname="argument engine", value=engine, expected_type=type_hints["engine"])
1052
+ check_type(argname="argument cluster", value=cluster, expected_type=type_hints["cluster"])
1053
+ check_type(argname="argument function_arn", value=function_arn, expected_type=type_hints["function_arn"])
1054
+ check_type(argname="argument function_name", value=function_name, expected_type=type_hints["function_name"])
1055
+ self._values: typing.Dict[builtins.str, typing.Any] = {
1056
+ "engine": engine,
1057
+ }
1058
+ if cluster is not None:
1059
+ self._values["cluster"] = cluster
1060
+ if function_arn is not None:
1061
+ self._values["function_arn"] = function_arn
1062
+ if function_name is not None:
1063
+ self._values["function_name"] = function_name
1064
+
1065
+ @builtins.property
1066
+ def engine(self) -> "DatabaseEngine":
1067
+ result = self._values.get("engine")
1068
+ assert result is not None, "Required property 'engine' is missing"
1069
+ return typing.cast("DatabaseEngine", result)
1070
+
1071
+ @builtins.property
1072
+ def cluster(
1073
+ self,
1074
+ ) -> typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]]:
1075
+ '''Optional cluster information for role creation.
1076
+
1077
+ When importing a provider, cluster details are often not available.
1078
+ However, some operations like role creation require cluster endpoint
1079
+ information to build connection secrets.
1080
+
1081
+ If you plan to create roles with the imported provider, you must
1082
+ provide the cluster reference. If you only plan to use existing
1083
+ roles, databases, schemas, or SQL operations, this can be omitted.
1084
+ '''
1085
+ result = self._values.get("cluster")
1086
+ return typing.cast(typing.Optional[typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]], result)
1087
+
1088
+ @builtins.property
1089
+ def function_arn(self) -> typing.Optional[builtins.str]:
1090
+ '''Either the ARN or name of the Lambda function.
1091
+
1092
+ Use functionArn for cross-account or cross-region scenarios.
1093
+ Use functionName for same-account, same-region scenarios.
1094
+ '''
1095
+ result = self._values.get("function_arn")
1096
+ return typing.cast(typing.Optional[builtins.str], result)
1097
+
1098
+ @builtins.property
1099
+ def function_name(self) -> typing.Optional[builtins.str]:
1100
+ result = self._values.get("function_name")
1101
+ return typing.cast(typing.Optional[builtins.str], result)
1102
+
1103
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
1104
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
1105
+
1106
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
1107
+ return not (rhs == self)
1108
+
1109
+ def __repr__(self) -> str:
1110
+ return "ProviderAttributes(%s)" % ", ".join(
1111
+ k + "=" + repr(v) for k, v in self._values.items()
1112
+ )
1113
+
1114
+
1115
+ @jsii.data_type(
1116
+ jsii_type="cdk-rds-sql.RdsSqlProps",
1117
+ jsii_struct_bases=[],
1118
+ name_mapping={
1119
+ "cluster": "cluster",
1120
+ "function_props": "functionProps",
1121
+ "logger": "logger",
1122
+ "secret": "secret",
1123
+ "ssl": "ssl",
1124
+ "timeout": "timeout",
1125
+ "vpc": "vpc",
1126
+ "vpc_subnets": "vpcSubnets",
1127
+ },
1128
+ )
1129
+ class RdsSqlProps:
1130
+ def __init__(
1131
+ self,
1132
+ *,
1133
+ cluster: typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"],
1134
+ function_props: typing.Optional[typing.Union["_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps", typing.Dict[builtins.str, typing.Any]]] = None,
1135
+ logger: typing.Optional[builtins.bool] = None,
1136
+ secret: typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"] = None,
1137
+ ssl: typing.Optional[builtins.bool] = None,
1138
+ timeout: typing.Optional["_aws_cdk_ceddda9d.Duration"] = None,
1139
+ vpc: typing.Optional["_aws_cdk_aws_ec2_ceddda9d.IVpc"] = None,
1140
+ vpc_subnets: typing.Optional[typing.Union["_aws_cdk_aws_ec2_ceddda9d.SubnetSelection", typing.Dict[builtins.str, typing.Any]]] = None,
1141
+ ) -> None:
1142
+ '''
1143
+ :param cluster: Your database cluster or instance. Supports both traditional RDS/Aurora clusters and DSQL clusters. - For RDS/Aurora: security groups will be configured to allow access - For DSQL: IAM authentication will be used instead of secrets
1144
+ :param function_props: Additional function customization. This enables additional function customization such as the log group. However, lambda function properties controlled by other {RdsSqlProps} parameters will trump opions set via this parameter. Default: - empty
1145
+ :param logger: Log SQL statements. This includes passwords. Use only for debugging. Default: - false
1146
+ :param secret: Secret that grants access to your database. Usually this is your cluster's master secret. Not required when relying on IAM authentication (such as DSQL). Default: - undefined for DSQL clusters using IAM authentication
1147
+ :param ssl: Use SSL? Default: - true
1148
+ :param timeout: Timeout for lambda to do its work. Default: - 5 minutes
1149
+ :param vpc: VPC network to place the provider lambda. Normally this is the VPC of your database. Required when your database is only accessible in a VPC. Not required for DSQL as it uses public endpoints with IAM authentication. Default: - Function is not placed within a VPC.
1150
+ :param vpc_subnets: Where to place the network provider lambda within the VPC. Default: - the isolated subnet if not specified
1151
+ '''
1152
+ if isinstance(function_props, dict):
1153
+ function_props = _aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps(**function_props)
1154
+ if isinstance(vpc_subnets, dict):
1155
+ vpc_subnets = _aws_cdk_aws_ec2_ceddda9d.SubnetSelection(**vpc_subnets)
1156
+ if __debug__:
1157
+ type_hints = typing.get_type_hints(_typecheckingstub__1562dfb28e0e71a0b95785ddbc26511738019b8ab5c6885e0ff1f2050e6d045b)
1158
+ check_type(argname="argument cluster", value=cluster, expected_type=type_hints["cluster"])
1159
+ check_type(argname="argument function_props", value=function_props, expected_type=type_hints["function_props"])
1160
+ check_type(argname="argument logger", value=logger, expected_type=type_hints["logger"])
1161
+ check_type(argname="argument secret", value=secret, expected_type=type_hints["secret"])
1162
+ check_type(argname="argument ssl", value=ssl, expected_type=type_hints["ssl"])
1163
+ check_type(argname="argument timeout", value=timeout, expected_type=type_hints["timeout"])
1164
+ check_type(argname="argument vpc", value=vpc, expected_type=type_hints["vpc"])
1165
+ check_type(argname="argument vpc_subnets", value=vpc_subnets, expected_type=type_hints["vpc_subnets"])
1166
+ self._values: typing.Dict[builtins.str, typing.Any] = {
1167
+ "cluster": cluster,
1168
+ }
1169
+ if function_props is not None:
1170
+ self._values["function_props"] = function_props
1171
+ if logger is not None:
1172
+ self._values["logger"] = logger
1173
+ if secret is not None:
1174
+ self._values["secret"] = secret
1175
+ if ssl is not None:
1176
+ self._values["ssl"] = ssl
1177
+ if timeout is not None:
1178
+ self._values["timeout"] = timeout
1179
+ if vpc is not None:
1180
+ self._values["vpc"] = vpc
1181
+ if vpc_subnets is not None:
1182
+ self._values["vpc_subnets"] = vpc_subnets
1183
+
1184
+ @builtins.property
1185
+ def cluster(
1186
+ self,
1187
+ ) -> typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"]:
1188
+ '''Your database cluster or instance.
1189
+
1190
+ Supports both traditional RDS/Aurora clusters and DSQL clusters.
1191
+
1192
+ - For RDS/Aurora: security groups will be configured to allow access
1193
+ - For DSQL: IAM authentication will be used instead of secrets
1194
+ '''
1195
+ result = self._values.get("cluster")
1196
+ assert result is not None, "Required property 'cluster' is missing"
1197
+ return typing.cast(typing.Union["_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster", "_aws_cdk_aws_rds_ceddda9d.IDatabaseInstance", "_aws_cdk_aws_dsql_ceddda9d.CfnCluster"], result)
1198
+
1199
+ @builtins.property
1200
+ def function_props(
1201
+ self,
1202
+ ) -> typing.Optional["_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps"]:
1203
+ '''Additional function customization.
1204
+
1205
+ This enables additional function customization such as the log group. However,
1206
+ lambda function properties controlled by other {RdsSqlProps} parameters will trump
1207
+ opions set via this parameter.
1208
+
1209
+ :default: - empty
1210
+ '''
1211
+ result = self._values.get("function_props")
1212
+ return typing.cast(typing.Optional["_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps"], result)
1213
+
1214
+ @builtins.property
1215
+ def logger(self) -> typing.Optional[builtins.bool]:
1216
+ '''Log SQL statements.
1217
+
1218
+ This includes passwords. Use only for debugging.
1219
+
1220
+ :default: - false
1221
+ '''
1222
+ result = self._values.get("logger")
1223
+ return typing.cast(typing.Optional[builtins.bool], result)
1224
+
1225
+ @builtins.property
1226
+ def secret(self) -> typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"]:
1227
+ '''Secret that grants access to your database.
1228
+
1229
+ Usually this is your cluster's master secret.
1230
+ Not required when relying on IAM authentication (such as DSQL).
1231
+
1232
+ :default: - undefined for DSQL clusters using IAM authentication
1233
+ '''
1234
+ result = self._values.get("secret")
1235
+ return typing.cast(typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"], result)
1236
+
1237
+ @builtins.property
1238
+ def ssl(self) -> typing.Optional[builtins.bool]:
1239
+ '''Use SSL?
1240
+
1241
+ :default: - true
1242
+ '''
1243
+ result = self._values.get("ssl")
1244
+ return typing.cast(typing.Optional[builtins.bool], result)
1245
+
1246
+ @builtins.property
1247
+ def timeout(self) -> typing.Optional["_aws_cdk_ceddda9d.Duration"]:
1248
+ '''Timeout for lambda to do its work.
1249
+
1250
+ :default: - 5 minutes
1251
+ '''
1252
+ result = self._values.get("timeout")
1253
+ return typing.cast(typing.Optional["_aws_cdk_ceddda9d.Duration"], result)
1254
+
1255
+ @builtins.property
1256
+ def vpc(self) -> typing.Optional["_aws_cdk_aws_ec2_ceddda9d.IVpc"]:
1257
+ '''VPC network to place the provider lambda.
1258
+
1259
+ Normally this is the VPC of your database.
1260
+ Required when your database is only accessible in a VPC.
1261
+ Not required for DSQL as it uses public endpoints with IAM authentication.
1262
+
1263
+ :default: - Function is not placed within a VPC.
1264
+ '''
1265
+ result = self._values.get("vpc")
1266
+ return typing.cast(typing.Optional["_aws_cdk_aws_ec2_ceddda9d.IVpc"], result)
1267
+
1268
+ @builtins.property
1269
+ def vpc_subnets(
1270
+ self,
1271
+ ) -> typing.Optional["_aws_cdk_aws_ec2_ceddda9d.SubnetSelection"]:
1272
+ '''Where to place the network provider lambda within the VPC.
1273
+
1274
+ :default: - the isolated subnet if not specified
1275
+ '''
1276
+ result = self._values.get("vpc_subnets")
1277
+ return typing.cast(typing.Optional["_aws_cdk_aws_ec2_ceddda9d.SubnetSelection"], result)
1278
+
1279
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
1280
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
1281
+
1282
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
1283
+ return not (rhs == self)
1284
+
1285
+ def __repr__(self) -> str:
1286
+ return "RdsSqlProps(%s)" % ", ".join(
1287
+ k + "=" + repr(v) for k, v in self._values.items()
1288
+ )
1289
+
1290
+
1291
+ @jsii.enum(jsii_type="cdk-rds-sql.RdsSqlResource")
1292
+ class RdsSqlResource(enum.Enum):
1293
+ SCHEMA = "SCHEMA"
1294
+ ROLE = "ROLE"
1295
+ SQL = "SQL"
1296
+ DATABASE = "DATABASE"
1297
+ PARAMETER_PASSWORD = "PARAMETER_PASSWORD"
1298
+ IAM_GRANT = "IAM_GRANT"
1299
+
1300
+
1301
+ class Role(
1302
+ _constructs_77d1e7e8.Construct,
1303
+ metaclass=jsii.JSIIMeta,
1304
+ jsii_type="cdk-rds-sql.Role",
1305
+ ):
1306
+ def __init__(
1307
+ self,
1308
+ scope: "_constructs_77d1e7e8.Construct",
1309
+ id: builtins.str,
1310
+ *,
1311
+ provider: "IProvider",
1312
+ role_name: builtins.str,
1313
+ database: typing.Optional["IDatabase"] = None,
1314
+ database_name: typing.Optional[builtins.str] = None,
1315
+ enable_iam_auth: typing.Optional[builtins.bool] = None,
1316
+ encryption_key: typing.Optional["_aws_cdk_aws_kms_ceddda9d.IKey"] = None,
1317
+ parameter_prefix: typing.Optional[builtins.str] = None,
1318
+ secret_name: typing.Optional[builtins.str] = None,
1319
+ ) -> None:
1320
+ '''
1321
+ :param scope: -
1322
+ :param id: -
1323
+ :param provider: Provider.
1324
+ :param role_name: SQL.
1325
+ :param database: Optional database this user is expected to use. If the database exists, connect privileges are granted. Specify one of ``database`` or ``databaseName``. This is the name that will be stored in the role's secret as the database name to use.
1326
+ :param database_name: Optional database name this user is expected to use. If the database exists, connect privileges are granted. Specify one of ``database`` or ``databaseName``. This is the name that will be stored in the role's secret as the database name to use.
1327
+ :param enable_iam_auth: Enable IAM authentication for this role. When enabled, the role will be created without a password and configured for AWS IAM database authentication. No secret will be created for this role. Note: For DSQL clusters, this property is ignored as DSQL always uses IAM authentication. Default: false - use password authentication
1328
+ :param encryption_key: A new secret is created for this user. Optionally encrypt it with the given key.
1329
+ :param parameter_prefix: Prefix for SSM parameters to store credentials in Parameter Store. When defined, credentials will also be stored as parameters. The parameter names such as "password" is simply appended to ``parameterPrefix``, so make sure the prefix ends with a slash if you have your parameter names slash separated. The password parameter is refreshed when CloudFormation updates the generated secret resource. Default: - credentials are only stored in Secrets Manager
1330
+ :param secret_name: A new secret is created for this user. Optionally add secret name to the secret.
1331
+ '''
1332
+ if __debug__:
1333
+ type_hints = typing.get_type_hints(_typecheckingstub__062afab8717d46f6fc2a31188b28d9e663190b2080174cc7f1ddd691f699de7e)
1334
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
1335
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
1336
+ props = RoleProps(
1337
+ provider=provider,
1338
+ role_name=role_name,
1339
+ database=database,
1340
+ database_name=database_name,
1341
+ enable_iam_auth=enable_iam_auth,
1342
+ encryption_key=encryption_key,
1343
+ parameter_prefix=parameter_prefix,
1344
+ secret_name=secret_name,
1345
+ )
1346
+
1347
+ jsii.create(self.__class__, self, [scope, id, props])
1348
+
1349
+ @builtins.property
1350
+ @jsii.member(jsii_name="roleName")
1351
+ def role_name(self) -> builtins.str:
1352
+ '''The role name.'''
1353
+ return typing.cast(builtins.str, jsii.get(self, "roleName"))
1354
+
1355
+ @builtins.property
1356
+ @jsii.member(jsii_name="secret")
1357
+ def secret(self) -> typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"]:
1358
+ '''The generated secret containing connection information and password.
1359
+
1360
+ This is only available when:
1361
+
1362
+ - The provider is not a DSQL cluster (DSQL uses IAM authentication)
1363
+ - ``enableIamAuth`` is not set to ``true``
1364
+
1365
+ When using IAM authentication, no secret is created as the password
1366
+ is generated dynamically using IAM credentials.
1367
+ '''
1368
+ return typing.cast(typing.Optional["_aws_cdk_aws_secretsmanager_ceddda9d.ISecret"], jsii.get(self, "secret"))
1369
+
1370
+
1371
+ @jsii.data_type(
1372
+ jsii_type="cdk-rds-sql.RoleProps",
1373
+ jsii_struct_bases=[],
1374
+ name_mapping={
1375
+ "provider": "provider",
1376
+ "role_name": "roleName",
1377
+ "database": "database",
1378
+ "database_name": "databaseName",
1379
+ "enable_iam_auth": "enableIamAuth",
1380
+ "encryption_key": "encryptionKey",
1381
+ "parameter_prefix": "parameterPrefix",
1382
+ "secret_name": "secretName",
1383
+ },
1384
+ )
1385
+ class RoleProps:
1386
+ def __init__(
1387
+ self,
1388
+ *,
1389
+ provider: "IProvider",
1390
+ role_name: builtins.str,
1391
+ database: typing.Optional["IDatabase"] = None,
1392
+ database_name: typing.Optional[builtins.str] = None,
1393
+ enable_iam_auth: typing.Optional[builtins.bool] = None,
1394
+ encryption_key: typing.Optional["_aws_cdk_aws_kms_ceddda9d.IKey"] = None,
1395
+ parameter_prefix: typing.Optional[builtins.str] = None,
1396
+ secret_name: typing.Optional[builtins.str] = None,
1397
+ ) -> None:
1398
+ '''
1399
+ :param provider: Provider.
1400
+ :param role_name: SQL.
1401
+ :param database: Optional database this user is expected to use. If the database exists, connect privileges are granted. Specify one of ``database`` or ``databaseName``. This is the name that will be stored in the role's secret as the database name to use.
1402
+ :param database_name: Optional database name this user is expected to use. If the database exists, connect privileges are granted. Specify one of ``database`` or ``databaseName``. This is the name that will be stored in the role's secret as the database name to use.
1403
+ :param enable_iam_auth: Enable IAM authentication for this role. When enabled, the role will be created without a password and configured for AWS IAM database authentication. No secret will be created for this role. Note: For DSQL clusters, this property is ignored as DSQL always uses IAM authentication. Default: false - use password authentication
1404
+ :param encryption_key: A new secret is created for this user. Optionally encrypt it with the given key.
1405
+ :param parameter_prefix: Prefix for SSM parameters to store credentials in Parameter Store. When defined, credentials will also be stored as parameters. The parameter names such as "password" is simply appended to ``parameterPrefix``, so make sure the prefix ends with a slash if you have your parameter names slash separated. The password parameter is refreshed when CloudFormation updates the generated secret resource. Default: - credentials are only stored in Secrets Manager
1406
+ :param secret_name: A new secret is created for this user. Optionally add secret name to the secret.
1407
+ '''
1408
+ if __debug__:
1409
+ type_hints = typing.get_type_hints(_typecheckingstub__a7ed79cdb7903207b3240698f6bcb0582905979c1519e2b49d66fa6fbdac11ee)
1410
+ check_type(argname="argument provider", value=provider, expected_type=type_hints["provider"])
1411
+ check_type(argname="argument role_name", value=role_name, expected_type=type_hints["role_name"])
1412
+ check_type(argname="argument database", value=database, expected_type=type_hints["database"])
1413
+ check_type(argname="argument database_name", value=database_name, expected_type=type_hints["database_name"])
1414
+ check_type(argname="argument enable_iam_auth", value=enable_iam_auth, expected_type=type_hints["enable_iam_auth"])
1415
+ check_type(argname="argument encryption_key", value=encryption_key, expected_type=type_hints["encryption_key"])
1416
+ check_type(argname="argument parameter_prefix", value=parameter_prefix, expected_type=type_hints["parameter_prefix"])
1417
+ check_type(argname="argument secret_name", value=secret_name, expected_type=type_hints["secret_name"])
1418
+ self._values: typing.Dict[builtins.str, typing.Any] = {
1419
+ "provider": provider,
1420
+ "role_name": role_name,
1421
+ }
1422
+ if database is not None:
1423
+ self._values["database"] = database
1424
+ if database_name is not None:
1425
+ self._values["database_name"] = database_name
1426
+ if enable_iam_auth is not None:
1427
+ self._values["enable_iam_auth"] = enable_iam_auth
1428
+ if encryption_key is not None:
1429
+ self._values["encryption_key"] = encryption_key
1430
+ if parameter_prefix is not None:
1431
+ self._values["parameter_prefix"] = parameter_prefix
1432
+ if secret_name is not None:
1433
+ self._values["secret_name"] = secret_name
1434
+
1435
+ @builtins.property
1436
+ def provider(self) -> "IProvider":
1437
+ '''Provider.'''
1438
+ result = self._values.get("provider")
1439
+ assert result is not None, "Required property 'provider' is missing"
1440
+ return typing.cast("IProvider", result)
1441
+
1442
+ @builtins.property
1443
+ def role_name(self) -> builtins.str:
1444
+ '''SQL.'''
1445
+ result = self._values.get("role_name")
1446
+ assert result is not None, "Required property 'role_name' is missing"
1447
+ return typing.cast(builtins.str, result)
1448
+
1449
+ @builtins.property
1450
+ def database(self) -> typing.Optional["IDatabase"]:
1451
+ '''Optional database this user is expected to use.
1452
+
1453
+ If the database exists, connect privileges are granted.
1454
+
1455
+ Specify one of ``database`` or ``databaseName``. This is the name
1456
+ that will be stored in the role's secret as the database name to
1457
+ use.
1458
+ '''
1459
+ result = self._values.get("database")
1460
+ return typing.cast(typing.Optional["IDatabase"], result)
1461
+
1462
+ @builtins.property
1463
+ def database_name(self) -> typing.Optional[builtins.str]:
1464
+ '''Optional database name this user is expected to use.
1465
+
1466
+ If the database exists, connect privileges are granted.
1467
+
1468
+ Specify one of ``database`` or ``databaseName``. This is the name
1469
+ that will be stored in the role's secret as the database name to
1470
+ use.
1471
+ '''
1472
+ result = self._values.get("database_name")
1473
+ return typing.cast(typing.Optional[builtins.str], result)
1474
+
1475
+ @builtins.property
1476
+ def enable_iam_auth(self) -> typing.Optional[builtins.bool]:
1477
+ '''Enable IAM authentication for this role.
1478
+
1479
+ When enabled, the role will be created without a password and
1480
+ configured for AWS IAM database authentication. No secret will
1481
+ be created for this role.
1482
+
1483
+ Note: For DSQL clusters, this property is ignored as DSQL always
1484
+ uses IAM authentication.
1485
+
1486
+ :default: false - use password authentication
1487
+ '''
1488
+ result = self._values.get("enable_iam_auth")
1489
+ return typing.cast(typing.Optional[builtins.bool], result)
1490
+
1491
+ @builtins.property
1492
+ def encryption_key(self) -> typing.Optional["_aws_cdk_aws_kms_ceddda9d.IKey"]:
1493
+ '''A new secret is created for this user.
1494
+
1495
+ Optionally encrypt it with the given key.
1496
+ '''
1497
+ result = self._values.get("encryption_key")
1498
+ return typing.cast(typing.Optional["_aws_cdk_aws_kms_ceddda9d.IKey"], result)
1499
+
1500
+ @builtins.property
1501
+ def parameter_prefix(self) -> typing.Optional[builtins.str]:
1502
+ '''Prefix for SSM parameters to store credentials in Parameter Store. When defined, credentials will also be stored as parameters.
1503
+
1504
+ The parameter names such as "password" is simply appended to
1505
+ ``parameterPrefix``, so make sure the prefix ends with a slash if
1506
+ you have your parameter names slash separated.
1507
+
1508
+ The password parameter is refreshed when CloudFormation updates the
1509
+ generated secret resource.
1510
+
1511
+ :default: - credentials are only stored in Secrets Manager
1512
+ '''
1513
+ result = self._values.get("parameter_prefix")
1514
+ return typing.cast(typing.Optional[builtins.str], result)
1515
+
1516
+ @builtins.property
1517
+ def secret_name(self) -> typing.Optional[builtins.str]:
1518
+ '''A new secret is created for this user.
1519
+
1520
+ Optionally add secret name to the secret.
1521
+ '''
1522
+ result = self._values.get("secret_name")
1523
+ return typing.cast(typing.Optional[builtins.str], result)
1524
+
1525
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
1526
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
1527
+
1528
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
1529
+ return not (rhs == self)
1530
+
1531
+ def __repr__(self) -> str:
1532
+ return "RoleProps(%s)" % ", ".join(
1533
+ k + "=" + repr(v) for k, v in self._values.items()
1534
+ )
1535
+
1536
+
1537
+ class Schema(
1538
+ _aws_cdk_ceddda9d.CustomResource,
1539
+ metaclass=jsii.JSIIMeta,
1540
+ jsii_type="cdk-rds-sql.Schema",
1541
+ ):
1542
+ def __init__(
1543
+ self,
1544
+ scope: "_constructs_77d1e7e8.Construct",
1545
+ id: builtins.str,
1546
+ *,
1547
+ provider: "IProvider",
1548
+ schema_name: builtins.str,
1549
+ database: typing.Optional["IDatabase"] = None,
1550
+ role: typing.Optional["Role"] = None,
1551
+ ) -> None:
1552
+ '''
1553
+ :param scope: -
1554
+ :param id: -
1555
+ :param provider: Provider.
1556
+ :param schema_name: Schema name.
1557
+ :param database: Optional database. Default: - use default database
1558
+ :param role: Optional role which will be granted usage and create permissions to this schema. This way the role can read its own tables, but cannot see or access tables created by others.
1559
+ '''
1560
+ if __debug__:
1561
+ type_hints = typing.get_type_hints(_typecheckingstub__23264d20ca42f56453469fb6eae1679bf4f901ace3ccab77b186aa28167779bf)
1562
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
1563
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
1564
+ props = SchemaProps(
1565
+ provider=provider, schema_name=schema_name, database=database, role=role
1566
+ )
1567
+
1568
+ jsii.create(self.__class__, self, [scope, id, props])
1569
+
1570
+ @builtins.property
1571
+ @jsii.member(jsii_name="schemaName")
1572
+ def schema_name(self) -> builtins.str:
1573
+ return typing.cast(builtins.str, jsii.get(self, "schemaName"))
1574
+
1575
+
1576
+ @jsii.data_type(
1577
+ jsii_type="cdk-rds-sql.SchemaProps",
1578
+ jsii_struct_bases=[],
1579
+ name_mapping={
1580
+ "provider": "provider",
1581
+ "schema_name": "schemaName",
1582
+ "database": "database",
1583
+ "role": "role",
1584
+ },
1585
+ )
1586
+ class SchemaProps:
1587
+ def __init__(
1588
+ self,
1589
+ *,
1590
+ provider: "IProvider",
1591
+ schema_name: builtins.str,
1592
+ database: typing.Optional["IDatabase"] = None,
1593
+ role: typing.Optional["Role"] = None,
1594
+ ) -> None:
1595
+ '''
1596
+ :param provider: Provider.
1597
+ :param schema_name: Schema name.
1598
+ :param database: Optional database. Default: - use default database
1599
+ :param role: Optional role which will be granted usage and create permissions to this schema. This way the role can read its own tables, but cannot see or access tables created by others.
1600
+ '''
1601
+ if __debug__:
1602
+ type_hints = typing.get_type_hints(_typecheckingstub__3e5c9257731fa92bb3b0a3fd8f4556888ed99294fcba1b14ade48e8d8d57c6b0)
1603
+ check_type(argname="argument provider", value=provider, expected_type=type_hints["provider"])
1604
+ check_type(argname="argument schema_name", value=schema_name, expected_type=type_hints["schema_name"])
1605
+ check_type(argname="argument database", value=database, expected_type=type_hints["database"])
1606
+ check_type(argname="argument role", value=role, expected_type=type_hints["role"])
1607
+ self._values: typing.Dict[builtins.str, typing.Any] = {
1608
+ "provider": provider,
1609
+ "schema_name": schema_name,
1610
+ }
1611
+ if database is not None:
1612
+ self._values["database"] = database
1613
+ if role is not None:
1614
+ self._values["role"] = role
1615
+
1616
+ @builtins.property
1617
+ def provider(self) -> "IProvider":
1618
+ '''Provider.'''
1619
+ result = self._values.get("provider")
1620
+ assert result is not None, "Required property 'provider' is missing"
1621
+ return typing.cast("IProvider", result)
1622
+
1623
+ @builtins.property
1624
+ def schema_name(self) -> builtins.str:
1625
+ '''Schema name.'''
1626
+ result = self._values.get("schema_name")
1627
+ assert result is not None, "Required property 'schema_name' is missing"
1628
+ return typing.cast(builtins.str, result)
1629
+
1630
+ @builtins.property
1631
+ def database(self) -> typing.Optional["IDatabase"]:
1632
+ '''Optional database.
1633
+
1634
+ :default: - use default database
1635
+ '''
1636
+ result = self._values.get("database")
1637
+ return typing.cast(typing.Optional["IDatabase"], result)
1638
+
1639
+ @builtins.property
1640
+ def role(self) -> typing.Optional["Role"]:
1641
+ '''Optional role which will be granted usage and create permissions to this schema.
1642
+
1643
+ This way the role can read its own tables, but
1644
+ cannot see or access tables created by others.
1645
+ '''
1646
+ result = self._values.get("role")
1647
+ return typing.cast(typing.Optional["Role"], result)
1648
+
1649
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
1650
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
1651
+
1652
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
1653
+ return not (rhs == self)
1654
+
1655
+ def __repr__(self) -> str:
1656
+ return "SchemaProps(%s)" % ", ".join(
1657
+ k + "=" + repr(v) for k, v in self._values.items()
1658
+ )
1659
+
1660
+
1661
+ class Sql(
1662
+ _aws_cdk_ceddda9d.CustomResource,
1663
+ metaclass=jsii.JSIIMeta,
1664
+ jsii_type="cdk-rds-sql.Sql",
1665
+ ):
1666
+ def __init__(
1667
+ self,
1668
+ scope: "_constructs_77d1e7e8.Construct",
1669
+ id: builtins.str,
1670
+ *,
1671
+ provider: "IProvider",
1672
+ database: typing.Optional["IDatabase"] = None,
1673
+ rollback: typing.Optional[builtins.str] = None,
1674
+ statement: typing.Optional[builtins.str] = None,
1675
+ ) -> None:
1676
+ '''
1677
+ :param scope: -
1678
+ :param id: -
1679
+ :param provider: Provider.
1680
+ :param database: Optional database. Default: - use default database
1681
+ :param rollback: Optional statment to be executed when the resource is deleted.
1682
+ :param statement: SQL.
1683
+ '''
1684
+ if __debug__:
1685
+ type_hints = typing.get_type_hints(_typecheckingstub__a34aa094d1e87a65ca4be0fe7c3fad7c2a9f986cfd40a3f07de15d3d6b0d2139)
1686
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
1687
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
1688
+ props = SqlProps(
1689
+ provider=provider,
1690
+ database=database,
1691
+ rollback=rollback,
1692
+ statement=statement,
1693
+ )
1694
+
1695
+ jsii.create(self.__class__, self, [scope, id, props])
1696
+
1697
+
1698
+ @jsii.data_type(
1699
+ jsii_type="cdk-rds-sql.SqlProps",
1700
+ jsii_struct_bases=[],
1701
+ name_mapping={
1702
+ "provider": "provider",
1703
+ "database": "database",
1704
+ "rollback": "rollback",
1705
+ "statement": "statement",
1706
+ },
1707
+ )
1708
+ class SqlProps:
1709
+ def __init__(
1710
+ self,
1711
+ *,
1712
+ provider: "IProvider",
1713
+ database: typing.Optional["IDatabase"] = None,
1714
+ rollback: typing.Optional[builtins.str] = None,
1715
+ statement: typing.Optional[builtins.str] = None,
1716
+ ) -> None:
1717
+ '''
1718
+ :param provider: Provider.
1719
+ :param database: Optional database. Default: - use default database
1720
+ :param rollback: Optional statment to be executed when the resource is deleted.
1721
+ :param statement: SQL.
1722
+ '''
1723
+ if __debug__:
1724
+ type_hints = typing.get_type_hints(_typecheckingstub__fee81de7736c28ed1e24db0db96a0f7084eb4dad448f37b2efdc59960daf7f24)
1725
+ check_type(argname="argument provider", value=provider, expected_type=type_hints["provider"])
1726
+ check_type(argname="argument database", value=database, expected_type=type_hints["database"])
1727
+ check_type(argname="argument rollback", value=rollback, expected_type=type_hints["rollback"])
1728
+ check_type(argname="argument statement", value=statement, expected_type=type_hints["statement"])
1729
+ self._values: typing.Dict[builtins.str, typing.Any] = {
1730
+ "provider": provider,
1731
+ }
1732
+ if database is not None:
1733
+ self._values["database"] = database
1734
+ if rollback is not None:
1735
+ self._values["rollback"] = rollback
1736
+ if statement is not None:
1737
+ self._values["statement"] = statement
1738
+
1739
+ @builtins.property
1740
+ def provider(self) -> "IProvider":
1741
+ '''Provider.'''
1742
+ result = self._values.get("provider")
1743
+ assert result is not None, "Required property 'provider' is missing"
1744
+ return typing.cast("IProvider", result)
1745
+
1746
+ @builtins.property
1747
+ def database(self) -> typing.Optional["IDatabase"]:
1748
+ '''Optional database.
1749
+
1750
+ :default: - use default database
1751
+ '''
1752
+ result = self._values.get("database")
1753
+ return typing.cast(typing.Optional["IDatabase"], result)
1754
+
1755
+ @builtins.property
1756
+ def rollback(self) -> typing.Optional[builtins.str]:
1757
+ '''Optional statment to be executed when the resource is deleted.'''
1758
+ result = self._values.get("rollback")
1759
+ return typing.cast(typing.Optional[builtins.str], result)
1760
+
1761
+ @builtins.property
1762
+ def statement(self) -> typing.Optional[builtins.str]:
1763
+ '''SQL.'''
1764
+ result = self._values.get("statement")
1765
+ return typing.cast(typing.Optional[builtins.str], result)
1766
+
1767
+ def __eq__(self, rhs: typing.Any) -> builtins.bool:
1768
+ return isinstance(rhs, self.__class__) and rhs._values == self._values
1769
+
1770
+ def __ne__(self, rhs: typing.Any) -> builtins.bool:
1771
+ return not (rhs == self)
1772
+
1773
+ def __repr__(self) -> str:
1774
+ return "SqlProps(%s)" % ", ".join(
1775
+ k + "=" + repr(v) for k, v in self._values.items()
1776
+ )
1777
+
1778
+
1779
+ @jsii.implements(IDatabase)
1780
+ class Database(
1781
+ _aws_cdk_ceddda9d.CustomResource,
1782
+ metaclass=jsii.JSIIMeta,
1783
+ jsii_type="cdk-rds-sql.Database",
1784
+ ):
1785
+ def __init__(
1786
+ self,
1787
+ scope: "_constructs_77d1e7e8.Construct",
1788
+ id: builtins.str,
1789
+ *,
1790
+ database_name: builtins.str,
1791
+ provider: "IProvider",
1792
+ owner: typing.Optional["Role"] = None,
1793
+ ) -> None:
1794
+ '''
1795
+ :param scope: -
1796
+ :param id: -
1797
+ :param database_name: Name of database to create.
1798
+ :param provider: Provider.
1799
+ :param owner: Optional database owner.
1800
+ '''
1801
+ if __debug__:
1802
+ type_hints = typing.get_type_hints(_typecheckingstub__9b0a129482abaf744a12ee5aabac9c0545bc3cdf8edcfb3dca83d0c1051326ed)
1803
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
1804
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
1805
+ props = DatabaseProps(
1806
+ database_name=database_name, provider=provider, owner=owner
1807
+ )
1808
+
1809
+ jsii.create(self.__class__, self, [scope, id, props])
1810
+
1811
+ @jsii.member(jsii_name="fromDatabaseName")
1812
+ @builtins.classmethod
1813
+ def from_database_name(
1814
+ cls,
1815
+ scope: "_constructs_77d1e7e8.Construct",
1816
+ id: builtins.str,
1817
+ database_name: builtins.str,
1818
+ ) -> "IDatabase":
1819
+ '''Return a Database based upon name only.
1820
+
1821
+ Use for importing existing databases.
1822
+
1823
+ :param scope: -
1824
+ :param id: -
1825
+ :param database_name: -
1826
+ '''
1827
+ if __debug__:
1828
+ type_hints = typing.get_type_hints(_typecheckingstub__771fb1f62814ed88a15c2f9d4d948498f7416f30cd8e9d630b3ea09667333681)
1829
+ check_type(argname="argument scope", value=scope, expected_type=type_hints["scope"])
1830
+ check_type(argname="argument id", value=id, expected_type=type_hints["id"])
1831
+ check_type(argname="argument database_name", value=database_name, expected_type=type_hints["database_name"])
1832
+ return typing.cast("IDatabase", jsii.sinvoke(cls, "fromDatabaseName", [scope, id, database_name]))
1833
+
1834
+ @builtins.property
1835
+ @jsii.member(jsii_name="databaseName")
1836
+ def database_name(self) -> builtins.str:
1837
+ return typing.cast(builtins.str, jsii.get(self, "databaseName"))
1838
+
1839
+
1840
+ __all__ = [
1841
+ "Database",
1842
+ "DatabaseEngine",
1843
+ "DatabaseProps",
1844
+ "IDatabase",
1845
+ "IProvider",
1846
+ "IamGrant",
1847
+ "IamGrantProps",
1848
+ "Provider",
1849
+ "ProviderAttributes",
1850
+ "RdsSqlProps",
1851
+ "RdsSqlResource",
1852
+ "Role",
1853
+ "RoleProps",
1854
+ "Schema",
1855
+ "SchemaProps",
1856
+ "Sql",
1857
+ "SqlProps",
1858
+ ]
1859
+
1860
+ publication.publish()
1861
+
1862
+ def _typecheckingstub__d02a87af93e26ceaf647662fc78818b2f43fe154b349df3c4f5752d22b61ea34(
1863
+ *,
1864
+ database_name: builtins.str,
1865
+ provider: IProvider,
1866
+ owner: typing.Optional[Role] = None,
1867
+ ) -> None:
1868
+ """Type checking stubs"""
1869
+ pass
1870
+
1871
+ def _typecheckingstub__ddc8001ac6195e8fb417d17f2106bdcd50800e6da2afb84794113f44cc6c18c9(
1872
+ scope: _constructs_77d1e7e8.Construct,
1873
+ id: builtins.str,
1874
+ *,
1875
+ provider: IProvider,
1876
+ resource_arn: builtins.str,
1877
+ role_name: builtins.str,
1878
+ ) -> None:
1879
+ """Type checking stubs"""
1880
+ pass
1881
+
1882
+ def _typecheckingstub__4887252bb5c41c89521a26b729d32055341e5bee89b4f65947a38d7c0aaf5dec(
1883
+ *,
1884
+ provider: IProvider,
1885
+ resource_arn: builtins.str,
1886
+ role_name: builtins.str,
1887
+ ) -> None:
1888
+ """Type checking stubs"""
1889
+ pass
1890
+
1891
+ def _typecheckingstub__f569409e68b7292df1965d915629ef8c34532a3dcd05bea0032c564041e409e4(
1892
+ scope: _constructs_77d1e7e8.Construct,
1893
+ id: builtins.str,
1894
+ *,
1895
+ cluster: typing.Union[_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster, _aws_cdk_aws_rds_ceddda9d.IDatabaseInstance, _aws_cdk_aws_dsql_ceddda9d.CfnCluster],
1896
+ function_props: typing.Optional[typing.Union[_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps, typing.Dict[builtins.str, typing.Any]]] = None,
1897
+ logger: typing.Optional[builtins.bool] = None,
1898
+ secret: typing.Optional[_aws_cdk_aws_secretsmanager_ceddda9d.ISecret] = None,
1899
+ ssl: typing.Optional[builtins.bool] = None,
1900
+ timeout: typing.Optional[_aws_cdk_ceddda9d.Duration] = None,
1901
+ vpc: typing.Optional[_aws_cdk_aws_ec2_ceddda9d.IVpc] = None,
1902
+ vpc_subnets: typing.Optional[typing.Union[_aws_cdk_aws_ec2_ceddda9d.SubnetSelection, typing.Dict[builtins.str, typing.Any]]] = None,
1903
+ ) -> None:
1904
+ """Type checking stubs"""
1905
+ pass
1906
+
1907
+ def _typecheckingstub__6447e54f3866ee95542c4c6e6f57beb9f77e9508347c20f14c7bb52a36c8133c(
1908
+ scope: _constructs_77d1e7e8.Construct,
1909
+ id: builtins.str,
1910
+ *,
1911
+ engine: DatabaseEngine,
1912
+ cluster: typing.Optional[typing.Union[_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster, _aws_cdk_aws_rds_ceddda9d.IDatabaseInstance, _aws_cdk_aws_dsql_ceddda9d.CfnCluster]] = None,
1913
+ function_arn: typing.Optional[builtins.str] = None,
1914
+ function_name: typing.Optional[builtins.str] = None,
1915
+ ) -> None:
1916
+ """Type checking stubs"""
1917
+ pass
1918
+
1919
+ def _typecheckingstub__16aa0dc03b1ffdc1c49190bb39d545df3907972a07f344528a5a891c23d0f28c(
1920
+ scope: _constructs_77d1e7e8.Construct,
1921
+ id: builtins.str,
1922
+ *,
1923
+ cluster: typing.Union[_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster, _aws_cdk_aws_rds_ceddda9d.IDatabaseInstance, _aws_cdk_aws_dsql_ceddda9d.CfnCluster],
1924
+ function_props: typing.Optional[typing.Union[_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps, typing.Dict[builtins.str, typing.Any]]] = None,
1925
+ logger: typing.Optional[builtins.bool] = None,
1926
+ secret: typing.Optional[_aws_cdk_aws_secretsmanager_ceddda9d.ISecret] = None,
1927
+ ssl: typing.Optional[builtins.bool] = None,
1928
+ timeout: typing.Optional[_aws_cdk_ceddda9d.Duration] = None,
1929
+ vpc: typing.Optional[_aws_cdk_aws_ec2_ceddda9d.IVpc] = None,
1930
+ vpc_subnets: typing.Optional[typing.Union[_aws_cdk_aws_ec2_ceddda9d.SubnetSelection, typing.Dict[builtins.str, typing.Any]]] = None,
1931
+ ) -> None:
1932
+ """Type checking stubs"""
1933
+ pass
1934
+
1935
+ def _typecheckingstub__38638fb01c5b5c1e90a480e969bec755370ee72cad8844940b704cff73c8057c(
1936
+ *,
1937
+ engine: DatabaseEngine,
1938
+ cluster: typing.Optional[typing.Union[_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster, _aws_cdk_aws_rds_ceddda9d.IDatabaseInstance, _aws_cdk_aws_dsql_ceddda9d.CfnCluster]] = None,
1939
+ function_arn: typing.Optional[builtins.str] = None,
1940
+ function_name: typing.Optional[builtins.str] = None,
1941
+ ) -> None:
1942
+ """Type checking stubs"""
1943
+ pass
1944
+
1945
+ def _typecheckingstub__1562dfb28e0e71a0b95785ddbc26511738019b8ab5c6885e0ff1f2050e6d045b(
1946
+ *,
1947
+ cluster: typing.Union[_aws_cdk_aws_rds_ceddda9d.IDatabaseCluster, _aws_cdk_aws_rds_ceddda9d.IDatabaseInstance, _aws_cdk_aws_dsql_ceddda9d.CfnCluster],
1948
+ function_props: typing.Optional[typing.Union[_aws_cdk_aws_lambda_nodejs_ceddda9d.NodejsFunctionProps, typing.Dict[builtins.str, typing.Any]]] = None,
1949
+ logger: typing.Optional[builtins.bool] = None,
1950
+ secret: typing.Optional[_aws_cdk_aws_secretsmanager_ceddda9d.ISecret] = None,
1951
+ ssl: typing.Optional[builtins.bool] = None,
1952
+ timeout: typing.Optional[_aws_cdk_ceddda9d.Duration] = None,
1953
+ vpc: typing.Optional[_aws_cdk_aws_ec2_ceddda9d.IVpc] = None,
1954
+ vpc_subnets: typing.Optional[typing.Union[_aws_cdk_aws_ec2_ceddda9d.SubnetSelection, typing.Dict[builtins.str, typing.Any]]] = None,
1955
+ ) -> None:
1956
+ """Type checking stubs"""
1957
+ pass
1958
+
1959
+ def _typecheckingstub__062afab8717d46f6fc2a31188b28d9e663190b2080174cc7f1ddd691f699de7e(
1960
+ scope: _constructs_77d1e7e8.Construct,
1961
+ id: builtins.str,
1962
+ *,
1963
+ provider: IProvider,
1964
+ role_name: builtins.str,
1965
+ database: typing.Optional[IDatabase] = None,
1966
+ database_name: typing.Optional[builtins.str] = None,
1967
+ enable_iam_auth: typing.Optional[builtins.bool] = None,
1968
+ encryption_key: typing.Optional[_aws_cdk_aws_kms_ceddda9d.IKey] = None,
1969
+ parameter_prefix: typing.Optional[builtins.str] = None,
1970
+ secret_name: typing.Optional[builtins.str] = None,
1971
+ ) -> None:
1972
+ """Type checking stubs"""
1973
+ pass
1974
+
1975
+ def _typecheckingstub__a7ed79cdb7903207b3240698f6bcb0582905979c1519e2b49d66fa6fbdac11ee(
1976
+ *,
1977
+ provider: IProvider,
1978
+ role_name: builtins.str,
1979
+ database: typing.Optional[IDatabase] = None,
1980
+ database_name: typing.Optional[builtins.str] = None,
1981
+ enable_iam_auth: typing.Optional[builtins.bool] = None,
1982
+ encryption_key: typing.Optional[_aws_cdk_aws_kms_ceddda9d.IKey] = None,
1983
+ parameter_prefix: typing.Optional[builtins.str] = None,
1984
+ secret_name: typing.Optional[builtins.str] = None,
1985
+ ) -> None:
1986
+ """Type checking stubs"""
1987
+ pass
1988
+
1989
+ def _typecheckingstub__23264d20ca42f56453469fb6eae1679bf4f901ace3ccab77b186aa28167779bf(
1990
+ scope: _constructs_77d1e7e8.Construct,
1991
+ id: builtins.str,
1992
+ *,
1993
+ provider: IProvider,
1994
+ schema_name: builtins.str,
1995
+ database: typing.Optional[IDatabase] = None,
1996
+ role: typing.Optional[Role] = None,
1997
+ ) -> None:
1998
+ """Type checking stubs"""
1999
+ pass
2000
+
2001
+ def _typecheckingstub__3e5c9257731fa92bb3b0a3fd8f4556888ed99294fcba1b14ade48e8d8d57c6b0(
2002
+ *,
2003
+ provider: IProvider,
2004
+ schema_name: builtins.str,
2005
+ database: typing.Optional[IDatabase] = None,
2006
+ role: typing.Optional[Role] = None,
2007
+ ) -> None:
2008
+ """Type checking stubs"""
2009
+ pass
2010
+
2011
+ def _typecheckingstub__a34aa094d1e87a65ca4be0fe7c3fad7c2a9f986cfd40a3f07de15d3d6b0d2139(
2012
+ scope: _constructs_77d1e7e8.Construct,
2013
+ id: builtins.str,
2014
+ *,
2015
+ provider: IProvider,
2016
+ database: typing.Optional[IDatabase] = None,
2017
+ rollback: typing.Optional[builtins.str] = None,
2018
+ statement: typing.Optional[builtins.str] = None,
2019
+ ) -> None:
2020
+ """Type checking stubs"""
2021
+ pass
2022
+
2023
+ def _typecheckingstub__fee81de7736c28ed1e24db0db96a0f7084eb4dad448f37b2efdc59960daf7f24(
2024
+ *,
2025
+ provider: IProvider,
2026
+ database: typing.Optional[IDatabase] = None,
2027
+ rollback: typing.Optional[builtins.str] = None,
2028
+ statement: typing.Optional[builtins.str] = None,
2029
+ ) -> None:
2030
+ """Type checking stubs"""
2031
+ pass
2032
+
2033
+ def _typecheckingstub__9b0a129482abaf744a12ee5aabac9c0545bc3cdf8edcfb3dca83d0c1051326ed(
2034
+ scope: _constructs_77d1e7e8.Construct,
2035
+ id: builtins.str,
2036
+ *,
2037
+ database_name: builtins.str,
2038
+ provider: IProvider,
2039
+ owner: typing.Optional[Role] = None,
2040
+ ) -> None:
2041
+ """Type checking stubs"""
2042
+ pass
2043
+
2044
+ def _typecheckingstub__771fb1f62814ed88a15c2f9d4d948498f7416f30cd8e9d630b3ea09667333681(
2045
+ scope: _constructs_77d1e7e8.Construct,
2046
+ id: builtins.str,
2047
+ database_name: builtins.str,
2048
+ ) -> None:
2049
+ """Type checking stubs"""
2050
+ pass
2051
+
2052
+ for cls in [IDatabase, IProvider]:
2053
+ typing.cast(typing.Any, cls).__protocol_attrs__ = typing.cast(typing.Any, cls).__protocol_attrs__ - set(['__jsii_proxy_class__', '__jsii_type__'])