Skip to content

Commit 0038fbc

Browse files
committed
Merge branch 'feature/CG-820' into 'master'
Resolve CG-820 WAFV2 Closes CG-820 See merge request auto-cloud/cloudgraph/provider/cloudgraph-provider-aws!209
2 parents d35e06d + 9df5d38 commit 0038fbc

14 files changed

Lines changed: 1161 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,5 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
151151
| vpc | alb, codebuild, ec2, eip, elb, ecsService, efsMountTarget, eksCluster igw, elastiCacheCluster, lambda, nacl, natGateway, networkInterface, rdsDbInstance, redshiftCluster, route53HostedZone, routeTable, subnet, flowLog, vpnGateway, transitGatewayAttachment |
152152
| vpnConnection | customerGateway, transitGateway, transitGatewayAttachment, vpnGateway |
153153
| vpnGateway | vpc, vpnConnection |
154+
| wafV2WebAcl | |
154155

src/enums/schemasMap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,6 @@ export default {
8989
[services.transitGatewayAttachment]: 'awsTransitGatewayAttachment',
9090
[services.vpnConnection]: 'awsVpnConnection',
9191
[services.organization]: 'awsOrganization',
92+
[services.wafV2WebAcl]: 'awsWafV2WebAcl',
9293
tag: 'awsTag',
9394
}

src/enums/serviceMap.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ import GlueRegistry from '../services/glueRegistry'
8585
import SageMakerProject from '../services/sageMakerProject'
8686
import SageMakerExperiment from '../services/sageMakerExperiment'
8787
import ManagedAirflow from '../services/managedAirflow'
88+
import WafV2WebAcl from '../services/wafV2WebAcl'
8889

