Skip to content

Commit a4d4ed0

Browse files
authored
Merge pull request #22 from cloudgraphdev/fix/CG-1069
fix: Added kms and iam roles connections to rds cluster
2 parents 447b324 + ef38e33 commit a4d4ed0

7 files changed

Lines changed: 141 additions & 15 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,20 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
124124
| iamServerCertificate | |
125125
| iamUser | iamGroup |
126126
| iamPolicy | iamRole, iamGroup |
127-
| iamRole | appSync, codebuild, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, sageMakerNotebookInstance, systemsManagerInstance guardDutyDetector, lambda, kinesisFirehose |
127+
| iamRole | appSync, codebuild, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, sageMakerNotebookInstance, systemsManagerInstance guardDutyDetector, lambda, kinesisFirehose, rdsCluster |
128128
| iamGroup | iamUser, iamPolicy |
129129
| igw | vpc |
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, dmsReplicationInstance, redshiftCluster |
133+
| kms | cloudtrail, cloudwatchLog, codebuild, ecsCluster, efs, eksCluster, elastiCacheReplicationGroup, elasticSearchDomain, emrCluster, lambda, rdsClusterSnapshot, sns, sageMakerNotebookInstance, dmsReplicationInstance, redshiftCluster, rdsCluster |
134134
| lambda | appSync, cognitoUserPool, kms, securityGroup, subnet, vpc, iamRole |
135135
| managedAirflow | iamRole, securityGroups, subnet, s3 |
136136
| nacl | vpc |
137137
| natGateway | networkInterface, subnet, vpc |
138138
| networkInterface | ec2, eip, efsMountTarget, natGateway, sageMakerNotebookInstance, subnet, vpc, flowLog |
139139
| organization |
140-
| rdsCluster | appSync, rdsClusterSnapshot, rdsDbInstance, securityGroup |
140+
| rdsCluster | appSync, rdsClusterSnapshot, rdsDbInstance, securityGroup, iamRole, kms |
141141
| rdsClusterSnapshot | kms, rdsCluster, vpc |
142142
| rdsDbInstance | rdsCluster, securityGroup, vpc, subnet |
143143
| redshiftCluster | kms, vpc |

src/services/iamRole/schema.graphql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ type awsIamRole implements awsBaseService @key(fields: "id") {
2828
appSync: [awsAppSync] @hasInverse(field: iamRoles)
2929
lambda: [awsLambda] @hasInverse(field: iamRole)
3030
kinesisFirehose: [awsKinesisFirehose] @hasInverse(field: iamRole)
31+
rdsClusterMonitoringRole: [awsRdsCluster]
32+
@hasInverse(field: monitoringIamRole)
33+
rdsClusterIamRoles: [awsRdsCluster] @hasInverse(field: iamRoles)
3134
}

src/services/kms/schema.graphql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,10 @@ type awsKms implements awsBaseService @key(fields: "id") {
3131
ecsCluster: [awsEcsCluster] @hasInverse(field: kms)
3232
dynamodb: [awsDynamoDbTable] @hasInverse(field: kms)
3333
cognitoUserPools: [awsCognitoUserPool] @hasInverse(field: kms)
34+
rdsClusterStorageEncryption: [awsRdsCluster]
35+
@hasInverse(field: storageEncryptedKms)
36+
rdsClusterActivityStream: [awsRdsCluster]
37+
@hasInverse(field: activityStreamKms)
38+
rdsClusterPerformanceInsights: [awsRdsCluster]
39+
@hasInverse(field: performanceInsightsKms)
3440
}

src/services/rdsCluster/connections.ts

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { DBInstance, DBCluster } from 'aws-sdk/clients/rds'
55

66
import services from '../../enums/services'
77
import { RawAwsRdsClusterSnapshot } from '../rdsClusterSnapshot/data'
8+
import { RawAwsIamRole } from '../iamRole/data'
9+
import { AwsKms } from '../kms/data'
10+
import { globalRegionName } from '../../enums/regions'
811

