Skip to content

Commit 21c9199

Browse files
authored
Merge pull request #17 from cloudgraphdev/feature/CG-1060
Feature/cg 1060
2 parents e687b56 + eb2b6f7 commit 21c9199

File tree

9 files changed

+311
-31
lines changed

9 files changed

+311
-31
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
8787
| cognitoUserPool | appSync, lambda |
8888
| configurationRecorder | iamRole |
8989
| customerGateway | vpnConnection |
90-
| dynamodb | appSync |
90+
| dynamodb | appSync, iamRole, kms |
9191
| dmsReplicationInstance | securityGroup, subnet, vpc, kms |
9292
| ebs | asg, ec2, emrInstance |
9393
| ec2 | alb, asg, ebs, eip, emrInstance, eksCluster, elasticBeanstalkEnv, iamInstanceProfile, iamRole, networkInterface, securityGroup, subnet, systemsManagerInstance, vpc, ecsContainer |
@@ -128,7 +128,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
128128
| iot | |
129129
| kinesisFirehose | kinesisStream, s3 |
130130
| kinesisStream | kinesisFirehose |
131-
| kms | cloudtrail, cloudwatchLog, codebuild, efs, eksCluster, elastiCacheReplicationGroup, elasticSearchDomain, emrCluster, lambda, rdsClusterSnapshot, sns, sageMakerNotebookInstance, dmsReplicationInstance, redshiftCluster |
131+
| kms | cloudtrail, cloudwatchLog, codebuild, dynamodb, efs, eksCluster, elastiCacheReplicationGroup, elasticSearchDomain, emrCluster, lambda, rdsClusterSnapshot, sns, sageMakerNotebookInstance, dmsReplicationInstance, redshiftCluster |
132132
| lambda | appSync, cognitoUserPool, kms, securityGroup, subnet, vpc |
133133
| managedAirflow | iamRole, securityGroups, subnet, s3 |
134134
| nacl | vpc |
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { ServiceConnection } from '@cloudgraph/sdk'
2+
import { isEmpty } from 'lodash'
3+
import services from '../../enums/services'
4+
import { RawAwsDynamoDbTable } from './data'
5+
import { AwsKms } from '../kms/data'
6+
import { RawAwsIamRole } from '../iamRole/data'
7+
import { globalRegionName } from '../../enums/regions'
8+
9+
/**
10+
* Dynamo DB
11+
*/
12+
13+
export default ({
14+
service: dynamoDbTable,
15+
data,
16+
region,
17+
}: {
18+
account: string
19+
data: { name: string; data: { [property: string]: any[] } }[]
20+
service: RawAwsDynamoDbTable
21+
region: string
22+
}): { [key: string]: ServiceConnection[] } => {
23+
const connections: ServiceConnection[] = []
24+
25+
const {
26+
TableId: id,
27+
SSEDescription: sseDescription,
28+
Replicas: replicas,
29+
} = dynamoDbTable
30+
31+
/**
32+
* Find KMS
33+
* related to this dynamo db table
34+
*/
35+
const kmsMasterKeyArn = sseDescription?.KMSMasterKeyArn
36+
const kms = data.find(({ name }) => name === services.kms)
37+
38+
if (kmsMasterKeyArn && kms?.data?.[region]) {
39+
const kmsInRegion: AwsKms = kms.data[region].find(
40+
({ Arn }: AwsKms) => kmsMasterKeyArn === Arn
41+
)
42+
43+
if (kmsInRegion) {
44+
connections.push({
45+
id: kmsInRegion.KeyId,
46+
resourceType: services.kms,
47+
relation: 'child',
48+
field: 'kms',
49+
})
50+
}
51+
}
52+
53+
/**
54+
* Find IAM Roles
55+
* related to this dynamo db table
56+
*/
57+
const roleArns: string[] = []
58+
replicas?.map(({ AutoScaling: autoScaling }) => {
59+
roleArns.push(
60+
autoScaling?.ReplicaProvisionedReadCapacityAutoScalingSettings
61+
?.AutoScalingRoleArn
62+
)
63+
roleArns.push(
64+
autoScaling?.ReplicaProvisionedWriteCapacityAutoScalingSettings
65+
?.AutoScalingRoleArn
66+
)
67+
})
68+
69+
const roles: { name: string; data: { [property: string]: any[] } } =
70+
data.find(({ name }) => name === services.iamRole)
71+
if (roles?.data?.[globalRegionName]) {
72+
const dataAtRegion: RawAwsIamRole[] = roles.data[globalRegionName].filter(
73+
({ Arn }: RawAwsIamRole) => roleArns?.includes(Arn)
74+
)
75+
if (!isEmpty(dataAtRegion)) {
76+
for (const iamRole of dataAtRegion) {
77+
const { Arn: arn }: RawAwsIamRole = iamRole
78+
79+
connections.push({
80+
id: arn,
81+
resourceType: services.iamRole,
82+
relation: 'child',
83+
field: 'iamRoles',
84+
})
85+
}
86+
}
87+
}
88+
89+
const dynamoDbResult = {
90+
[id]: connections,
91+
}
92+
return dynamoDbResult
93+
}

