Skip to content

Commit 206bd29

Browse files
author
Marco Franceschi
committed
fix: Added missing connections to RDS DB Instance
1 parent 6480e7f commit 206bd29

9 files changed

Lines changed: 219 additions & 113 deletions

File tree

README.md

Lines changed: 94 additions & 94 deletions
Large diffs are not rendered by default.

src/services/cloudwatchLogs/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type awsCloudwatchLog @key(fields: "arn") {
1414
cloudwatch: [awsCloudwatch] @hasInverse(field: cloudwatchLog)
1515
cloudtrail: [awsCloudtrail] @hasInverse(field: cloudwatchLog)
1616
ecsCluster: [awsEcsCluster] @hasInverse(field: cloudwatchLog)
17+
rdsDbInstance: [awsRdsDbInstance] @hasInverse(field: cloudwatchLogs)
1718
}
1819

1920
type awsMetricFilter

src/services/iamRole/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ type awsIamRole implements awsBaseService @key(fields: "id") {
3333
cloudFormationStackSet: [awsCloudFormationStackSet]
3434
@hasInverse(field: iamRoles)
3535
asg: [awsAsg] @hasInverse(field: iamRole)
36+
rdsDbInstance: [awsRdsDbInstance] @hasInverse(field: iamRoles)
3637
}

src/services/rdsDbInstance/connections.ts

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import { SecurityGroup } from 'aws-sdk/clients/ec2'
44
import { DBInstance } from 'aws-sdk/clients/rds'
55
import { RawAwsSubnet } from '../subnet/data'
66
import services from '../../enums/services'
7+
import { RawAwsIamRole } from '../iamRole/data'
8+
import { globalRegionName } from '../../enums/regions'
9+
import { AwsKms } from '../kms/data'
10+
import { RawAwsLogGroup } from '../cloudwatchLogs/data'
11+
import { RawAwsRoute53HostedZone } from '../route53HostedZone/data'
12+
import { getHostedZoneId } from '../../utils/ids'
713

