Skip to content

Commit f501a4e

Browse files
Christopher BrandtMarco Franceschi
authored andcommitted
feat(rds): add kms connection cluster/dbInstance
1 parent 7706a02 commit f501a4e

8 files changed

Lines changed: 76 additions & 5 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
130130
| iot | |
131131
| kinesisFirehose | kinesisStream, s3, iamRole |
132132
| kinesisStream | kinesisFirehose |
133-
| kms | cloudtrail, cloudwatchLog, codebuild, ecsCluster, efs, eksCluster, elastiCacheReplicationGroup, elasticSearchDomain, emrCluster, lambda, rdsClusterSnapshot, sns, sageMakerNotebookInstance, secretsManager, dmsReplicationInstance, redshiftCluster, rdsCluster |
133+
| kms | cloudtrail, cloudwatchLog, codebuild, ecsCluster, efs, eksCluster, elastiCacheReplicationGroup, elasticSearchDomain, emrCluster, lambda, rdsCluster, rdsClusterSnapshot, rdsDbInstance, sns, sageMakerNotebookInstance, secretsManager, dmsReplicationInstance, redshiftCluster |
134134
| lambda | appSync, cognitoUserPool, kms, s3, secretsManager, securityGroup, subnet, vpc, iamRole |
135135
| managedAirflow | iamRole, securityGroups, subnet, s3 |
136136
| nacl | vpc |
@@ -139,7 +139,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
139139
| organization |
140140
| rdsCluster | appSync, rdsClusterSnapshot, rdsDbInstance, securityGroup, subnet, iamRole, kms |
141141
| rdsClusterSnapshot | kms, rdsCluster, vpc |
142-
| rdsDbInstance | rdsCluster, securityGroup, vpc, subnet |
142+
| rdsDbInstance | kms, rdsCluster, securityGroup, vpc, subnet |
143143
| redshiftCluster | kms, vpc |
144144
| route53Record | alb, apiGatewayRestApi, elb, route53HostedZone |
145145
| route53HostedZone | route53Record, vpc |

src/services/kms/schema.graphql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ type awsKms implements awsBaseService @key(fields: "id") {
5353
@hasInverse(field: activityStreamKms)
5454
rdsClusterPerformanceInsights: [awsRdsCluster]
5555
@hasInverse(field: performanceInsightsKms)
56+
rdsCluster: [awsRdsCluster] @hasInverse(field: kms)
57+
rdsDbInstance: [awsRdsDbInstance] @hasInverse(field: kms)
5658
}

src/services/rdsCluster/connections.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,33 @@ export default ({
211211
}
212212
}
213213