src/services/dynamodb/data.ts

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ import DynamoDB, {
1313
TableNameList,
1414
ListTablesInput,
1515
ContinuousBackupsDescription,
16+
DescribeTableReplicaAutoScalingOutput,
17+
TableAutoScalingDescription,
18+
ReplicaAutoScalingDescription,
19+
ReplicaDescription,
1620
} from 'aws-sdk/clients/dynamodb'
1721
import { Config } from 'aws-sdk/lib/config'
1822
import { AWSError } from 'aws-sdk/lib/error'
@@ -31,11 +35,17 @@ const serviceName = 'DynamoDB'
3135
const errorLog = new AwsErrorLog(serviceName)
3236
const endpoint = initTestEndpoint(serviceName)
3337

34-
export interface RawAwsDynamoDbTable extends TableDescription {
38+
export interface RawAwsReplicaDescription extends ReplicaDescription {
39+
AutoScaling?: ReplicaAutoScalingDescription
40+
}
41+
42+
export interface RawAwsDynamoDbTable
43+
extends Omit<TableDescription, 'Replicas'> {
3544
region: string
3645
ttlEnabled?: boolean
3746
pointInTimeRecoveryEnabled?: boolean
3847
Tags?: TagMap
48+
Replicas?: RawAwsReplicaDescription[]
3949
}
4050

4151
const checkIfEnabled = (status: string): boolean =>
@@ -220,6 +230,30 @@ const getTableBackupsDescription = async (
220230
)
221231
})
222232

233+
const getTableReplicaAutoScaling = async (
234+
dynamoDb: DynamoDB,
235+
tableName: TableName
236+
): Promise<TableAutoScalingDescription> =>
237+
new Promise(resolve => {
238+
dynamoDb.describeTableReplicaAutoScaling(
239+
{
240+
TableName: tableName,
241+
},
242+
(err: AWSError, data: DescribeTableReplicaAutoScalingOutput) => {
243+
if (err) {
244+
errorLog.generateAwsErrorLog({
245+
functionName: 'dynamodb:describeTableReplicaAutoScaling',
246+
err,
247+
})
248+
}
249+
if (!isEmpty(data)) {
250+
resolve(data.TableAutoScalingDescription)
251+
}
252+
resolve({})
253+
}
254+
)
255+
})
256+
223257
export default async ({
224258
regions,
225259
config,
@@ -235,6 +269,7 @@ export default async ({
235269
const tagsPromises = []
236270
const ttlInfoPromises = []
237271
const backupInfoPromises = []
272+
const tableReplicaAutoScalingPromises = []
238273

239274
// First we get all table name for all regions
240275
regions.split(',').map(region => {
@@ -306,7 +341,7 @@ export default async ({
306341
logger.debug(lt.gettingTableTtlInfo)
307342
await Promise.all(ttlInfoPromises)
308343

309-
// Finally we get the backup information for each table
344+
// Get the backup information for each table
310345
tableData.map(({ TableName, region }, idx) => {
311346
const dynamoDb = new DynamoDB({ ...config, region, endpoint })
312347
const backupInfoPromise = new Promise<void>(async resolveBackupInfo => {
@@ -320,6 +355,36 @@ export default async ({
320355
})
321356
logger.debug(lt.gettingTableBackupInfo)
322357
await Promise.all(backupInfoPromises)
358+
359+
// Finally we get the auto scaling settings for each table
360+
tableData.map(({ TableName: tableName, region }, idx) => {
361+
const dynamoDb = new DynamoDB({ ...config, region, endpoint })
362+
const tableReplicaAutoScalingPromise = new Promise<void>(
363+
async resolveTableReplicaAutoScaling => {
364+
const globalSettings: TableAutoScalingDescription =
365+
await getTableReplicaAutoScaling(dynamoDb, tableName)
366+
tableData[idx].Replicas = tableData[idx].Replicas?.map(
367+
({ RegionName: regionName, ...rest }) => {
368+
const autoScaling: ReplicaAutoScalingDescription =
369+
globalSettings?.Replicas?.find(
370+
r => r.RegionName === regionName
371+
) || {}
372+
return {
373+
AutoScaling: autoScaling,
374+
RegionName: regionName,
375+
...rest,
376+
}
377+
}
378+
)
379+
resolveTableReplicaAutoScaling()
380+
}
381+
)
382+
tableReplicaAutoScalingPromises.push(tableReplicaAutoScalingPromise)
383+
})
384+
385+
logger.debug(lt.gettingTableBackupInfo)
386+
await Promise.all(tableReplicaAutoScalingPromises)
387+
323388
errorLog.reset()
324389

325390
resolve(groupBy(tableData, 'region'))

0 commit comments

Comments
 (0)