8990
/**
9091
* serviceMap is an object that contains all currently supported services for AWS
@@ -176,5 +177,6 @@ export default {
176177
[services.vpnGateway]: VpnGateway,
177178
[services.vpnConnection]: VpnConnection,
178179
[services.organization]: Organization,
180+
[services.wafV2WebAcl]: WafV2WebAcl,
179181
tag: AwsTag,
180182
}

src/enums/services.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,5 @@ export default {
8484
vpc: 'vpc',
8585
vpnConnection: 'vpnConnection',
8686
vpnGateway: 'vpnGateway',
87+
wafV2WebAcl: 'wafV2WebAcl'
8788
}

src/services/managedAirflow/format.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,15 @@ export default ({
2323
Arn: arn,
2424
CreatedAt: createdAt,
2525
DagS3Path: dagS3Path,
26+
KmsKey,
2627
EnvironmentClass: environmentClass,
2728
ExecutionRoleArn: executionRoleArn,
2829
LastUpdate: {
2930
CreatedAt: lastUpdateCreatedAt,
31+
Error: {
32+
ErrorCode: errorCode,
33+
ErrorMessage: errorMessage
34+
} = {},
3035
Status: lastUpdateStatus,
3136
} = {},
3237
LoggingConfiguration: {
@@ -90,13 +95,18 @@ export default ({
9095
accountId: account,
9196
airflowConfigurationOptions: mappedAirflowConfigurationOptions,
9297
airflowVersion,
98+
kmsKey: KmsKey,
9399
createdAt: createdAt?.toISOString(),
94100
dagS3Path,
95101
environmentClass,
96102
executionRoleArn,
97103
lastUpdate: {
98104
createdAt: lastUpdateCreatedAt?.toISOString(),
99105
status: lastUpdateStatus,
106+
error: {
107+
errorCode,
108+
errorMessage
109+
}
100110
},
101111
loggingConfiguration: {
102112
dagProcessingLogs: {

src/services/managedAirflow/schema.graphql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type awsManagedAirflow @key(fields: "arn") {
55
region: String @search(by: [hash, regexp])
66
airflowConfigurationOptions: [awsRawTag]
77
airflowVersion: String @search(by: [hash, regexp])
8+
kmsKey: String @search(by: [hash, regexp])
89
createdAt: DateTime
910
dagS3Path: String @search(by: [hash, regexp])
1011
environmentClass: String @search(by: [hash, regexp])
@@ -38,9 +39,15 @@ type awsManagedAirflow @key(fields: "arn") {
3839

3940
type awsManagedAirflowLastUpdate {
4041
createdAt: DateTime
42+
error: awsManagedAirflowLastUpdateError
4143
status: String @search(by: [hash, regexp])
4244
}
4345

46+
type awsManagedAirflowLastUpdateError {
47+
errorCode: String @search(by: [hash, regexp])
48+
errorMessage: String @search(by: [hash, regexp])
49+
}
50+
4451
type awsManagedAirflowLoggingConfig {
4552
dagProcessingLogs: awsManagedAirflowLogging
4653
schedulerLogs: awsManagedAirflowLogging

src/services/wafV2WebAcl/data.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { Config } from 'aws-sdk/lib/config'
2+
import WAFV2, { WebACLSummaries } from 'aws-sdk/clients/wafv2'
3+
import isEmpty from 'lodash/isEmpty'
4+
import groupBy from 'lodash/groupBy'
5+
import { initTestEndpoint } from '../../utils'
6+
import ErrorLog from '../../utils/errorLog'
7+
8+
const serviceName = 'wafV2WebAcl'
9+
const errorLog = new ErrorLog(serviceName)
10+
const endpoint = initTestEndpoint(serviceName)
11+
12+
const scopes = {
13+
cloudfront: 'CLOUDFRONT',
14+
regional: 'REGIONAL',
15+
}
16+
17+
export interface RawAwsWafV2WebAcl extends WAFV2.WebACL {
18+
region: string
19+
loggingConfiguration: WAFV2.LoggingConfiguration
20+
}
21+
22+
/**
23+
* WafV2WebAcl
24+
*/
25+
26+
export default async ({
27+
regions,
28+
config,
29+
}: {
30+
regions: string
31+
config: Config
32+
}): Promise<{ [region: string]: RawAwsWafV2WebAcl[] }> => {
33+
const result: RawAwsWafV2WebAcl[] = []
34+
35+
const activeRegions = regions.split(',')
36+
activeRegions.push('global')
37+
for (const region of activeRegions) {
38+
const client = new WAFV2({
39+
...config,
40+
region: region === 'global' ? 'us-east-1' : region,
41+
endpoint,
42+
})
43+
const scope = region === 'global' ? scopes.cloudfront : scopes.regional
44+
const WafV2WebAclData: WebACLSummaries = []
45+
try {
46+
const { WebACLs, NextMarker } = await client
47+
.listWebACLs({ Scope: scope, Limit: 10 })
48+
.promise()
49+
WafV2WebAclData.push(...WebACLs)
50+
let marker = NextMarker
51+
while (marker) {
52+
const { WebACLs, NextMarker } = await client
53+
.listWebACLs({ Scope: scope, Limit: 10, NextMarker: marker })
54+
.promise()
55+
marker = NextMarker
56+
WafV2WebAclData.push(...WebACLs)
57+
}
58+
} catch (err) {
59+
errorLog.generateAwsErrorLog({ functionName: 'listWebAcls', err })
60+
}
61+
if (!isEmpty(WafV2WebAclData)) {
62+
for (const waf of WafV2WebAclData) {
63+
let wafData
64+
try {
65+
wafData = await client
66+
.getWebACL({ Name: waf.Name, Id: waf.Id, Scope: scope })
67+
.promise()
68+
69+
const arn = wafData?.WebACL?.ARN
70+
const loggingConfiguration = await client
71+
.getLoggingConfiguration({ ResourceArn: arn })
72+
.promise()
73+
wafData.loggingConfiguration =
74+
loggingConfiguration.LoggingConfiguration
75+
} catch (err) {
76+
errorLog.generateAwsErrorLog({ functionName: 'getWebACL', err })
77+
}
78+
result.push({
79+
...wafData?.WebACL,
80+
loggingConfiguration: wafData?.loggingConfiguration,
81+
region,
82+
})
83+
}
84+
}
85+
}
86+
errorLog.reset()
87+
return groupBy(result, 'region')
88+
}