814
export default ({
915
service,
@@ -17,7 +23,19 @@ export default ({
1723
[property: string]: ServiceConnection[]
1824
} => {
1925
const connections: ServiceConnection[] = []
20-
const { DBInstanceArn: id, VpcSecurityGroups, DBSubnetGroup, KmsKeyId } = service
26+
const {
27+
DBInstanceArn: id,
28+
VpcSecurityGroups,
29+
DBSubnetGroup,
30+
MonitoringRoleArn: monitoringRoleArn,
31+
AssociatedRoles: associatedRoles = [],
32+
PerformanceInsightsKMSKeyId,
33+
KmsKeyId,
34+
ActivityStreamKmsKeyId,
35+
DomainMemberships,
36+
EnhancedMonitoringResourceArn,
37+
Endpoint,
38+
} = service
2139

2240
const sgIds = VpcSecurityGroups.map(
2341
({ VpcSecurityGroupId }) => VpcSecurityGroupId
@@ -73,13 +91,70 @@ export default ({
7391
}
7492
}
7593

94+
/**
95+
* Find Cloudwatch Logs
96+
*/
97+
const cloudwatchLogs = data.find(
98+
({ name }) => name === services.cloudwatchLog
99+
)
100+
if (cloudwatchLogs?.data?.[region]) {
101+
// Search the correspondent cloudwatch log group name for the rds logs
102+
// e.g. enhancedMonitoringArn arn:aws:logs:us-east-1::log-group:RDSOSMetrics:log-stream:db-databaseid
103+
// belongs to cloudwatchLogs group arn arn:aws:logs:us-east-1::log-group:RDSOSMetrics:*
104+
const cloudwatchLogsInRegion = cloudwatchLogs.data[region].filter(
105+
({ arn }: RawAwsLogGroup) =>
106+
arn &&
107+
EnhancedMonitoringResourceArn?.includes(
108+
arn.substring(0, arn.length - 1)
109+
)
110+
)
111+
if (!isEmpty(cloudwatchLogsInRegion)) {
112+
for (const cloudwatchLog of cloudwatchLogsInRegion) {
113+
connections.push({
114+
id: cloudwatchLog.logGroupName,
115+
resourceType: services.cloudwatchLog,
116+
relation: 'child',
117+
field: 'cloudwatchLogs',
118+
})
119+
}
120+
}
121+
}
122+
123+
/**
124+
* Find Route53 Hosted Zone
125+
*/
126+
const route53HostedZones = data.find(
127+
({ name }) => name === services.route53HostedZone
128+
)
129+
if (route53HostedZones?.data?.[globalRegionName]) {
130+
const route53HostedZonesInRegion = route53HostedZones.data[
131+
globalRegionName
132+
].filter(
133+
({ Id }: RawAwsRoute53HostedZone) =>
134+
Endpoint?.HostedZoneId && Id.includes(Endpoint.HostedZoneId)
135+
)
136+
if (!isEmpty(route53HostedZonesInRegion)) {
137+
for (const route53HostedZone of route53HostedZonesInRegion) {
138+
connections.push({
139+
id: getHostedZoneId(route53HostedZone.Id),
140+
resourceType: services.route53HostedZone,
141+
relation: 'child',
142+
field: 'route53HostedZone',
143+
})
144+
}
145+
}
146+
}
147+
76148
/**
77149
* Find KMS
78150
*/
79151
const kmsKeys = data.find(({ name }) => name === services.kms)
80152
if (kmsKeys?.data?.[region]) {
81153
const kmsKeyInRegion = kmsKeys.data[region].filter(
82-
kmsKey => kmsKey.Arn === KmsKeyId
154+
({ Arn }) =>
155+
Arn === KmsKeyId ||
156+
Arn === ActivityStreamKmsKeyId ||
157+
Arn === PerformanceInsightsKMSKeyId
83158
)
84159
if (!isEmpty(kmsKeyInRegion)) {
85160
for (const kms of kmsKeyInRegion) {
@@ -93,8 +168,38 @@ export default ({
93168
}
94169
}
95170

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+
const iamRolesInRegion: RawAwsIamRole[] = iamRoles.data[
182+
globalRegionName
183+
].filter(
184+
({ Arn, RoleName }: RawAwsIamRole) =>
185+
Arn === monitoringRoleArn ||
186+
associatedRoles.find(r => r.RoleArn === Arn) ||
187+
DomainMemberships.find(d => d.IAMRoleName === RoleName)
188+
)
189+
if (!isEmpty(iamRolesInRegion)) {
190+
for (const instance of iamRolesInRegion) {
191+
connections.push({
192+
id: instance.Arn,
193+
resourceType: services.iamRole,
194+
relation: 'child',
195+
field: 'iamRoles',
196+
})
197+
}
198+
}
199+
}
200+
96201
const rdsDbInstanceResult = {
97202
[id]: connections,
98203
}
99204
return rdsDbInstanceResult
100-
}
205+
}

src/services/rdsDbInstance/schema.graphql

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ type awsRdsDbInstance implements awsBaseService @key(fields: "arn") {
3535
securityGroups: [awsSecurityGroup] @hasInverse(field: rdsDbInstance)
3636
subnet: [awsSubnet] @hasInverse(field: rdsDbInstance)
3737
vpc: [awsVpc] @hasInverse(field: rdsDbInstance)
38+
cloudwatchLogs: [awsCloudwatchLog] @hasInverse(field: rdsDbInstance)
39+
route53HostedZone: [awsRoute53HostedZone] @hasInverse(field: rdsDbInstance)
40+
iamRoles: [awsIamRole] @hasInverse(field: rdsDbInstance)
3841
}
39-
40-
#TODO: add connection to route53HostedZone using hostedZoneId in Endpoint
41-
# TODO: add connection to kms using kmsKeyId AND PerformanceInsightsKMSKeyId AND ActivityStreamKmsKeyId
42-
# TODO: add connection to IAM role using DomainMembership AND MonitoringRoleArn AND AssociatedRoles
43-
# TODO: add connection to cloudwatchLog using EnhancedMonitoringResourceArn

src/services/route53HostedZone/data.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import awsLoggerText from '../../properties/logger'
1717
import { initTestEndpoint, setAwsRetryOptions } from '../../utils'
1818
import AwsErrorLog from '../../utils/errorLog'
1919
import { ROUTE_53_CUSTOM_DELAY } from '../../config/constants'
20+
import { globalRegionName } from '../../enums/regions'
2021

2122
const lt = { ...awsLoggerText }
2223
const { logger } = CloudGraph
@@ -128,7 +129,7 @@ export const getHostedZoneData = async (
128129
...data.HostedZone,
129130
DelegationSet: data.DelegationSet,
130131
VPCs: data.VPCs,
131-
region: 'global',
132+
region: globalRegionName,
132133
})
133134

134135
return resolveZone()

src/services/route53HostedZone/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ type awsRoute53HostedZone implements awsBaseService @key(fields: "arn") {
66
rdsCluster: [awsRdsCluster] @hasInverse(field: route53HostedZone)
77
route53Record: [awsRoute53Record] @hasInverse(field: route53HostedZone) #change to plural
88
vpc: [awsVpc] @hasInverse(field: route53HostedZone)
9+
rdsDbInstance: [awsRdsDbInstance] @hasInverse(field: route53HostedZone)
910
}

src/services/route53Record/data.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from '../route53HostedZone/data'
2222
import { ROUTE_53_CUSTOM_DELAY } from '../../config/constants'
2323
import services from '../../enums/services'
24+
import { globalRegionName } from '../../enums/regions'
2425

2526
const lt = { ...awsLoggerText }
2627
const { logger } = CloudGraph
@@ -115,7 +116,7 @@ const listRecordsForHostedZone = async ({
115116
* If there are not, then add the records to the zone's records
116117
*/
117118
for (const record of records) {
118-
recordData.push({ ...record, HostedZoneId, region: 'global' })
119+
recordData.push({ ...record, HostedZoneId, region: globalRegionName })
119120
}
120121

121122
/**

src/types/generated.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,7 @@ export type AwsCloudwatchLog = {
922922
kmsKeyId?: Maybe<Scalars['String']>;
923923
metricFilterCount?: Maybe<Scalars['Int']>;
924924
metricFilters?: Maybe<Array<Maybe<AwsMetricFilter>>>;
925+
rdsDbInstance?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
925926
region?: Maybe<Scalars['String']>;
926927
retentionInDays?: Maybe<Scalars['Int']>;
927928
storedBytes?: Maybe<Scalars['String']>;
@@ -3079,8 +3080,8 @@ export type AwsIamRole = AwsBaseService & {
30793080
maxSessionDuration?: Maybe<Scalars['Int']>;
30803081
name?: Maybe<Scalars['String']>;
30813082
path?: Maybe<Scalars['String']>;
3082-
rdsClusterIamRoles?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3083-
rdsClusterMonitoringRole?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3083+
rdsCluster?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3084+
rdsDbInstance?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
30843085
s3?: Maybe<Array<Maybe<AwsS3>>>;
30853086
sageMakerNotebookInstances?: Maybe<Array<Maybe<AwsSageMakerNotebookInstance>>>;
30863087
systemsManagerInstances?: Maybe<Array<Maybe<AwsSystemsManagerInstance>>>;
@@ -3213,10 +3214,7 @@ export type AwsKms = AwsBaseService & {
32133214
origin?: Maybe<Scalars['String']>;
32143215
policy?: Maybe<AwsIamJsonPolicy>;
32153216
rdsCluster?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3216-
rdsClusterActivityStream?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3217-
rdsClusterPerformanceInsights?: Maybe<Array<Maybe<AwsRdsCluster>>>;
32183217
rdsClusterSnapshots?: Maybe<Array<Maybe<AwsRdsClusterSnapshot>>>;
3219-
rdsClusterStorageEncryption?: Maybe<Array<Maybe<AwsRdsCluster>>>;
32203218
rdsDbInstance?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
32213219
redshiftCluster?: Maybe<Array<Maybe<AwsRedshiftCluster>>>;
32223220
sageMakerNotebookInstances?: Maybe<Array<Maybe<AwsSageMakerNotebookInstance>>>;
@@ -3505,7 +3503,6 @@ export type AwsRawTag = {
35053503
};
35063504

35073505
export type AwsRdsCluster = AwsBaseService & {
3508-
activityStreamKms?: Maybe<Array<Maybe<AwsKms>>>;
35093506
allocatedStorage?: Maybe<Scalars['Int']>;
35103507
appSync?: Maybe<Array<Maybe<AwsAppSync>>>;
35113508
backupRetentionPeriod?: Maybe<Scalars['Int']>;
@@ -3532,10 +3529,8 @@ export type AwsRdsCluster = AwsBaseService & {
35323529
instances?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
35333530
kms?: Maybe<Array<Maybe<AwsKms>>>;
35343531
kmsKey?: Maybe<Scalars['String']>;
3535-
monitoringIamRole?: Maybe<Array<Maybe<AwsIamRole>>>;
35363532
multiAZ?: Maybe<Scalars['Boolean']>;
35373533
percentProgress?: Maybe<Scalars['String']>;
3538-
performanceInsightsKms?: Maybe<Array<Maybe<AwsKms>>>;
35393534
port?: Maybe<Scalars['Int']>;
35403535
readerEndpoint?: Maybe<Scalars['String']>;
35413536
replicationSourceIdentifier?: Maybe<Scalars['String']>;
@@ -3544,7 +3539,6 @@ export type AwsRdsCluster = AwsBaseService & {
35443539
securityGroups?: Maybe<Array<Maybe<AwsSecurityGroup>>>;
35453540
snapshots?: Maybe<Array<Maybe<AwsRdsClusterSnapshot>>>;
35463541
status?: Maybe<Scalars['String']>;
3547-
storageEncryptedKms?: Maybe<Array<Maybe<AwsKms>>>;
35483542
subnets?: Maybe<Array<Maybe<AwsSubnet>>>;
35493543
tags?: Maybe<Array<Maybe<AwsRawTag>>>;
35503544
username?: Maybe<Scalars['String']>;
@@ -3591,6 +3585,7 @@ export type AwsRdsDbInstance = AwsBaseService & {
35913585
autoMinorVersionUpgrade?: Maybe<Scalars['Boolean']>;
35923586
availabilityZone?: Maybe<Scalars['String']>;
35933587
certificateAuthority?: Maybe<Scalars['String']>;
3588+
cloudwatchLogs?: Maybe<Array<Maybe<AwsCloudwatchLog>>>;
35943589
cluster?: Maybe<Array<Maybe<AwsRdsCluster>>>;
35953590
copyTagsToSnapshot?: Maybe<Scalars['Boolean']>;
35963591
createdTime?: Maybe<Scalars['String']>;
@@ -3602,6 +3597,7 @@ export type AwsRdsDbInstance = AwsBaseService & {
36023597
failoverPriority?: Maybe<Scalars['Int']>;
36033598
hostedZoneId?: Maybe<Scalars['String']>;
36043599
iamDbAuthenticationEnabled?: Maybe<Scalars['Boolean']>;
3600+
iamRoles?: Maybe<Array<Maybe<AwsIamRole>>>;
36053601
instanceClass?: Maybe<Scalars['String']>;
36063602
kms?: Maybe<Array<Maybe<AwsKms>>>;
36073603
kmsKey?: Maybe<Scalars['String']>;
@@ -3614,6 +3610,7 @@ export type AwsRdsDbInstance = AwsBaseService & {
36143610
port?: Maybe<Scalars['Int']>;
36153611
publiclyAccessible?: Maybe<Scalars['Boolean']>;
36163612
resourceId?: Maybe<Scalars['String']>;
3613+
route53HostedZone?: Maybe<Array<Maybe<AwsRoute53HostedZone>>>;
36173614
securityGroups?: Maybe<Array<Maybe<AwsSecurityGroup>>>;
36183615
status?: Maybe<Scalars['String']>;
36193616
storageType?: Maybe<Scalars['String']>;
@@ -3688,6 +3685,7 @@ export type AwsRoute53HostedZone = AwsBaseService & {
36883685
name?: Maybe<Scalars['String']>;
36893686
nameServers?: Maybe<Array<Maybe<Scalars['String']>>>;
36903687
rdsCluster?: Maybe<Array<Maybe<AwsRdsCluster>>>;
3688+
rdsDbInstance?: Maybe<Array<Maybe<AwsRdsDbInstance>>>;
36913689
route53Record?: Maybe<Array<Maybe<AwsRoute53Record>>>;
36923690
vpc?: Maybe<Array<Maybe<AwsVpc>>>;
36933691
};

0 commit comments

Comments
 (0)