Skip to content

Commit da49a74

Browse files
committed
feat(services): Add managedPrefixList service
1 parent a118711 commit da49a74

File tree

15 files changed

+361
-0
lines changed

15 files changed

+361
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
136136
| kms | cloudtrail, cloudwatchLog, codebuild, ecsCluster, efs, eksCluster, elastiCacheReplicationGroup, elasticSearchDomain, emrCluster, managedAirflow, lambda, rdsCluster, rdsClusterSnapshot, rdsDbInstance, sns, sageMakerNotebookInstance, secretsManager, dmsReplicationInstance, redshiftCluster |
137137
| lambda | appSync, cognitoUserPool, kms, s3, secretsManager, securityGroup, subnet, vpc, iamRole |
138138
| managedAirflow | cloudwatchLog, iamRole, kms, securityGroups, subnet, s3 |
139+
| managedPrefixList | |
139140
| nacl | vpc |
140141
| natGateway | networkInterface, subnet, vpc |
141142
| networkInterface | ec2, eip, efsMountTarget, natGateway, sageMakerNotebookInstance, subnet, vpc, flowLog, securityGroup |

src/enums/schemasMap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export default {
7373
[services.kms]: 'awsKms',
7474
[services.lambda]: 'awsLambda',
7575
[services.managedAirflow]: 'awsManagedAirflow',
76+
[services.managedPrefixList]: 'awsManagedPrefixList',
7677
[services.nacl]: 'awsNetworkAcl',
7778
[services.nat]: 'awsNatGateway',
7879
[services.networkInterface]: 'awsNetworkInterface',

src/enums/serviceAliases.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export default {
5151
[services.kinesisStream]: 'kinesisStreams',
5252
[services.lambda]: 'lambdaFunctions',
5353
[services.managedAirflow]: 'managedAirflows',
54+
[services.managedPrefixList]: 'managedPrefixLists',
5455
[services.nat]: 'natGateway',
5556
[services.networkInterface]: 'networkInterfaces',
5657
[services.organization]: 'organizations',

src/enums/serviceMap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ import SystemsManagerDocument from '../services/systemsManagerDocument'
9898
import RdsClusterSnapshot from '../services/rdsClusterSnapshot'
9999
import APIGatewayDomainName from '../services/apiGatewayDomainName'
100100
import APIGatewayHttpApi from '../services/apiGatewayHttpApi'
101+
import ManagedPrefixList from '../services/managedPrefixList'
101102

102103
/**
103104
* serviceMap is an object that contains all currently supported services for AWS
@@ -156,6 +157,7 @@ export default {
156157
[services.kms]: AwsKms,
157158
[services.lambda]: Lambda,
158159
[services.managedAirflow]: ManagedAirflow,
160+
[services.managedPrefixList]: ManagedPrefixList,
159161
[services.nacl]: NetworkAcl,
160162
[services.nat]: NATGateway,
161163
[services.networkInterface]: NetworkInterface,

src/enums/services.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export default {
6767
kms: 'kms',
6868
lambda: 'lambda',
6969
managedAirflow: 'managedAirflow',
70+
managedPrefixList: 'managedPrefixList',
7071
nacl: 'nacl',
7172
nat: 'nat',
7273
networkInterface: 'networkInterface',

src/properties/logger.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,4 +672,9 @@ export default {
672672
* Access Analyzers
673673
*/
674674
fetchedaccessAnalyzers: (num: number): string => `Found ${num} Access Analyzers`,
675+
/**
676+
* Managed Prefix Lists
677+
*/
678+
fetchedManagedPrefixLists: (num: number): string => `Found ${num} Managed Prefix Lists`,
679+
fetchedManagedPrefixListEntries: (num: number): string => `Found ${num} Managed Prefix List Entries`,
675680
}

src/services/account/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type awsAccount implements awsOptionalService @key(fields: "id") {
6868
kms: [awsKms]
6969
lambdaFunctions: [awsLambda]
7070
managedAirflows: [awsManagedAirflow]
71+
managedPrefixLists: [awsManagedPrefixList]
7172
nacl: [awsNetworkAcl]
7273
natGateway: [awsNatGateway]
7374
networkInterfaces: [awsNetworkInterface]
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
import CloudGraph from '@cloudgraph/sdk'
2+
import groupBy from 'lodash/groupBy'
3+
import isEmpty from 'lodash/isEmpty'
4+
5+
import EC2, {
6+
DescribeManagedPrefixListsRequest,
7+
DescribeManagedPrefixListsResult,
8+
GetManagedPrefixListEntriesRequest,
9+
GetManagedPrefixListEntriesResult,
10+
ManagedPrefixList,
11+
PrefixListEntry,
12+
} from 'aws-sdk/clients/ec2'
13+
14+
import { Config } from 'aws-sdk/lib/config'
15+
import { AWSError } from 'aws-sdk/lib/error'
16+
import { convertAwsTagsToTagMap } from '../../utils/format'
17+
import { AwsTag, TagMap } from '../../types'
18+
19+
import awsLoggerText from '../../properties/logger'
20+
import { initTestEndpoint } from '../../utils'
21+
import AwsErrorLog from '../../utils/errorLog'
22+
23+
const lt = { ...awsLoggerText }
24+
const { logger } = CloudGraph
25+
const serviceName = 'Managed Prefix List'
26+
const errorLog = new AwsErrorLog(serviceName)
27+
const endpoint = initTestEndpoint(serviceName)
28+
29+
const listManagedPrefixListData = async ({
30+
ec2,
31+
resolveRegion,
32+
}: {
33+
ec2: EC2
34+
resolveRegion: () => void
35+
}): Promise<ManagedPrefixList[]> =>
36+
new Promise<ManagedPrefixList[]>(resolve => {
37+
const managedPrefixLists: ManagedPrefixList[] = []
38+
let args: DescribeManagedPrefixListsRequest = {}
39+
40+
const listManagedPrefixLists = (token?: string): void => {
41+
if (token) {
42+
args = { ...args, NextToken: token }
43+
}
44+
try {
45+
ec2.describeManagedPrefixLists(
46+
args,
47+
(err: AWSError, data: DescribeManagedPrefixListsResult) => {
48+
if (err) {
49+
errorLog.generateAwsErrorLog({
50+
functionName: 'ec2:describeManagedPrefixLists',
51+
err,
52+
})
53+
}
54+
55+
if (isEmpty(data)) {
56+
return resolveRegion()
57+
}
58+
59+
const { NextToken: nextToken, PrefixLists: prefixLists = [] } = data
60+
61+
if (isEmpty(prefixLists)) {
62+
return resolveRegion()
63+
}
64+
65+
managedPrefixLists.push(...prefixLists)
66+
67+
logger.debug(lt.fetchedManagedPrefixLists(prefixLists.length))
68+
69+
if (nextToken) {
70+
listManagedPrefixLists(nextToken)
71+
} else {
72+
resolve(managedPrefixLists)
73+
}
74+
}
75+
)
76+
} catch (error) {
77+
resolve([])
78+
}
79+
}
80+
listManagedPrefixLists()
81+
})
82+
83+
const getManagedPrefixListEntries = async ({
84+
ec2,
85+
prefixListId,
86+
resolveEntry,
87+
}: {
88+
ec2: EC2
89+
prefixListId: string
90+
resolveEntry: () => void
91+
}): Promise<PrefixListEntry[]> =>
92+
new Promise<PrefixListEntry[]>(resolve => {
93+
const managedPrefixListEntries: PrefixListEntry[] = []
94+
let args: GetManagedPrefixListEntriesRequest = {
95+
PrefixListId: prefixListId,
96+
}
97+
98+
const listManagedPrefixListEntries = (token?: string): void => {
99+
if (token) {
100+
args = { ...args, NextToken: token }
101+
}
102+
try {
103+
ec2.getManagedPrefixListEntries(
104+
args,
105+
(err: AWSError, data: GetManagedPrefixListEntriesResult) => {
106+
if (err) {
107+
errorLog.generateAwsErrorLog({
108+
functionName: 'ec2:getManagedPrefixListEntries',
109+
err,
110+
})
111+
}
112+
113+
if (isEmpty(data)) {
114+
return resolveEntry()
115+
}
116+
117+
const { NextToken: nextToken, Entries: entries = [] } = data
118+
119+
if (isEmpty(entries)) {
120+
return resolveEntry()
121+
}
122+
123+
managedPrefixListEntries.push(...entries)
124+
125+
logger.debug(lt.fetchedManagedPrefixListEntries(entries.length))
126+
127+
if (nextToken) {
128+
listManagedPrefixListEntries(nextToken)
129+
} else {
130+
resolve(managedPrefixListEntries)
131+
}
132+
}
133+
)
134+
} catch (error) {
135+
resolve([])
136+
}
137+
}
138+
listManagedPrefixListEntries()
139+
})
140+
141+
/**
142+
* Managed Prefix List
143+
*/
144+
145+
export interface RawAwsManagedPrefixList
146+
extends Omit<ManagedPrefixList, 'Tags'> {
147+
region: string
148+
Tags?: TagMap
149+
Entries?: PrefixListEntry[]
150+
}
151+
152+
export default async ({
153+
regions,
154+
config,
155+
}: {
156+
regions: string
157+
config: Config
158+
}): Promise<{
159+
[region: string]: RawAwsManagedPrefixList[]
160+
}> =>
161+
new Promise(async resolve => {
162+
const managedPrefixListsResult: RawAwsManagedPrefixList[] = []
163+
const entriesPromises = []
164+
165+
const regionPromises = regions.split(',').map(region => {
166+
const ec2 = new EC2({ ...config, region, endpoint })
167+
168+
return new Promise<void>(async resolveRegion => {
169+
const managedPrefixLists = await listManagedPrefixListData({
170+
ec2,
171+
resolveRegion,
172+
})
173+
174+
if (!isEmpty(managedPrefixLists)) {
175+
for (const managedPrefixList of managedPrefixLists) {
176+
managedPrefixListsResult.push({
177+
...managedPrefixList,
178+
region,
179+
Tags: convertAwsTagsToTagMap(managedPrefixList.Tags as AwsTag[]),
180+
})
181+
}
182+
}
183+
resolveRegion()
184+
})
185+
})
186+
await Promise.all(regionPromises)
187+
188+
managedPrefixListsResult.map(
189+
({ PrefixListId: prefixListId, region }, idx) => {
190+
const ec2 = new EC2({ ...config, region, endpoint })
191+
const entryPromise = new Promise<void>(async resolveEntry => {
192+
const entries: PrefixListEntry[] =
193+
await getManagedPrefixListEntries({
194+
ec2,
195+
prefixListId,
196+
resolveEntry,
197+
})
198+
managedPrefixListsResult[idx] = {
199+
...managedPrefixListsResult[idx],
200+
Entries: entries || [],
201+
}
202+
resolveEntry()
203+
})
204+
entriesPromises.push(entryPromise)
205+
}
206+
)
207+
await Promise.all(entriesPromises)
208+
209+
errorLog.reset()
210+
resolve(groupBy(managedPrefixListsResult, 'region'))
211+
})
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import cuid from 'cuid'
2+
import { formatTagsFromMap } from '../../utils/format'
3+
import { RawAwsManagedPrefixList } from './data'
4+
import { AwsManagedPrefixList } from '../../types/generated'
5+
6+
/**
7+
* Managed Prefix List
8+
*/
9+
10+
export default ({
11+
service: rawData,
12+
account,
13+
region,
14+
}: {
15+
service: RawAwsManagedPrefixList
16+
account: string
17+
region: string
18+
}): AwsManagedPrefixList => {
19+
const {
20+
PrefixListId: id,
21+
PrefixListArn: arn,
22+
PrefixListName: name,
23+
AddressFamily: addressFamily,
24+
State: state,
25+
StateMessage: stateMessage,
26+
MaxEntries: maxEntries,
27+
Version: version,
28+
Entries: entries = [],
29+
Tags: tags,
30+
} = rawData
31+
32+
const managedPrefixList = {
33+
id,
34+
accountId: account,
35+
arn,
36+
region,
37+
name,
38+
addressFamily,
39+
state,
40+
stateMessage,
41+
maxEntries,
42+
version,
43+
entries: entries?.map(e => ({
44+
id: cuid(),
45+
cidr: e.Cidr,
46+
description: e.Description,
47+
})) || [],
48+
tags: formatTagsFromMap(tags),
49+
}
50+
51+
return managedPrefixList
52+
}
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 ManagedPrefixList extends BaseService implements Service {
8+
format = format.bind(this)
9+
10+
getData = getData.bind(this)
11+
12+
mutation = mutation
13+
}

0 commit comments

Comments
 (0)