Skip to content

Commit fdc1342

Browse files
author
Marco Franceschi
committed
feat: Added rdsGlobalClusters
1 parent 1377e9a commit fdc1342

9 files changed

Lines changed: 246 additions & 0 deletions

File tree

src/enums/serviceMap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import NATGateway from '../services/natGateway'
5151
import NetworkAcl from '../services/nacl'
5252
import NetworkInterface from '../services/networkInterface'
5353
import RDSCluster from '../services/rdsCluster'
54+
import RDSGlobalCluster from '../services/rdsGlobalCluster '
5455
import RDSDbInstance from '../services/rdsDbInstance'
5556
import RDSEventSubscription from '../services/rdsEventSubscription'
5657
import RdsDbProxies from '../services/rdsDbProxies'
@@ -185,6 +186,7 @@ export default {
185186
[services.vpcPeeringConnection]: VpcPeeringConnection,
186187
[services.sqs]: SQS,
187188
[services.rdsCluster]: RDSCluster,
189+
[services.rdsGlobalCluster]: RDSGlobalCluster,
188190
[services.rdsClusterSnapshot]: RdsClusterSnapshot,
189191
[services.rdsDbInstance]: RDSDbInstance,
190192
[services.rdsEventSubscription]: RDSEventSubscription,

src/enums/services.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export default {
7878
networkInterface: 'networkInterface',
7979
organization: 'organization',
8080
rdsCluster: 'rdsCluster',
81+
rdsGlobalCluster: 'rdsGlobalCluster',
8182
rdsClusterSnapshot: 'rdsClusterSnapshot',
8283
rdsDbInstance: 'rdsDbInstance',
8384
rdsEventSubscription: 'rdsEventSubscription',

src/properties/logger.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ export default {
292292
lookingforRdsClusters: 'Looking for RDS Clusters...',
293293
creatingRdsInstance: (num: number): string => `Creating RDS Instance #${num}`,
294294
fetchedRdsClusters: (num: number): string => `Fetched ${num} RDS Clusters`,
295+
fetchedRdsGlobalClusters: (num: number): string => `Fetched ${num} RDS Global Clusters`,
295296
fetchedRdsInstances: (num: number): string =>
296297
`Fetched ${num} RDS DB Instances`,
297298
fetchedRdsEventSubscriptions: (num: number): string =>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import CloudGraph from '@cloudgraph/sdk'
2+
import RDS, {
3+
GlobalClustersMessage,
4+
DescribeGlobalClustersMessage,
5+
GlobalCluster,
6+
} from 'aws-sdk/clients/rds'
7+
import { AWSError } from 'aws-sdk/lib/error'
8+
import groupBy from 'lodash/groupBy'
9+
import isEmpty from 'lodash/isEmpty'
10+
import { Config } from 'aws-sdk/lib/config'
11+
import awsLoggerText from '../../properties/logger'
12+
import AwsErrorLog from '../../utils/errorLog'
13+
import { initTestEndpoint } from '../../utils'
14+
15+
const lt = { ...awsLoggerText }
16+
const { logger } = CloudGraph
17+
const serviceName = 'RDS DB cluster'
18+
const errorLog = new AwsErrorLog(serviceName)
19+
const endpoint = initTestEndpoint(serviceName)
20+
21+
const listGlobalClustersForRegion = async (rds: RDS): Promise<GlobalCluster[]> =>
22+
new Promise<GlobalCluster[]>(resolve => {
23+
const clusterList: GlobalCluster[] = []
24+
const descClustersOpts: DescribeGlobalClustersMessage = {}
25+
const listAllClusters = (token?: string): void => {
26+
if (token) {
27+
descClustersOpts.Marker = token
28+
}
29+
try {
30+
rds.describeGlobalClusters(
31+
descClustersOpts,
32+
(err: AWSError, data: GlobalClustersMessage) => {
33+
const { Marker, GlobalClusters = [] } = data || {}
34+
if (err) {
35+
errorLog.generateAwsErrorLog({
36+
functionName: 'rds:describeGlobalClusters',
37+
err,
38+
})
39+
}
40+
41+
clusterList.push(...GlobalClusters)
42+
43+
if (Marker) {
44+
listAllClusters(Marker)
45+
} else {
46+
resolve(clusterList)
47+
}
48+
}
49+
)
50+
} catch (error) {
51+
resolve([])
52+
}
53+
}
54+
listAllClusters()
55+
})
56+
57+
58+
export interface RawAwsRdsGlobalCluster extends GlobalCluster {
59+
region: string
60+
}
61+
62+
export default async ({
63+
regions,
64+
config,
65+
}: {
66+
regions: string
67+
config: Config
68+
}): Promise<{ [property: string]: RawAwsRdsGlobalCluster[] }> =>
69+
new Promise(async resolve => {
70+
const rdsData: RawAwsRdsGlobalCluster[] = []
71+
const regionPromises = []
72+
const tagsPromises = []
73+
74+
// Get all the global clusters for the region
75+
regions.split(',').map(region => {
76+
const regionPromise = new Promise<void>(async resolveRegion => {
77+
const rds = new RDS({ ...config, region, endpoint })
78+
const clusters = await listGlobalClustersForRegion(rds)
79+
80+
if (!isEmpty(clusters)) {
81+
rdsData.push(
82+
...(await Promise.all(
83+
clusters.map(async cluster => ({
84+
...cluster,
85+
region,
86+
}))
87+
))
88+
)
89+
}
90+
resolveRegion()
91+
})
92+
regionPromises.push(regionPromise)
93+
})
94+
95+
await Promise.all(regionPromises)
96+
logger.debug(lt.fetchedRdsGlobalClusters(rdsData.length))
97+
errorLog.reset()
98+
resolve(groupBy(rdsData, 'region'))
99+
})
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { RawAwsRdsGlobalCluster } from './data'
2+
import { AwsRdsGlobalCluster } from '../../types/generated'
3+
import { generateUniqueId } from '@cloudgraph/sdk'
4+
5+
export default ({
6+
service,
7+
account,
8+
region,
9+
}: {
10+
service: RawAwsRdsGlobalCluster
11+
account: string
12+
region: string
13+
}): AwsRdsGlobalCluster => {
14+
const {
15+
GlobalClusterIdentifier: globalClusterIdentifier,
16+
GlobalClusterResourceId: globalClusterResourceId,
17+
GlobalClusterArn: arn,
18+
Status: status,
19+
Engine: engine,
20+
EngineVersion: engineVersion,
21+
DatabaseName: databaseName,
22+
StorageEncrypted: storageEncrypted,
23+
DeletionProtection: deletionProtection,
24+
GlobalClusterMembers = [],
25+
FailoverState = {},
26+
} = service
27+
28+
29+
const failoverState = {
30+
status: FailoverState.Status,
31+
fromDbClusterArn: FailoverState.FromDbClusterArn,
32+
toDbClusterArn: FailoverState.ToDbClusterArn,
33+
}
34+
35+
const globalClusterMembers = GlobalClusterMembers.map(gc => ({
36+
id: generateUniqueId({
37+
arn,
38+
...gc,
39+
}),
40+
dBClusterArn: gc.DBClusterArn,
41+
isWriter: gc.IsWriter,
42+
globalWriteForwardingStatus: gc.GlobalWriteForwardingStatus,
43+
readers: gc.Readers ?? [],
44+
}))
45+
46+
47+
return {
48+
id: arn,
49+
accountId: account,
50+
arn,
51+
region,
52+
globalClusterIdentifier,
53+
globalClusterResourceId,
54+
status,
55+
engine,
56+
engineVersion,
57+
databaseName,
58+
storageEncrypted,
59+
deletionProtection,
60+
globalClusterMembers,
61+
failoverState,
62+
63+
}
64+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Service } from '@cloudgraph/sdk'
2+
import BaseService from '../base'
3+
import format from './format'
4+
import getData from './data'
5+
import mutation from './mutation'
6+
7+
export default class RDSGlobalCluster extends BaseService implements Service {
8+
format = format.bind(this)
9+
10+
getData = getData.bind(this)
11+
12+
mutation = mutation
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default `mutation($input: [AddawsRdsGlobalClusterInput!]!) {
2+
addawsRdsGlobalCluster(input: $input, upsert: true) {
3+
numUids
4+
}
5+
}`
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
type awsRdsGlobalClusterFailoverState {
2+
status: String @search(by: [hash, regexp])
3+
fromDbClusterArn: String @search(by: [hash, regexp])
4+
toDbClusterArn: String @search(by: [hash, regexp])
5+
}
6+
7+
type awsRdsGlobalClusterMembers
8+
@generate(
9+
query: { get: false, query: true, aggregate: false }
10+
mutation: { add: false, delete: false }
11+
subscription: false
12+
) {
13+
id: String! @id
14+
dBClusterArn: String @search(by: [hash, regexp])
15+
readers: [String] @search(by: [hash])
16+
isWriter: Boolean @search
17+
globalWriteForwardingStatus: String @search(by: [hash, regexp])
18+
}
19+
20+
21+
type awsRdsGlobalCluster implements awsBaseService @key(fields: "arn") {
22+
globalClusterIdentifier: String @search(by: [hash, regexp])
23+
globalClusterResourceId: String @search(by: [hash, regexp])
24+
globalClusterArn: String @search(by: [hash, regexp])
25+
status: String @search(by: [hash, regexp])
26+
engine: String @search(by: [hash, regexp])
27+
engineVersion: String @search(by: [hash, regexp])
28+
databaseName: String @search(by: [hash, regexp])
29+
storageEncrypted: Boolean @search
30+
deletionProtection: Boolean @search
31+
globalClusterMembers: [awsRdsGlobalClusterMembers]
32+
failoverState: awsRdsGlobalClusterFailoverState
33+
}

src/types/generated.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4152,6 +4152,34 @@ export type AwsRdsEventSubscription = AwsBaseService & {
41524152
subscriptionCreationTime?: Maybe<Scalars['String']>;
41534153
};
41544154

4155+
export type AwsRdsGlobalCluster = AwsBaseService & {
4156+
databaseName?: Maybe<Scalars['String']>;
4157+
deletionProtection?: Maybe<Scalars['Boolean']>;
4158+
engine?: Maybe<Scalars['String']>;
4159+
engineVersion?: Maybe<Scalars['String']>;
4160+
failoverState?: Maybe<AwsRdsGlobalClusterFailoverState>;
4161+
globalClusterArn?: Maybe<Scalars['String']>;
4162+
globalClusterIdentifier?: Maybe<Scalars['String']>;
4163+
globalClusterMembers?: Maybe<Array<Maybe<AwsRdsGlobalClusterMembers>>>;
4164+
globalClusterResourceId?: Maybe<Scalars['String']>;
4165+
status?: Maybe<Scalars['String']>;
4166+
storageEncrypted?: Maybe<Scalars['Boolean']>;
4167+
};
4168+
4169+
export type AwsRdsGlobalClusterFailoverState = {
4170+
fromDbClusterArn?: Maybe<Scalars['String']>;
4171+
status?: Maybe<Scalars['String']>;
4172+
toDbClusterArn?: Maybe<Scalars['String']>;
4173+
};
4174+
4175+
export type AwsRdsGlobalClusterMembers = {
4176+
dBClusterArn?: Maybe<Scalars['String']>;
4177+
globalWriteForwardingStatus?: Maybe<Scalars['String']>;
4178+
id: Scalars['String'];
4179+
isWriter?: Maybe<Scalars['Boolean']>;
4180+
readers?: Maybe<Array<Maybe<Scalars['String']>>>;
4181+
};
4182+
41554183
export type AwsRecorderStatus = {
41564184
lastStartTime?: Maybe<Scalars['String']>;
41574185
lastStatus?: Maybe<Scalars['String']>;

0 commit comments

Comments
 (0)