214+
/**
215+
* Find KMS
216+
*/
217+
const kmsKeys = data.find(({ name }) => name === services.kms)
218+
if (kmsKeys?.data?.[region]) {
219+
const kmsKeyInRegion = kmsKeys.data[region].filter(
220+
kmsKey => kmsKey.Arn === KmsKeyId
221+
)
222+
if (!isEmpty(kmsKeyInRegion)) {
223+
for (const kms of kmsKeyInRegion) {
224+
connections.push({
225+
id: kms.KeyId,
226+
resourceType: services.kms,
227+
relation: 'child',
228+
field: 'kms',
229+
})
230+
}
231+
}
232+
}
233+
214234
/**
215235
* Find Subnets
216236
* related to this RDS Cluster
217237
*/
218238
const subnets = data.find(({ name }) => name === services.subnet)
219-
const subnetIds = dbSubnetGroups?.map(
220-
({ Subnets }) => Subnets?.map(subnet => subnet.SubnetIdentifier)
239+
const subnetIds = dbSubnetGroups?.map(({ Subnets }) =>
240+
Subnets?.map(subnet => subnet.SubnetIdentifier)
221241
)
222242
if (subnets?.data?.[region]) {
223243
const subnetsInRegion = subnets.data[region].filter(

src/services/rdsCluster/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type awsRdsCluster implements awsBaseService @key(fields: "arn") {
3535
securityGroups: [awsSecurityGroup] @hasInverse(field: rdsCluster)
3636
subnets: [awsSubnet] @hasInverse(field: rdsCluster)
3737
appSync: [awsAppSync] @hasInverse(field: rdsCluster)
38+
kms: [awsKms] @hasInverse(field: rdsCluster)
3839
monitoringIamRole: [awsIamRole] @hasInverse(field: rdsClusterMonitoringRole)
3940
iamRoles: [awsIamRole] @hasInverse(field: rdsClusterIamRoles)
4041
storageEncryptedKms: [awsKms] @hasInverse(field: rdsClusterStorageEncryption)

src/services/rdsDbInstance/connections.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default ({
1717
[property: string]: ServiceConnection[]
1818
} => {
1919
const connections: ServiceConnection[] = []
20-
const { DBInstanceArn: id, VpcSecurityGroups, DBSubnetGroup } = service
20+
const { DBInstanceArn: id, VpcSecurityGroups, DBSubnetGroup, KmsKeyId } = service
2121

2222
const sgIds = VpcSecurityGroups.map(
2323
({ VpcSecurityGroupId }) => VpcSecurityGroupId
@@ -73,6 +73,26 @@ export default ({
7373
}
7474
}
7575

76+
/**
77+
* Find KMS
78+
*/
79+
const kmsKeys = data.find(({ name }) => name === services.kms)
80+
if (kmsKeys?.data?.[region]) {
81+
const kmsKeyInRegion = kmsKeys.data[region].filter(
82+
kmsKey => kmsKey.Arn === KmsKeyId
83+
)
84+
if (!isEmpty(kmsKeyInRegion)) {
85+
for (const kms of kmsKeyInRegion) {
86+
connections.push({
87+
id: kms.KeyId,
88+
resourceType: services.kms,
89+
relation: 'child',
90+
field: 'kms',
91+
})
92+
}
93+
}
94+
}
95+
7696
const rdsDbInstanceResult = {
7797
[id]: connections,
7898
}

src/services/rdsDbInstance/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type awsRdsDbInstance implements awsBaseService @key(fields: "arn") {
3131
licenseModel: String @search(by: [hash, regexp])
3232
tags: [awsRawTag]
3333
cluster: [awsRdsCluster] @hasInverse(field: instances)
34+
kms: [awsKms] @hasInverse(field: rdsDbInstance)
3435
securityGroups: [awsSecurityGroup] @hasInverse(field: rdsDbInstance)
3536
subnet: [awsSubnet] @hasInverse(field: rdsDbInstance)
3637
vpc: [awsVpc] @hasInverse(field: rdsDbInstance)

src/types/generated.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3212,10 +3212,12 @@ export type AwsKms = AwsBaseService & {
32123212
lambda?: Maybe<Array<Maybe<AwsLambda>>>;
32133213
origin?: Maybe<Scalars['String']>;
32143214
policy?: Maybe<AwsIamJsonPolicy>;
3215+
rdsCluster?: Maybe<Array<Maybe<AwsRdsCluster>>>;
32153216
rdsClusterActivityStream?: Maybe<Array<Maybe<AwsRdsCluster>>>;
32163217
rdsClusterPerformanceInsights?: Maybe<Array<Maybe<AwsRdsCluster>>>;
32173218
rdsClusterSnapshots?: Maybe<Array<Maybe<AwsRdsClusterSnapshot>>>;
32183219
rdsClusterStorageEncryption?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3220+
rdsDbInstance?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
32193221
redshiftCluster?: Maybe<Array<Maybe<AwsRedshiftCluster>>>;
32203222
sageMakerNotebookInstances?: Maybe<Array<Maybe<AwsSageMakerNotebookInstance>>>;
32213223
secretsManager?: Maybe<Array<Maybe<AwsSecretsManager>>>;
@@ -3528,6 +3530,7 @@ export type AwsRdsCluster = AwsBaseService & {
35283530
iamDbAuthenticationEnabled?: Maybe<Scalars['Boolean']>;
35293531
iamRoles?: Maybe<Array<Maybe<AwsIamRole>>>;
35303532
instances?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
3533+
kms?: Maybe<Array<Maybe<AwsKms>>>;
35313534
kmsKey?: Maybe<Scalars['String']>;
35323535
monitoringIamRole?: Maybe<Array<Maybe<AwsIamRole>>>;
35333536
multiAZ?: Maybe<Scalars['Boolean']>;
@@ -3599,6 +3602,7 @@ export type AwsRdsDbInstance = AwsBaseService & {
35993602
hostedZoneId?: Maybe<Scalars['String']>;
36003603
iamDbAuthenticationEnabled?: Maybe<Scalars['Boolean']>;
36013604
instanceClass?: Maybe<Scalars['String']>;
3605+
kms?: Maybe<Array<Maybe<AwsKms>>>;
36023606
kmsKey?: Maybe<Scalars['String']>;
36033607
licenseModel?: Maybe<Scalars['String']>;
36043608
multiAZ?: Maybe<Scalars['Boolean']>;

tests/aws_rdsDBInstance.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { account, credentials, region } from '../src/properties/test'
55
import services from '../src/enums/services'
66
import Subnet from '../src/services/subnet'
77
import SecurityGroup from '../src/services/securityGroup'
8+
import KMS from '../src/services/kms'
89

910
// TODO: Localstack Pro Tier
1011
describe.skip('RDS DB Instance Service Test: ', () => {
@@ -19,6 +20,7 @@ describe.skip('RDS DB Instance Service Test: ', () => {
1920
try {
2021
const subnetService = new Subnet({ logger: CloudGraph.logger })
2122
const sgService = new SecurityGroup({ logger: CloudGraph.logger })
23+
const kmsService = new KMS({ logger: CloudGraph.logger })
2224
const classInstance = new RDSDbInstance({
2325
logger: CloudGraph.logger,
2426
})
@@ -43,6 +45,12 @@ describe.skip('RDS DB Instance Service Test: ', () => {
4345
regions: region,
4446
})
4547

48+
// Get kms data
49+
const kmsData = await kmsService.getData({
50+
credentials,
51+
regions: region,
52+
})
53+
4654
const [cluster] = getDataResult[region]
4755
rdsDbInstanceId = cluster.DBInstanceArn
4856

@@ -61,6 +69,12 @@ describe.skip('RDS DB Instance Service Test: ', () => {
6169
account,
6270
region,
6371
},
72+
{
73+
name: services.kms,
74+
data: kmsData,
75+
account,
76+
region,
77+
},
6478
],
6579
region,
6680
account,
@@ -189,5 +203,14 @@ describe.skip('RDS DB Instance Service Test: ', () => {
189203
expect(sgConnections).toBeDefined()
190204
expect(sgConnections.length).toBe(1)
191205
})
206+
207+
test('should verify the connection to kms', () => {
208+
const kmsConnections = rdsDbInstanceConnections[rdsDbInstanceId]?.filter(
209+
connection => connection.resourceType === services.kms
210+
)
211+
212+
expect(kmsConnections).toBeDefined()
213+
expect(kmsConnections.length).toBe(1)
214+
})
192215
})
193216
})

0 commit comments

Comments
 (0)