Skip to content

Commit afd255f

Browse files
committed
feat: add apigateway missing services
1 parent 83486c5 commit afd255f

25 files changed

Lines changed: 974 additions & 128 deletions

File tree

README.md

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

src/enums/serviceAliases.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ export default {
77
[services.apiGatewayHttpApi]: 'apiGatewayHttpApis',
88
[services.apiGatewayResource]: 'apiGatewayResources',
99
[services.apiGatewayRestApi]: 'apiGatewayRestApis',
10+
[services.apiGatewayApiKey]: 'apiGatewayApiKeys',
11+
[services.apiGatewayVpcLink]: 'apiGatewayVpcLinks',
12+
[services.apiGatewayUsagePlan]: 'apiGatewayUsagePlans',
1013
[services.apiGatewayStage]: 'apiGatewayStages',
1114
[services.asg]: 'asgs',
1215
[services.athenaDataCatalog]: 'athenaDataCatalogs',

src/enums/serviceMap.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import ACM from '../services/acm'
33
import ALB from '../services/alb'
44
import APIGatewayResource from '../services/apiGatewayResource'
55
import APIGatewayRestApi from '../services/apiGatewayRestApi'
6+
import APIGatewayApiKey from '../services/apiGatewayApiKey'
7+
import APIGatewayVpcLink from '../services/apiGatewayVpcLink'
8+
import APIGatewayUsagePlan from '../services/apiGatewayUsagePlan'
69
import APIGatewayStage from '../services/apiGatewayStage'
710
import ASG from '../services/asg'
811
import AppSync from '../services/appSync'
@@ -126,6 +129,9 @@ export default {
126129
[services.apiGatewayHttpApi]: APIGatewayHttpApi,
127130
[services.apiGatewayResource]: APIGatewayResource,
128131
[services.apiGatewayRestApi]: APIGatewayRestApi,
132+
[services.apiGatewayApiKey]: APIGatewayApiKey,
133+
[services.apiGatewayVpcLink]: APIGatewayVpcLink,
134+
[services.apiGatewayUsagePlan]: APIGatewayUsagePlan,
129135
[services.apiGatewayStage]: APIGatewayStage,
130136
[services.athenaDataCatalog]: AthenaDataCatalog,
131137
[services.asg]: ASG,

src/enums/services.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ export default {
55
apiGatewayHttpApi: 'apiGatewayHttpApi',
66
apiGatewayResource: 'apiGatewayResource',
77
apiGatewayRestApi: 'apiGatewayRestApi',
8+
apiGatewayApiKey: 'apiGatewayApiKey',
9+
apiGatewayVpcLink: 'apiGatewayVpcLink',
10+
apiGatewayUsagePlan: 'apiGatewayUsagePlan',
811
apiGatewayStage: 'apiGatewayStage',
912
appSync: 'appSync',
1013
asg: 'asg',

src/properties/logger.ts

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export default {
5959
*/
6060
fetchingCloudFrontData:
6161
'Fetching CloudFront Distros for this AWS account via the AWS SDK...',
62-
fetchedCloudFrontDistros: (num: number) =>
62+
fetchedCloudFrontDistros: (num: number): string =>
6363
`Fetched ${num} CloudFront Distros`,
6464
fetchingCloudFrontDistrosConfigAndTags:
6565
'Fetching CloudFront Distros Config Data and Tags...',
@@ -117,7 +117,7 @@ export default {
117117
lookingForIotThing: 'Looking for IoT Things to add to Region...',
118118
addingIotThing: (num: number): string =>
119119
`Created and added ${num} IoT Things to this region`,
120-
foundMoreIoTThings: (num: number) =>
120+
foundMoreIoTThings: (num: number): string =>
121121
`Found another ${num} IoT things in this region...`,
122122
gettingIoTThings: 'Fetching IoT things...',
123123
/**
@@ -134,10 +134,24 @@ export default {
134134
`Fetched ${num} Api Gateway Stages`,
135135
fetchedApiGwDomainNames: (num: number): string =>
136136
`Fetched ${num} API Gateway Domain Names`,
137+
fetchedApiGatewayApiKeys: (num: number): string =>
138+
`Fetched ${num} Api Gateway Api Keys`,
139+
fetchedApiGatewayVpcLinks: (num: number): string =>
140+
`Fetched ${num} Api Gateway Vpc Links`,
141+
fetchedApiGatewayUsagePlans: (num: number): string =>
142+
`Fetched ${num} Api Gateway Usage Plans`,
137143
fetchingApiGatewayData:
138144
'Fetching API Gateway data for this AWS account via the AWS SDK...',
139145
doneFetchingApiGatewayData: '✅ Done fetching API Gateway Data ✅',
140146
gettingApiGatewayTags: 'Fetching tags for each Api Gateway Rest Api...',
147+
gettingApiGatewayAuthorizers:
148+
'Fetching authorizers for each Api Gateway Rest Api...',
149+
gettingApiGatewayDocumentationParts:
150+
'Fetching authorizers for each Api Gateway Documentation Parts...',
151+
gettingApiGatewayGatewayResponses:
152+
'Fetching authorizers for each Api Gateway Gateway Responses...',
153+
gettingApiGatewayModels:
154+
'Fetching authorizers for each Api Gateway Models...',
141155
gettingApiGatewayStageTags: 'Fetching tags for each Api Gateway Stage...',
142156
/**
143157
* Vpc
@@ -318,13 +332,14 @@ export default {
318332
fetchedEmrClusters: (num: number): string => `Fetched ${num} EMR Clusters`,
319333
fetchedEmrClusterInstances: (num: number): string =>
320334
`Fetched ${num} EMR Clusters Instances`,
321-
foundAnotherFiftyClusters: (region: string) =>
335+
foundAnotherFiftyClusters: (region: string): string =>
322336
`Found another 50 EMR clusters for the ${region} region...`,
323-
foundAnotherTwoThousandInstances: (cluster: string) =>
337+
foundAnotherTwoThousandInstances: (cluster: string): string =>
324338
`Found another 2000 EMR instances for the ${cluster} cluster...`,
325-
foundAnotherFiftySteps: (cluster: string) =>
339+
foundAnotherFiftySteps: (cluster: string): string =>
326340
`Found another 50 EMR steps for the ${cluster} cluster...`,
327-
fetchedEmrClusterSteps: (num: number) => `Fetched ${num} EMR Cluster Steps`,
341+
fetchedEmrClusterSteps: (num: number): string =>
342+
`Fetched ${num} EMR Cluster Steps`,
328343
addingEmrEc2Connection: (
329344
clusterName: string,
330345
ec2InstanceName: string
@@ -377,11 +392,11 @@ export default {
377392
lookingForDynamoDb: 'Looking for DynamoDb Tables to add...',
378393
fetchingDynamoDbData:
379394
'Fetching DynamoDB data for this AWS account via the AWS SDK...',
380-
doneFetchingDynamoDbData: (num: number) =>
395+
doneFetchingDynamoDbData: (num: number): string =>
381396
`🕒 Done fetching DynamoDb Data in ${num} 🕘`,
382-
fetchedDynamoDbTableNames: (num: number) =>
397+
fetchedDynamoDbTableNames: (num: number): string =>
383398
`Fetched ${num} DynamoDB table names`,
384-
addingDynamoDbTables: (num: number) =>
399+
addingDynamoDbTables: (num: number): string =>
385400
`Found ${num} Dynamo DB tables, adding them to the Region`,
386401
gettingTableDetails: 'Fetching details for each table...',
387402
gettingTableTags: 'Fetching tags for each table...',
@@ -391,10 +406,10 @@ export default {
391406
/**
392407
* SNS
393408
*/
394-
fetchedSNSTopics: (num: number) => `Fetched ${num} SNS Topics`,
395-
gettingSNSTopicAttributes: `Fetching attributes for each topic...`,
396-
gettingSNSTopicTags: `Fetching tags for each topic...`,
397-
gettingSNSTopicSubscriptions: `Fetching subscriptions for each topic...`,
409+
fetchedSNSTopics: (num: number): string => `Fetched ${num} SNS Topics`,
410+
gettingSNSTopicAttributes: 'Fetching attributes for each topic...',
411+
gettingSNSTopicTags: 'Fetching tags for each topic...',
412+
gettingSNSTopicSubscriptions: 'Fetching subscriptions for each topic...',
398413
lookingForSns: 'Looking for SNS topics and subscriptions to add...',
399414
addingSns: (num: number): string =>
400415
`Found ${num} SNS topics, adding them to the Region`,
@@ -459,7 +474,7 @@ export default {
459474
`Found ${num} EKS Clusters, adding them to the VPC`,
460475
canNotFindClusterForAsg:
461476
'ERROR: Can not find ECS/EKS cluster for ASG - it should have been added already',
462-
foundMoreEKSClusters: (num: number) =>
477+
foundMoreEKSClusters: (num: number): string =>
463478
`Found another ${num} EKS clusters in this region...`,
464479
/**
465480
* Elastic Beanstalk
@@ -476,13 +491,13 @@ export default {
476491
`Found ${num} ElastiCache Clusters, adding them to the VPC`,
477492
missingReplicationGroup: (is: string): string =>
478493
`Missing replication group for ${is} ElastiCache Cluster! Not adding ElastiCache Data`,
479-
fetchedElasticacheClusters: (num: number) =>
494+
fetchedElasticacheClusters: (num: number): string =>
480495
`Fetched ${num} Elasticache clusters...`,
481496
/**
482497
* ECR
483498
*/
484499
fetchedECRRepos: (num: number): string => `Found ${num} ECR repos...`,
485-
foundMoreECRRepos: (num: number) =>
500+
foundMoreECRRepos: (num: number): string =>
486501
`Found another ${num} ECR repos in this region...`,
487502
gettingECRRepos: 'Fetching ECR repos...',
488503
gettingECRRepoTags: 'Fetching tags for each ECR repo...',
@@ -625,7 +640,7 @@ export default {
625640
lookingForCloud9: 'Looking for Cloud9 to add to Region...',
626641
addingCloud9: (num: number): string =>
627642
`Created and added ${num} Cloud9 to this region`,
628-
foundMoreCloud9Environments: (num: number) =>
643+
foundMoreCloud9Environments: (num: number): string =>
629644
`Found another ${num} Cloud9 environments in this region...`,
630645
gettingCloud9Environments: 'Fetching Cloud9 environments...',
631646
gettingCloud9EnvironmentTags: 'Fetching tags for each Cloud9 environment...',

src/services/account/schema.graphql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
type awsAccount implements awsOptionalService @key(fields: "id") {
22
regions: [String] @search(by: [hash])
33
albs: [awsAlb]
4+
apiGatewayApiKeys: [awsApiGatewayApiKey]
45
apiGatewayDomainNames: [awsApiGatewayDomainName]
56
apiGatewayHttpApis: [awsApiGatewayHttpApi]
67
apiGatewayResources: [awsApiGatewayResource]
78
apiGatewayRestApis: [awsApiGatewayRestApi]
89
apiGatewayStages: [awsApiGatewayStage]
10+
apiGatewayUsagePlans: [awsApiGatewayUsagePlan]
11+
apiGatewayVpcLinks: [awsApiGatewayVpcLink]
912
appSync: [awsAppSync]
1013
asgs: [awsAsg]
1114
athenaDataCatalogs: [awsAthenaDataCatalog]
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import CloudGraph from '@cloudgraph/sdk'
2+
import APIGW, {
3+
ApiKey,
4+
ListOfApiKey,
5+
GetApiKeysRequest,
6+
ApiKeys,
7+
} from 'aws-sdk/clients/apigateway'
8+
import { AWSError } from 'aws-sdk/lib/error'
9+
import { Config } from 'aws-sdk/lib/config'
10+
import isEmpty from 'lodash/isEmpty'
11+
import groupBy from 'lodash/groupBy'
12+
import awsLoggerText from '../../properties/logger'
13+
import { initTestEndpoint, setAwsRetryOptions } from '../../utils'
14+
import AwsErrorLog from '../../utils/errorLog'
15+
import { API_GATEWAY_CUSTOM_DELAY } from '../../config/constants'
16+
17+
const lt = { ...awsLoggerText }
18+
const { logger } = CloudGraph
19+
const MAX_API_KEYS = 500
20+
const serviceName = 'API Gateway Api Key'
21+
const errorLog = new AwsErrorLog(serviceName)
22+
const endpoint = initTestEndpoint(serviceName)
23+
const customRetrySettings = setAwsRetryOptions({
24+
baseDelay: API_GATEWAY_CUSTOM_DELAY,
25+
})
26+
27+
export interface RawAwsApiGatewayApiKey extends ApiKey {
28+
region: string
29+
}
30+
31+
export const getApiKeysForRegion = async (
32+
apiGw: APIGW
33+
): Promise<ListOfApiKey> =>
34+
new Promise<ListOfApiKey>(resolve => {
35+
const apiKeyList: ListOfApiKey = []
36+
const getApiKeyOpts: GetApiKeysRequest = {}
37+
const listAllApiKeys = (token?: string): void => {
38+
getApiKeyOpts.limit = MAX_API_KEYS
39+
if (token) {
40+
getApiKeyOpts.position = token
41+
}
42+
try {
43+
apiGw.getApiKeys(getApiKeyOpts, (err: AWSError, data: ApiKeys) => {
44+
const { position, items = [] } = data || {}
45+
if (err) {
46+
errorLog.generateAwsErrorLog({
47+
functionName: 'apiGw:getApiKeys',
48+
err,
49+
})
50+
}
51+
52+
apiKeyList.push(...items)
53+
54+
if (position) {
55+
listAllApiKeys(position)
56+
} else {
57+
resolve(apiKeyList)
58+
}
59+
})
60+
} catch (error) {
61+
resolve([])
62+
}
63+
}
64+
listAllApiKeys()
65+
})
66+
67+
export default async ({
68+
regions,
69+
config,
70+
}: {
71+
regions: string
72+
config: Config
73+
}): Promise<{ [property: string]: RawAwsApiGatewayApiKey[] }> =>
74+
new Promise(async resolve => {
75+
const apiGatewayData = []
76+
const regionPromises = []
77+
78+
regions.split(',').forEach(region => {
79+
const apiGw = new APIGW({
80+
...config,
81+
region,
82+
endpoint,
83+
...customRetrySettings,
84+
})
85+
const regionPromise = new Promise<void>(async resolveRegion => {
86+
const apiKeyList = await getApiKeysForRegion(apiGw)
87+
if (!isEmpty(apiKeyList)) {
88+
apiGatewayData.push(
89+
...apiKeyList.map(apiKey => ({
90+
...apiKey,
91+
region,
92+
}))
93+
)
94+
}
95+
resolveRegion()
96+
})
97+
regionPromises.push(regionPromise)
98+
})
99+
100+
await Promise.all(regionPromises)
101+
logger.debug(lt.fetchedApiGatewayApiKeys(apiGatewayData.length))
102+
103+
errorLog.reset()
104+
105+
resolve(groupBy(apiGatewayData, 'region'))
106+
})
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { RawAwsApiGatewayApiKey } from './data'
2+
import { AwsApiGatewayApiKey } from '../../types/generated'
3+
4+
export default ({
5+
service,
6+
account: accountId,
7+
region,
8+
}: {
9+
service: RawAwsApiGatewayApiKey
10+
account: string
11+
region: string
12+
}): AwsApiGatewayApiKey => {
13+
const { id, value, name } = service
14+
15+
return {
16+
id,
17+
arn: id,
18+
accountId,
19+
region,
20+
value,
21+
name,
22+
}
23+
}
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 APIGatewayApiKey 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: [AddawsApiGatewayApiKeyInput!]!) {
2+
addawsApiGatewayApiKey(input: $input, upsert: true) {
3+
numUids
4+
}
5+
}`

0 commit comments

Comments
 (0)