Skip to content

Commit 5ea6932

Browse files
author
Marco Franceschi
committed
feat: Added new DocumentDBCluster service
1 parent b292e03 commit 5ea6932

File tree

6 files changed

+312
-1
lines changed

6 files changed

+312
-1
lines changed

src/services/docdbCluster/data.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import CloudGraph from '@cloudgraph/sdk'
2+
import DOCDB, {
3+
DBCluster,
4+
TagListMessage,
5+
DescribeDBClustersMessage,
6+
DBClusterMessage,
7+
DBSubnetGroup,
8+
DBSubnetGroupMessage,
9+
} from 'aws-sdk/clients/docdb'
10+
import { AWSError } from 'aws-sdk/lib/error'
11+
import groupBy from 'lodash/groupBy'
12+
import isEmpty from 'lodash/isEmpty'
13+
import { Config } from 'aws-sdk/lib/config'
14+
import awsLoggerText from '../../properties/logger'
15+
import { TagMap, AwsTag } from '../../types'
16+
import { convertAwsTagsToTagMap } from '../../utils/format'
17+
import AwsErrorLog from '../../utils/errorLog'
18+
import { initTestEndpoint } from '../../utils'
19+
20+
const lt = { ...awsLoggerText }
21+
const { logger } = CloudGraph
22+
const serviceName = 'DOC DB cluster'
23+
const errorLog = new AwsErrorLog(serviceName)
24+
const endpoint = initTestEndpoint(serviceName)
25+
26+
const listClustersForRegion = async (docdb: DOCDB): Promise<DBCluster[]> =>
27+
new Promise<DBCluster[]>(resolve => {
28+
const clusterList: DBCluster[] = []
29+
const descClustersOpts: DescribeDBClustersMessage = {}
30+
const listAllClusters = (token?: string): void => {
31+
if (token) {
32+
descClustersOpts.Marker = token
33+
}
34+
try {
35+
docdb.describeDBClusters(
36+
descClustersOpts,
37+
(err: AWSError, data: DBClusterMessage) => {
38+
const { Marker, DBClusters = [] } = data || {}
39+
if (err) {
40+
errorLog.generateAwsErrorLog({
41+
functionName: 'docdb:describeDBClusters',
42+
err,
43+
})
44+
}
45+
46+
clusterList.push(...DBClusters)
47+
48+
if (Marker) {
49+
listAllClusters(Marker)
50+
} else {
51+
resolve(clusterList)
52+
}
53+
}
54+
)
55+
} catch (error) {
56+
resolve([])
57+
}
58+
}
59+
listAllClusters()
60+
})
61+
62+
const describeDBSubnetGroups = async (
63+
docdb: DOCDB,
64+
DBSubnetGroupName: string
65+
): Promise<DBSubnetGroup[]> =>
66+
new Promise(resolve => {
67+
try {
68+
docdb.describeDBSubnetGroups(
69+
{ DBSubnetGroupName },
70+
(err: AWSError, data: DBSubnetGroupMessage) => {
71+
if (err) {
72+
errorLog.generateAwsErrorLog({
73+
functionName: 'docdb:describeDBSubnetGroups',
74+
err,
75+
})
76+
return resolve([])
77+
}
78+
if (!isEmpty(data)) {
79+
resolve(data.DBSubnetGroups)
80+
}
81+
}
82+
)
83+
} catch (error) {
84+
resolve([])
85+
}
86+
})
87+
88+
export interface RawAwsDocDBCluster extends DBCluster {
89+
DbSubnetGroups: DBSubnetGroup[]
90+
Tags?: TagMap
91+
region: string
92+
}
93+
94+
export default async ({
95+
regions,
96+
config,
97+
}: {
98+
regions: string
99+
config: Config
100+
}): Promise<{ [property: string]: RawAwsDocDBCluster[] }> =>
101+
new Promise(async resolve => {
102+
const docDBData: RawAwsDocDBCluster[] = []
103+
const regionPromises = []
104+
105+
// Get all the clusters for the region
106+
regions.split(',').map(region => {
107+
const regionPromise = new Promise<void>(async resolveRegion => {
108+
const docdb = new DOCDB({ ...config, region, endpoint })
109+
const clusters = await listClustersForRegion(docdb)
110+
111+
if (!isEmpty(clusters)) {
112+
docDBData.push(
113+
...(await Promise.all(
114+
clusters.map(async cluster => ({
115+
...cluster,
116+
DbSubnetGroups: await describeDBSubnetGroups(
117+
docdb,
118+
cluster.DBSubnetGroup
119+
),
120+
region,
121+
}))
122+
))
123+
)
124+
}
125+
resolveRegion()
126+
})
127+
regionPromises.push(regionPromise)
128+
})
129+
130+
await Promise.all(regionPromises)
131+
logger.debug(lt.fetchedDocdbClusters(docDBData.length))
132+
errorLog.reset()
133+
134+
resolve(groupBy(docDBData, 'region'))
135+
})
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { RawAwsDocDBCluster } from './data'
2+
import { AwsDocdbCluster } from '../../types/generated'
3+
import { formatTagsFromMap } from '../../utils/format'
4+
5+
export default ({
6+
service,
7+
account,
8+
region,
9+
}: {
10+
service: RawAwsDocDBCluster
11+
account: string
12+
region: string
13+
}): AwsDocdbCluster => {
14+
const {
15+
AvailabilityZones = [],
16+
BackupRetentionPeriod: backupRetentionPeriod,
17+
DBClusterIdentifier: dBClusterIdentifier,
18+
DBClusterParameterGroup: dBClusterParameterGroup,
19+
DBSubnetGroup: dBSubnetGroup,
20+
Status: status,
21+
PercentProgress: percentProgress,
22+
EarliestRestorableTime: earliestRestorableTime,
23+
Endpoint: endpoint,
24+
ReaderEndpoint: readerEndpoint,
25+
MultiAZ: multiAZ,
26+
Engine: engine,
27+
EngineVersion: engineVersion,
28+
LatestRestorableTime: latestRestorableTime,
29+
Port: port,
30+
MasterUsername: masterUsername,
31+
PreferredBackupWindow: preferredBackupWindow,
32+
PreferredMaintenanceWindow: preferredMaintenanceWindow,
33+
ReplicationSourceIdentifier: replicationSourceIdentifier,
34+
ReadReplicaIdentifiers: readReplicaIdentifiers,
35+
DBClusterMembers = [],
36+
VpcSecurityGroups = [],
37+
HostedZoneId: hostedZoneId,
38+
StorageEncrypted: storageEncrypted,
39+
KmsKeyId: kmsKeyId,
40+
DbClusterResourceId: dbClusterResourceId,
41+
DBClusterArn: arn,
42+
CloneGroupId: cloneGroupId,
43+
ClusterCreateTime: clusterCreateTime,
44+
DeletionProtection: deletionProtection,
45+
} = service
46+
47+
const availabilityZones = AvailabilityZones.map(az => az)
48+
const dBClusterMembers = DBClusterMembers.map(dbinstance => dbinstance.DBInstanceIdentifier)
49+
const vpcSecurityGroups = VpcSecurityGroups.map(vpcsg => vpcsg.VpcSecurityGroupId)
50+
51+
return {
52+
id: arn,
53+
accountId: account,
54+
arn,
55+
region,
56+
availabilityZones,
57+
backupRetentionPeriod,
58+
dBClusterIdentifier,
59+
dBClusterParameterGroup,
60+
dBSubnetGroup,
61+
status,
62+
percentProgress,
63+
earliestRestorableTime: earliestRestorableTime?.toISOString(),
64+
endpoint,
65+
readerEndpoint,
66+
multiAZ,
67+
engine,
68+
engineVersion,
69+
latestRestorableTime: latestRestorableTime?.toISOString(),
70+
port,
71+
masterUsername,
72+
preferredBackupWindow,
73+
preferredMaintenanceWindow,
74+
replicationSourceIdentifier,
75+
readReplicaIdentifiers,
76+
dBClusterMembers,
77+
vpcSecurityGroups,
78+
hostedZoneId,
79+
storageEncrypted,
80+
kmsKeyId,
81+
dbClusterResourceId,
82+
cloneGroupId,
83+
clusterCreateTime: clusterCreateTime?.toISOString(),
84+
deletionProtection,
85+
}
86+
}