src/services/wafV2WebAcl/format.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import cuid from 'cuid'
2+
import {
3+
formatFieldToMatch,
4+
formatRuleLabels,
5+
formatRuleStatement,
6+
formatRuleAction,
7+
formatRuleOverrideAction,
8+
formatDefaultAction,
9+
formatFirewallManagerRuleGroups,
10+
formatVisibilityConfig
11+
} from './utils'
12+
import { AwsWafV2WebAcl } from '../../types/generated'
13+
import { RawAwsWafV2WebAcl } from './data'
14+
15+
/**
16+
* WafV2WebAcl
17+
*/
18+
19+
export default ({
20+
account,
21+
service: rawData,
22+
region,
23+
}: {
24+
account: string
25+
service: RawAwsWafV2WebAcl
26+
region: string
27+
}): AwsWafV2WebAcl => {
28+
const {
29+
Id: id,
30+
ARN: arn,
31+
Name: name,
32+
Description: description,
33+
Rules,
34+
DefaultAction,
35+
Capacity: capacity,
36+
VisibilityConfig,
37+
PreProcessFirewallManagerRuleGroups,
38+
PostProcessFirewallManagerRuleGroups,
39+
ManagedByFirewallManager,
40+
LabelNamespace: labelNamespace,
41+
CustomResponseBodies,
42+
loggingConfiguration,
43+
} = rawData
44+
45+
const mappedRules = Rules?.map(rule => ({
46+
id: cuid(),
47+
name: rule.Name,
48+
priority: rule.Priority,
49+
statement: formatRuleStatement(rule.Statement),
50+
action: formatRuleAction(rule.Action),
51+
overrideAction: formatRuleOverrideAction(rule.OverrideAction),
52+
ruleLabels: formatRuleLabels(rule.RuleLabels),
53+
visibilityConfig: formatVisibilityConfig(rule.VisibilityConfig),
54+
}))
55+
56+
const mappedCustomResponseBodies = Object.keys(
57+
CustomResponseBodies ?? {}
58+
).map(key => ({
59+
id: cuid(),
60+
key,
61+
contentType: CustomResponseBodies[key]?.ContentType,
62+
content: CustomResponseBodies[key]?.Content,
63+
}))
64+
65+
const formattedLoggingConfig = {
66+
resourceArn: loggingConfiguration?.ResourceArn,
67+
logDestinationConfigs: loggingConfiguration?.LogDestinationConfigs,
68+
redactedFields: loggingConfiguration?.RedactedFields?.map(formatFieldToMatch),
69+
managedByFirewallManager: loggingConfiguration?.ManagedByFirewallManager,
70+
loggingFilter: {
71+
filters: loggingConfiguration?.LoggingFilter?.Filters?.map(filter => ({
72+
id: cuid(),
73+
behavior: filter.Behavior,
74+
requirement: filter.Requirement,
75+
conditions: filter.Conditions?.map(condition => ({
76+
id: cuid(),
77+
actionCondtion: {
78+
action: condition?.ActionCondition?.Action,
79+
},
80+
labelNameCondition: {
81+
labelName: condition?.LabelNameCondition?.LabelName,
82+
},
83+
})),
84+
})),
85+
defaultBehavior: loggingConfiguration?.LoggingFilter?.DefaultBehavior
86+
},
87+
}
88+
89+
return {
90+
id,
91+
region,
92+
accountId: account,
93+
arn,
94+
name,
95+
description,
96+
ManagedByFirewallManager,
97+
capacity,
98+
labelNamespace,
99+
rules: mappedRules,
100+
defaultAction: formatDefaultAction(DefaultAction),
101+
visibilityConfig: formatVisibilityConfig(VisibilityConfig),
102+
preProcessFirewallManagerRuleGroups: formatFirewallManagerRuleGroups(
103+
PreProcessFirewallManagerRuleGroups
104+
),
105+
postProcessFirewallManagerRuleGroups: formatFirewallManagerRuleGroups(
106+
PostProcessFirewallManagerRuleGroups
107+
),
108+
customResponseBodies: mappedCustomResponseBodies,
109+
loggingConfiguration: formattedLoggingConfig,
110+
}
111+
}

src/services/wafV2WebAcl/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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 WafV2WebAcl extends BaseService implements Service {
8+
format = format.bind(this)
9+
10+
getData = getData.bind(this)
11+
12+
mutation = mutation
13+
}
14+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default `mutation($input: [AddawsWafV2WebAclInput!]!) {
2+
addawsWafV2WebAcl(input: $input, upsert: true) {
3+
numUids
4+
}
5+
}`;

0 commit comments

Comments
 (0)