912
export default ({
1013
service,
@@ -21,6 +24,11 @@ export default ({
2124
const {
2225
DBClusterArn: id,
2326
DBClusterIdentifier: clusterId,
27+
MonitoringRoleArn: monitoringRoleArn,
28+
AssociatedRoles: associatedRoles = [],
29+
KmsKeyId,
30+
ActivityStreamKmsKeyId,
31+
PerformanceInsightsKMSKeyId,
2432
VpcSecurityGroups,
2533
} = service
2634
const sgIds = VpcSecurityGroups.map(
@@ -55,14 +63,17 @@ export default ({
5563
/**
5664
* Find cluster snapshots
5765
*/
58-
const snapshots: {
66+
const snapshots: {
5967
name: string
6068
data: { [property: string]: RawAwsRdsClusterSnapshot[] }
6169
} = data.find(({ name }) => name === services.rdsClusterSnapshot)
6270

6371
if (snapshots?.data?.[region]) {
64-
const dataInRegion: RawAwsRdsClusterSnapshot[] = snapshots.data[region].filter(
65-
({ DBClusterIdentifier }: RawAwsRdsClusterSnapshot) => DBClusterIdentifier === clusterId
72+
const dataInRegion: RawAwsRdsClusterSnapshot[] = snapshots.data[
73+
region
74+
].filter(
75+
({ DBClusterIdentifier }: RawAwsRdsClusterSnapshot) =>
76+
DBClusterIdentifier === clusterId
6677
)
6778
if (!isEmpty(dataInRegion)) {
6879
for (const snapshot of dataInRegion) {
@@ -101,6 +112,102 @@ export default ({
101112
}
102113
}
103114

115+
/**
116+
* Find KMS
117+
* related to this RDS Cluster
118+
*/
119+
const kms: {
120+
name: string
121+
data: { [property: string]: AwsKms[] }
122+
} = data.find(({ name }) => name === services.kms)
123+
124+
if (kms?.data?.[region]) {
125+
// set storage encryption kms key
126+
let kmsInRegion: AwsKms[] = kms.data[region].filter(
127+
({ Arn }: AwsKms) => Arn === KmsKeyId
128+
)
129+
if (!isEmpty(kmsInRegion)) {
130+
for (const instance of kmsInRegion) {
131+
connections.push({
132+
id: instance.KeyId,
133+
resourceType: services.kms,
134+
relation: 'child',
135+
field: 'storageEncryptedKms',
136+
})
137+
}
138+
}
139+
140+
// set activity stream kms key
141+
kmsInRegion = kms.data[region].filter(
142+
({ Arn }: AwsKms) => Arn === ActivityStreamKmsKeyId
143+
)
144+
if (!isEmpty(kmsInRegion)) {
145+
for (const instance of kmsInRegion) {
146+
connections.push({
147+
id: instance.KeyId,
148+
resourceType: services.kms,
149+
relation: 'child',
150+
field: 'activityStreamKms',
151+
})
152+
}
153+
}
154+
155+
// set performance insights kms key
156+
kmsInRegion = kms.data[region].filter(
157+
({ Arn }: AwsKms) => Arn === PerformanceInsightsKMSKeyId
158+
)
159+
if (!isEmpty(kmsInRegion)) {
160+
for (const instance of kmsInRegion) {
161+
connections.push({
162+
id: instance.KeyId,
163+
resourceType: services.kms,
164+
relation: 'child',
165+
field: 'performanceInsightsKms',
166+
})
167+
}
168+
}
169+
}
170+
171+
/**
172+
* Find IAM Role
173+
* related to this RDS Cluster
174+
*/
175+
const iamRoles: {
176+
name: string
177+
data: { [property: string]: RawAwsIamRole[] }
178+
} = data.find(({ name }) => name === services.iamRole)
179+
180+
if (iamRoles?.data?.[globalRegionName]) {
181+
let iamRolesInRegion: RawAwsIamRole[] = iamRoles.data[
182+
globalRegionName
183+
].filter(({ Arn }: RawAwsIamRole) =>
184+
associatedRoles.find(r => r.RoleArn === Arn)
185+
)
186+
if (!isEmpty(iamRolesInRegion)) {
187+
for (const instance of iamRolesInRegion) {
188+
connections.push({
189+
id: instance.Arn,
190+
resourceType: services.iamRole,
191+
relation: 'child',
192+
field: 'iamRoles',
193+
})
194+
}
195+
}
196+
iamRolesInRegion = iamRoles.data[globalRegionName].filter(
197+
({ Arn }: RawAwsIamRole) => Arn === monitoringRoleArn
198+
)
199+
if (!isEmpty(iamRolesInRegion)) {
200+
for (const instance of iamRolesInRegion) {
201+
connections.push({
202+
id: instance.Arn,
203+
resourceType: services.iamRole,
204+
relation: 'child',
205+
field: 'monitoringIamRole',
206+
})
207+
}
208+
}
209+
}
210+
104211
const rdsClusterResult = {
105212
[id]: connections,
106213
}

src/services/rdsCluster/format.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { RawAwsRdsCluster } from './data'
2-
import {
3-
AwsRdsCluster,
4-
} from '../../types/generated'
2+
import { AwsRdsCluster } from '../../types/generated'
53
import { formatTagsFromMap } from '../../utils/format'
64

75
export default ({
86
service,
97
account,
10-
region
11-
}:
12-
{
8+
region,
9+
}: {
1310
service: RawAwsRdsCluster
1411
account: string
1512
region: string

src/services/rdsCluster/schema.graphql

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ type awsRdsCluster implements awsBaseService @key(fields: "arn") {
3333
snapshots: [awsRdsClusterSnapshot] @hasInverse(field: cluster)
3434
securityGroups: [awsSecurityGroup] @hasInverse(field: rdsCluster)
3535
appSync: [awsAppSync] @hasInverse(field: rdsCluster)
36+
monitoringIamRole: [awsIamRole] @hasInverse(field: rdsClusterMonitoringRole)
37+
iamRoles: [awsIamRole] @hasInverse(field: rdsClusterIamRoles)
38+
storageEncryptedKms: [awsKms] @hasInverse(field: rdsClusterStorageEncryption)
39+
activityStreamKms: [awsKms] @hasInverse(field: rdsClusterActivityStream)
40+
performanceInsightsKms: [awsKms]
41+
@hasInverse(field: rdsClusterPerformanceInsights)
3642
}
37-
38-
# TODO: create connection to iam roles using AssociatedRoles property AND DomainMemberships AND MonitoringRole
39-
# TODO: create connection to kms using all kms related fields

src/types/generated.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,6 +3070,8 @@ export type AwsIamRole = AwsBaseService & {
30703070
maxSessionDuration?: Maybe<Scalars['Int']>;
30713071
name?: Maybe<Scalars['String']>;
30723072
path?: Maybe<Scalars['String']>;
3073+
rdsClusterIamRoles?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3074+
rdsClusterMonitoringRole?: Maybe<Array<Maybe<AwsRdsCluster>>>;
30733075
sageMakerNotebookInstances?: Maybe<Array<Maybe<AwsSageMakerNotebookInstance>>>;
30743076
systemsManagerInstances?: Maybe<Array<Maybe<AwsSystemsManagerInstance>>>;
30753077
tags?: Maybe<Array<Maybe<AwsRawTag>>>;
@@ -3199,7 +3201,10 @@ export type AwsKms = AwsBaseService & {
31993201
lambda?: Maybe<Array<Maybe<AwsLambda>>>;
32003202
origin?: Maybe<Scalars['String']>;
32013203
policy?: Maybe<AwsIamJsonPolicy>;
3204+
rdsClusterActivityStream?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3205+
rdsClusterPerformanceInsights?: Maybe<Array<Maybe<AwsRdsCluster>>>;
32023206
rdsClusterSnapshots?: Maybe<Array<Maybe<AwsRdsClusterSnapshot>>>;
3207+
rdsClusterStorageEncryption?: Maybe<Array<Maybe<AwsRdsCluster>>>;
32033208
redshiftCluster?: Maybe<Array<Maybe<AwsRedshiftCluster>>>;
32043209
sageMakerNotebookInstances?: Maybe<Array<Maybe<AwsSageMakerNotebookInstance>>>;
32053210
sns?: Maybe<Array<Maybe<AwsSns>>>;
@@ -3473,6 +3478,7 @@ export type AwsRawTag = {
34733478
};
34743479

34753480
export type AwsRdsCluster = AwsBaseService & {
3481+
activityStreamKms?: Maybe<Array<Maybe<AwsKms>>>;
34763482
allocatedStorage?: Maybe<Scalars['Int']>;
34773483
appSync?: Maybe<Array<Maybe<AwsAppSync>>>;
34783484
backupRetentionPeriod?: Maybe<Scalars['Int']>;
@@ -3493,17 +3499,21 @@ export type AwsRdsCluster = AwsBaseService & {
34933499
hostedZoneId?: Maybe<Scalars['String']>;
34943500
httpEndpointEnabled?: Maybe<Scalars['Boolean']>;
34953501
iamDbAuthenticationEnabled?: Maybe<Scalars['Boolean']>;
3502+
iamRoles?: Maybe<Array<Maybe<AwsIamRole>>>;
34963503
instances?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
34973504
kmsKey?: Maybe<Scalars['String']>;
3505+
monitoringIamRole?: Maybe<Array<Maybe<AwsIamRole>>>;
34983506
multiAZ?: Maybe<Scalars['Boolean']>;
34993507
percentProgress?: Maybe<Scalars['String']>;
3508+
performanceInsightsKms?: Maybe<Array<Maybe<AwsKms>>>;
35003509
port?: Maybe<Scalars['Int']>;
35013510
readerEndpoint?: Maybe<Scalars['String']>;
35023511
replicationSourceIdentifier?: Maybe<Scalars['String']>;
35033512
resourceId?: Maybe<Scalars['String']>;
35043513
securityGroups?: Maybe<Array<Maybe<AwsSecurityGroup>>>;
35053514
snapshots?: Maybe<Array<Maybe<AwsRdsClusterSnapshot>>>;
35063515
status?: Maybe<Scalars['String']>;
3516+
storageEncryptedKms?: Maybe<Array<Maybe<AwsKms>>>;
35073517
subnets?: Maybe<Scalars['String']>;
35083518
tags?: Maybe<Array<Maybe<AwsRawTag>>>;
35093519
username?: Maybe<Scalars['String']>;

0 commit comments

Comments
 (0)