src/services/docdbCluster/index.ts

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 DOCDBCluster 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: [AddawsDocdbClusterInput!]!) {
2+
addawsDocdbCluster(input: $input, upsert: true) {
3+
numUids
4+
}
5+
}`
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
type awsDocdbCluster implements awsBaseService @key(fields: "arn") {
2+
availabilityZones: [String] @search(by: [hash, regexp])
3+
backupRetentionPeriod: Int @search
4+
dBClusterIdentifier: String @search(by: [hash, regexp])
5+
dBClusterParameterGroup: String @search(by: [hash, regexp])
6+
dBSubnetGroup: String @search(by: [hash, regexp])
7+
status: String @search(by: [hash, regexp])
8+
percentProgress: String @search(by: [hash, regexp])
9+
earliestRestorableTime: DateTime @search(by: [day])
10+
endpoint: String @search(by: [hash, regexp])
11+
readerEndpoint: String @search(by: [hash, regexp])
12+
multiAZ: Boolean @search
13+
engine: String @search(by: [hash, regexp])
14+
engineVersion: String @search(by: [hash, regexp])
15+
latestRestorableTime: DateTime @search(by: [day])
16+
port: Int @search
17+
masterUsername: String @search(by: [hash, regexp])
18+
preferredBackupWindow: String @search(by: [hash, regexp])
19+
preferredMaintenanceWindow: String @search(by: [hash, regexp])
20+
replicationSourceIdentifier: String @search(by: [hash, regexp])
21+
readReplicaIdentifiers: [String] @search(by: [hash, regexp])
22+
dBClusterMembers: [String] @search(by: [hash, regexp])
23+
vpcSecurityGroups: [String] @search(by: [hash, regexp])
24+
hostedZoneId: String @search(by: [hash, regexp])
25+
storageEncrypted: Boolean @search
26+
kmsKeyId: String @search(by: [hash, regexp])
27+
dbClusterResourceId: String @search(by: [hash, regexp])
28+
dBClusterArn: String @search(by: [hash, regexp])
29+
cloneGroupId: String @search(by: [hash, regexp])
30+
clusterCreateTime: DateTime @search(by: [day])
31+
nabledCloudwatchLogsExports: [String] @search(by: [hash, regexp])
32+
deletionProtection: Boolean @search
33+
}
34+
35+
36+
37+

src/types/generated.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ export type AwsAccount = AwsOptionalService & {
159159
cloudtrail?: Maybe<Array<Maybe<AwsCloudtrail>>>;
160160
cloudwatch?: Maybe<Array<Maybe<AwsCloudwatch>>>;
161161
cloudwatchLogs?: Maybe<Array<Maybe<AwsCloudwatchLog>>>;
162+
codeCommitRepository?: Maybe<Array<Maybe<AwsCodeCommitRepository>>>;
162163
codePipelineWebhooks?: Maybe<Array<Maybe<AwsCodePipelineWebhook>>>;
163164
codePipelines?: Maybe<Array<Maybe<AwsCodePipeline>>>;
164-
codeCommitRepository?: Maybe<Array<Maybe<AwsCodeCommitRepository>>>;
165165
codebuilds?: Maybe<Array<Maybe<AwsCodebuild>>>;
166166
cognitoIdentityPool?: Maybe<Array<Maybe<AwsCognitoIdentityPool>>>;
167167
cognitoUserPool?: Maybe<Array<Maybe<AwsCognitoUserPool>>>;
@@ -170,6 +170,7 @@ export type AwsAccount = AwsOptionalService & {
170170
configurationRules?: Maybe<Array<Maybe<AwsConfigurationRule>>>;
171171
customerGateway?: Maybe<Array<Maybe<AwsCustomerGateway>>>;
172172
dmsReplicationInstances?: Maybe<Array<Maybe<AwsDmsReplicationInstance>>>;
173+
docdbCluster?: Maybe<Array<Maybe<AwsDocdbCluster>>>;
173174
dynamodb?: Maybe<Array<Maybe<AwsDynamoDbTable>>>;
174175
ebs?: Maybe<Array<Maybe<AwsEbs>>>;
175176
ec2Instances?: Maybe<Array<Maybe<AwsEc2>>>;
@@ -1478,6 +1479,40 @@ export type AwsDmsReplicationInstance = AwsBaseService & {
14781479
vpcSecurityGroups?: Maybe<Array<Maybe<AwsDmsReplicationInstanceVpcSecurityGroups>>>;
14791480
};
14801481

1482+
export type AwsDocdbCluster = AwsBaseService & {
1483+
availabilityZones?: Maybe<Array<Maybe<Scalars['String']>>>;
1484+
backupRetentionPeriod?: Maybe<Scalars['Int']>;
1485+
cloneGroupId?: Maybe<Scalars['String']>;
1486+
clusterCreateTime?: Maybe<Scalars['DateTime']>;
1487+
dBClusterArn?: Maybe<Scalars['String']>;
1488+
dBClusterIdentifier?: Maybe<Scalars['String']>;
1489+
dBClusterMembers?: Maybe<Array<Maybe<Scalars['String']>>>;
1490+
dBClusterParameterGroup?: Maybe<Scalars['String']>;
1491+
dBSubnetGroup?: Maybe<Scalars['String']>;
1492+
dbClusterResourceId?: Maybe<Scalars['String']>;
1493+
deletionProtection?: Maybe<Scalars['Boolean']>;
1494+
earliestRestorableTime?: Maybe<Scalars['DateTime']>;
1495+
endpoint?: Maybe<Scalars['String']>;
1496+
engine?: Maybe<Scalars['String']>;
1497+
engineVersion?: Maybe<Scalars['String']>;
1498+
hostedZoneId?: Maybe<Scalars['String']>;
1499+
kmsKeyId?: Maybe<Scalars['String']>;
1500+
latestRestorableTime?: Maybe<Scalars['DateTime']>;
1501+
masterUsername?: Maybe<Scalars['String']>;
1502+
multiAZ?: Maybe<Scalars['Boolean']>;
1503+
nabledCloudwatchLogsExports?: Maybe<Array<Maybe<Scalars['String']>>>;
1504+
percentProgress?: Maybe<Scalars['String']>;
1505+
port?: Maybe<Scalars['Int']>;
1506+
preferredBackupWindow?: Maybe<Scalars['String']>;
1507+
preferredMaintenanceWindow?: Maybe<Scalars['String']>;
1508+
readReplicaIdentifiers?: Maybe<Array<Maybe<Scalars['String']>>>;
1509+
readerEndpoint?: Maybe<Scalars['String']>;
1510+
replicationSourceIdentifier?: Maybe<Scalars['String']>;
1511+
status?: Maybe<Scalars['String']>;
1512+
storageEncrypted?: Maybe<Scalars['Boolean']>;
1513+
vpcSecurityGroups?: Maybe<Array<Maybe<Scalars['String']>>>;
1514+
};
1515+
14811516
export type AwsDynamoDbTable = AwsBaseService & {
14821517
appSync?: Maybe<Array<Maybe<AwsAppSync>>>;
14831518
attributes?: Maybe<Array<Maybe<AwsDynamoDbTableAttributes>>>;

0 commit comments

Comments
 (0)