Skip to content

Commit 074956d

Browse files
authored
Merge pull request #152 from cloudgraphdev/feat/EP-3201
feat: add efs missing services
2 parents 18d0c3b + ef37753 commit 074956d

File tree

15 files changed

+246
-10
lines changed

15 files changed

+246
-10
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
111111
| ecsTaskDefinition | ecsService, ecsTask, ecsTaskSet, iamRole |
112112
| ecsTaskSet | ecsCluster, ecsService, ecsTaskDefinition |
113113
| efs | kms |
114+
| efsAccessPoint | |
114115
| efsMountTarget | networkInterface, subnet, vpc |
115116
| eip | ec2, networkInterface, vpc |
116117
| eksCluster | ec2, iamRole, kms, securityGroup, subnet, vpc |

src/enums/serviceAliases.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export default {
3333
[services.ecsTask]: 'ecsTasks',
3434
[services.ecsTaskDefinition]: 'ecsTaskDefinitions',
3535
[services.ecsTaskSet]: 'ecsTaskSets',
36+
[services.efsAccessPoint]: 'efsAccessPoints',
3637
[services.eksCluster]: 'eksClusters',
3738
[services.elastiCacheCluster]: 'elastiCacheClusters',
3839
[services.elastiCacheReplicationGroup]: 'elastiCacheReplicationGroups',

src/enums/serviceMap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import EcsTask from '../services/ecsTask'
4343
import EcsTaskDefinition from '../services/ecsTaskDefinition'
4444
import EcsTaskSet from '../services/ecsTaskSet'
4545
import EFS from '../services/efs'
46+
import EfsAccessPoint from '../services/efsAccessPoint'
4647
import EfsMountTarget from '../services/efsMountTarget'
4748
import EIP from '../services/eip'
4849
import EKSCluster from '../services/eksCluster'
@@ -165,6 +166,7 @@ export default {
165166
[services.ec2Instance]: EC2,
166167
[services.ecr]: ECR,
167168
[services.efs]: EFS,
169+
[services.efsAccessPoint]: EfsAccessPoint,
168170
[services.efsMountTarget]: EfsMountTarget,
169171
[services.eip]: EIP,
170172
[services.eksCluster]: EKSCluster,

src/enums/services.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export default {
4343
ecsTaskDefinition: 'ecsTaskDefinition',
4444
ecsTaskSet: 'ecsTaskSet',
4545
efs: 'efs',
46+
efsAccessPoint: 'efsAccessPoint',
4647
efsMountTarget: 'efsMountTarget',
4748
eip: 'eip',
4849
eksCluster: 'eksCluster',

src/properties/logger.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ export default {
360360
`Found ${num} EFS Mount Targets, adding them to the subnet`,
361361
doneFetchingEfsData: '✅ Done fetching EFS Data ✅',
362362
fetchedEfs: (num: number): string => `Fetched ${num} EFS`,
363+
fetchedEfsAccessPoints: (num: number): string =>
364+
`Fetched ${num} EFS Access Points`,
363365
fetchedEfsMountTargets: (num: number): string =>
364366
`Fetched ${num} EFS Mount Targets`,
365367
fetchedEfsMountTargetSecurityGroups: (num: number): string =>

src/services/account/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type awsAccount implements awsOptionalService @key(fields: "id") {
4040
ecsTaskDefinitions: [awsEcsTaskDefinition]
4141
ecsTaskSets: [awsEcsTaskSet]
4242
efs: [awsEfs]
43+
efsAccessPoint: [awsEfsAccessPoint]
4344
efsMountTarget: [awsEfsMountTarget]
4445
eip: [awsEip]
4546
eksClusters: [awsEksCluster]

src/services/efs/data.ts

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import EFS, {
33
FileSystemDescription,
44
DescribeFileSystemsRequest,
55
DescribeFileSystemsResponse,
6+
DescribeFileSystemPolicyRequest,
7+
FileSystemPolicyDescription,
8+
Policy,
69
} from 'aws-sdk/clients/efs'
710
import { AWSError } from 'aws-sdk/lib/error'
811
import CloudGraph from '@cloudgraph/sdk'
@@ -20,6 +23,42 @@ const serviceName = 'EFS'
2023
const errorLog = new AwsErrorLog(serviceName)
2124
const endpoint = initTestEndpoint(serviceName)
2225

26+
const getFileSystemPolicy = async ({
27+
efs,
28+
FileSystemId,
29+
}: {
30+
efs: EFS
31+
FileSystemId: string
32+
}): Promise<Policy> =>
33+
new Promise<Policy>(resolve => {
34+
const args: DescribeFileSystemPolicyRequest = { FileSystemId }
35+
try {
36+
efs.describeFileSystemPolicy(
37+
args,
38+
(err: AWSError, data: FileSystemPolicyDescription) => {
39+
if (err) {
40+
errorLog.generateAwsErrorLog({
41+
functionName: 'efs:describeFileSystemPolicy',
42+
err,
43+
})
44+
}
45+
46+
/**
47+
* No policy for this file system
48+
*/
49+
if (isEmpty(data)) {
50+
return resolve('')
51+
}
52+
53+
const { Policy: policy } = data
54+
resolve(policy)
55+
}
56+
)
57+
} catch (error) {
58+
resolve('')
59+
}
60+
})
61+
2362
const listFileSystems = async ({
2463
efs,
2564
region,
@@ -29,7 +68,7 @@ const listFileSystems = async ({
2968
efs: EFS
3069
region: string
3170
token?: string
32-
resolveRegion: Function
71+
resolveRegion: () => void
3372
}): Promise<FileSystemDescription[]> =>
3473
new Promise<FileSystemDescription[]>(resolve => {
3574
const efsList: FileSystemDescription[] = []
@@ -57,10 +96,7 @@ const listFileSystems = async ({
5796
return resolveRegion()
5897
}
5998

60-
const {
61-
FileSystems: fileSystems = [],
62-
NextMarker: token,
63-
}: { FileSystems?: any; NextMarker?: any } = data
99+
const { FileSystems: fileSystems = [], NextMarker: token } = data
64100

65101
efsList.push(...fileSystems)
66102

@@ -100,6 +136,7 @@ const listFileSystems = async ({
100136

101137
export interface RawAwsEfs extends Omit<FileSystemDescription, 'Tags'> {
102138
region: string
139+
policy: Policy
103140
Tags?: TagMap
104141
}
105142

@@ -115,21 +152,23 @@ export default async ({
115152
new Promise(async resolve => {
116153
const efsFileSystems: RawAwsEfs[] = []
117154
const regionPromises = []
155+
const policyPromises = []
118156

119157
/**
120158
* Get all the EFS File Systems
121159
*/
122160

123-
regions.split(',').map(region => {
161+
regions.split(',').forEach(region => {
124162
const efs = new EFS({ ...config, region, endpoint })
125163
const regionPromise = new Promise<void>(async resolveRegion => {
126164
const efsList = await listFileSystems({ efs, region, resolveRegion })
127165
if (!isEmpty(efsList)) {
128166
efsFileSystems.push(
129-
...efsList.map(efs => ({
130-
...efs,
167+
...efsList.map(efsItem => ({
168+
...efsItem,
131169
region,
132-
Tags: convertAwsTagsToTagMap(efs.Tags),
170+
policy: '',
171+
Tags: convertAwsTagsToTagMap(efsItem.Tags),
133172
}))
134173
)
135174
}
@@ -139,6 +178,21 @@ export default async ({
139178
})
140179

141180
await Promise.all(regionPromises)
181+
182+
// get policy for each rest api
183+
efsFileSystems.forEach(({ FileSystemId: id, region }, idx) => {
184+
const efs = new EFS({ ...config, region, endpoint })
185+
const modelPromise = new Promise<void>(async resolvePolicy => {
186+
efsFileSystems[idx].policy = await getFileSystemPolicy({
187+
efs,
188+
FileSystemId: id,
189+
})
190+
resolvePolicy()
191+
})
192+
policyPromises.push(modelPromise)
193+
})
194+
await Promise.all(policyPromises)
195+
142196
errorLog.reset()
143197

144198
resolve(groupBy(efsFileSystems, 'region'))

src/services/efs/format.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export default ({
2727
ProvisionedThroughputInMibps: provisionedThroughputInMibps,
2828
AvailabilityZoneName: availabilityZoneName,
2929
AvailabilityZoneId: availabilityZoneId,
30+
policy,
3031
Tags,
3132
} = service
3233

@@ -46,14 +47,15 @@ export default ({
4647
value: sizeInBytes?.Value,
4748
timestamp: sizeInBytes?.Timestamp?.toISOString(),
4849
valueInIA: sizeInBytes?.ValueInIA,
49-
valueInStandard: sizeInBytes?.ValueInStandard
50+
valueInStandard: sizeInBytes?.ValueInStandard,
5051
},
5152
performanceMode,
5253
encrypted,
5354
throughputMode,
5455
provisionedThroughputInMibps,
5556
availabilityZoneName,
5657
availabilityZoneId,
58+
policy,
5759
tags: formatTagsFromMap(Tags),
5860
}
5961
}

src/services/efs/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type awsEfs implements awsBaseService @key(fields: "arn") {
1616
tags: [awsRawTag]
1717
efsMountTarget: [awsEfsMountTarget] @hasInverse(field: efs) #change to plural
1818
kms: [awsKms] @hasInverse(field: efs)
19+
policy: String
1920
}
2021

2122
type awsEfsFileSystemSize
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { Config } from 'aws-sdk'
2+
import EFS, {
3+
DescribeAccessPointsResponse,
4+
DescribeAccessPointsRequest,
5+
AccessPointDescription,
6+
} from 'aws-sdk/clients/efs'
7+
import { AWSError } from 'aws-sdk/lib/error'
8+
import CloudGraph from '@cloudgraph/sdk'
9+
import groupBy from 'lodash/groupBy'
10+
import isEmpty from 'lodash/isEmpty'
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 = 'EFS Access Point'
18+
const errorLog = new AwsErrorLog(serviceName)
19+
const endpoint = initTestEndpoint(serviceName)
20+
21+
export interface RawAwsEfsAccessPoint extends AccessPointDescription {
22+
region: string
23+
}
24+
25+
const listAccessPoint = async ({
26+
efs,
27+
}: {
28+
efs: EFS
29+
}): Promise<AccessPointDescription[]> =>
30+
new Promise<AccessPointDescription[]>(resolve => {
31+
const accessPointList: AccessPointDescription[] = []
32+
const args: DescribeAccessPointsRequest = {}
33+
const listAllAccessPoints = (token?: string): void => {
34+
if (token) {
35+
args.NextToken = token
36+
}
37+
38+
try {
39+
efs.describeAccessPoints(
40+
args,
41+
(err: AWSError, data: DescribeAccessPointsResponse) => {
42+
if (err) {
43+
errorLog.generateAwsErrorLog({
44+
functionName: 'efs:describeAccessPoints',
45+
err,
46+
})
47+
}
48+
49+
/**
50+
* No EFS access point data for this region
51+
*/
52+
if (isEmpty(data)) {
53+
return resolve([])
54+
}
55+
56+
const { AccessPoints: accessPoints = [], NextToken: nextToken } =
57+
data
58+
59+
accessPointList.push(...accessPoints)
60+
61+
/**
62+
* Check to see if there are more
63+
*/
64+
65+
if (nextToken) {
66+
listAllAccessPoints(nextToken)
67+
} else {
68+
resolve(accessPointList)
69+
}
70+
}
71+
)
72+
} catch (error) {
73+
resolve([])
74+
}
75+
}
76+
listAllAccessPoints()
77+
})
78+
79+
export default async ({
80+
regions,
81+
config,
82+
}: {
83+
regions: string
84+
config: Config
85+
}): Promise<{
86+
[region: string]: RawAwsEfsAccessPoint[]
87+
}> =>
88+
new Promise(async resolve => {
89+
const efsAccessPoints: RawAwsEfsAccessPoint[] = []
90+
const regionPromises = []
91+
92+
/**
93+
* Get all the EFS Access points
94+
*/
95+
96+
regions.split(',').forEach(region => {
97+
const efs = new EFS({ ...config, region, endpoint })
98+
const regionPromise = new Promise<void>(async resolveRegion => {
99+
const accessPointList = await listAccessPoint({ efs })
100+
if (!isEmpty(accessPointList)) {
101+
efsAccessPoints.push(
102+
...accessPointList.map(accessPoint => ({
103+
...accessPoint,
104+
region,
105+
}))
106+
)
107+
}
108+
resolveRegion()
109+
})
110+
regionPromises.push(regionPromise)
111+
})
112+
113+
await Promise.all(regionPromises)
114+
logger.debug(lt.fetchedEfsAccessPoints(efsAccessPoints.length))
115+
errorLog.reset()
116+
117+
resolve(groupBy(efsAccessPoints, 'region'))
118+
})

0 commit comments

Comments
 (0)