-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aws - appsync resource and waf filter/action (#7872)
- Loading branch information
Showing
14 changed files
with
599 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
# Copyright The Cloud Custodian Authors. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
import re | ||
|
||
from c7n.actions import BaseAction | ||
from c7n.filters import Filter | ||
from c7n.manager import resources | ||
from c7n.query import QueryResourceManager, TypeInfo | ||
from c7n.utils import local_session, type_schema, get_retry | ||
|
||
|
||
@resources.register('graphql-api') | ||
class GraphQLApi(QueryResourceManager): | ||
"""Resource Manager for AppSync GraphQLApi | ||
""" | ||
class resource_type(TypeInfo): | ||
service = 'appsync' | ||
enum_spec = ('list_graphql_apis', 'graphqlApis', {'maxResults': 25}) | ||
id = 'apiId' | ||
name = 'name' | ||
cfn_type = 'AWS::AppSync::GraphQLApi' | ||
arn_type = 'apis' | ||
arn = 'arn' | ||
universal_taggable = True | ||
|
||
|
||
@GraphQLApi.filter_registry.register('wafv2-enabled') | ||
class WafV2Enabled(Filter): | ||
"""Filter AppSync GraphQLApi by wafv2 web-acl | ||
:example: | ||
.. code-block:: yaml | ||
policies: | ||
- name: filter-graphql-api-wafv2 | ||
resource: graphql-api | ||
filters: | ||
- type: wafv2-enabled | ||
state: false | ||
web-acl: test-waf-v2 | ||
- name: filter-graphql-api-wafv2-regex | ||
resource: graphql-api | ||
filters: | ||
- type: wafv2-enabled | ||
state: false | ||
web-acl: .*FMManagedWebACLV2-?FMS-.* | ||
""" | ||
|
||
schema = type_schema( | ||
'wafv2-enabled', **{ | ||
'web-acl': {'type': 'string'}, | ||
'state': {'type': 'boolean'}}) | ||
|
||
permissions = ('wafv2:ListWebACLs',) | ||
|
||
def process(self, resources, event=None): | ||
wafs = self.manager.get_resource_manager('wafv2').resources(augment=False) | ||
waf_name_id_map = {w['Name']: w['ARN'] for w in wafs} | ||
|
||
target_acl = self.data.get('web-acl', '') | ||
state = self.data.get('state', False) | ||
target_acl_ids = [v for k, v in waf_name_id_map.items() if | ||
re.match(target_acl, k)] | ||
|
||
results = [] | ||
for r in resources: | ||
r_web_acl_id = r.get('wafWebAclArn') | ||
if state: | ||
if not target_acl and r_web_acl_id: | ||
results.append(r) | ||
elif target_acl and r_web_acl_id in target_acl_ids: | ||
results.append(r) | ||
else: | ||
if not target_acl and not r_web_acl_id: | ||
results.append(r) | ||
elif target_acl and r_web_acl_id not in target_acl_ids: | ||
results.append(r) | ||
return results | ||
|
||
|
||
@GraphQLApi.action_registry.register('set-wafv2') | ||
class SetWafv2(BaseAction): | ||
"""Enable wafv2 protection on AppSync graphqlApi. | ||
:example: | ||
.. code-block:: yaml | ||
policies: | ||
- name: set-wafv2-for-graphql-api | ||
resource: graphql-api | ||
filters: | ||
- type: wafv2-enabled | ||
state: false | ||
web-acl: test-waf-v2 | ||
actions: | ||
- type: set-wafv2 | ||
state: true | ||
force: true | ||
web-acl: test-waf-v2 | ||
- name: unset-wafv2-for-graphql-api | ||
resource: graphql-api | ||
filters: | ||
- type: wafv2-enabled | ||
state: true | ||
actions: | ||
- type: set-wafv2 | ||
state: true | ||
force: true | ||
web-acl: test-waf-v2 | ||
policies: | ||
- name: set-wafv2-for-graphql-api-regex | ||
resource: graphql-api | ||
filters: | ||
- type: wafv2-enabled | ||
state: false | ||
web-acl: .*FMManagedWebACLV2-?FMS-.* | ||
actions: | ||
- type: set-wafv2 | ||
state: true | ||
force: true | ||
web-acl: FMManagedWebACLV2-?FMS-TestWebACL | ||
""" | ||
permissions = ('wafv2:AssociateWebACL', | ||
'wafv2:DisassociateWebACL', | ||
'wafv2:ListWebACLs') | ||
|
||
schema = type_schema( | ||
'set-wafv2', **{ | ||
'web-acl': {'type': 'string'}, | ||
'force': {'type': 'boolean'}, | ||
'state': {'type': 'boolean'}}) | ||
|
||
retry = staticmethod(get_retry(( | ||
'ThrottlingException', | ||
'RequestLimitExceeded', | ||
'Throttled', | ||
'ThrottledException', | ||
'Throttling', | ||
'Client.RequestLimitExceeded'))) | ||
|
||
def process(self, resources): | ||
wafs = self.manager.get_resource_manager('wafv2').resources(augment=False) | ||
waf_name_id_map = {w['Name']: w['ARN'] for w in wafs} | ||
state = self.data.get('state', True) | ||
|
||
target_acl_id = '' | ||
if state: | ||
target_acl = self.data.get('web-acl', '') | ||
target_acl_ids = [v for k, v in waf_name_id_map.items() if | ||
re.match(target_acl, k)] | ||
if len(target_acl_ids) != 1: | ||
raise ValueError(f'{target_acl} matching to none or ' | ||
f'multiple webacls') | ||
target_acl_id = target_acl_ids[0] | ||
|
||
client = local_session(self.manager.session_factory).client('wafv2') | ||
force = self.data.get('force', False) | ||
|
||
arn_key = self.manager.resource_type.arn | ||
|
||
for r in resources: | ||
if r.get('wafWebAclArn') and not force: | ||
continue | ||
if r.get('wafWebAclArn') == target_acl_id: | ||
continue | ||
if state: | ||
self.retry(client.associate_web_acl, | ||
WebACLArn=target_acl_id, | ||
ResourceArn=r[arn_key]) | ||
else: | ||
self.retry(client.disassociate_web_acl, | ||
ResourceArn=r[arn_key]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
tests/data/placebo/test_graphql_api_action_wafv2/appsync.ListGraphqlApis_1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
{ | ||
"status_code": 200, | ||
"data": { | ||
"graphqlApis": [ | ||
{ | ||
"name": "My AppSync Api1", | ||
"apiId": "lopd6grtrnctrfi7g7ywvfkzta", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678912:apis/lopd6grtrnctrfi7g7ywvfkzta", | ||
"uris": { | ||
"REALTIME": "wss://az5joslekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://az5joslekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false, | ||
"wafWebAclArn": "arn:aws:wafv2:us-east-1:012345678912:regional/webacl/FMManagedWebACLV2-FMS-TEST-1656966584517/96494e83-ee49-4505-9f68-9103c6cd9406" | ||
}, | ||
{ | ||
"name": "My AppSync Api2", | ||
"apiId": "mlpaw0grtrnctrfi7g7ywvfk908", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678912:apis/mlpaw0grtrnctrfi7g7ywvfk908", | ||
"uris": { | ||
"REALTIME": "wss://kslwp0lekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://kslwp0lekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false | ||
}, | ||
{ | ||
"name": "My AppSync Api3", | ||
"apiId": "p012w0grtrnctrfi7g7ywvf4y67", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678912:apis/p012w0grtrnctrfi7g7ywvf4y67", | ||
"uris": { | ||
"REALTIME": "wss://pqlap0lekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://pqlap0lekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false, | ||
"wafWebAclArn": "arn:aws:wafv2:us-east-1:012345678912:regional/webacl/WebACL_TESTv2/887bbaec-c70b-4884-b290-ec7c7b5a43kl" | ||
} | ||
] | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/data/placebo/test_graphql_api_action_wafv2/wafv2.AssociateWebACL_1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"status_code": 200, | ||
"data": { | ||
"ResponseMetadata": {} | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/data/placebo/test_graphql_api_action_wafv2/wafv2.DisassociateWebACL_1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"status_code": 200, | ||
"data": { | ||
"ResponseMetadata": {} | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
tests/data/placebo/test_graphql_api_action_wafv2/wafv2.ListWebACLs_1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"status_code": 200, | ||
"data": { | ||
"NextMarker": "1ebe0b46-0fd2-4e07-a74c-27bf25adc0bf", | ||
"ResponseMetadata": { | ||
"RetryAttempts": 0, | ||
"HTTPStatusCode": 200, | ||
"RequestId": "05ff3012-a9c9-11e7-8af9-c510054683ae", | ||
"HTTPHeaders": { | ||
"x-amzn-requestid": "05ff3012-a9c9-11e7-8af9-c510054683ae", | ||
"date": "Thu, 05 Oct 2017 12:30:50 GMT", | ||
"content-length": "131", | ||
"content-type": "application/x-amz-json-1.1" | ||
} | ||
}, | ||
"WebACLs": [ | ||
{ | ||
"Id": "96494e83-ee49-4505-9f68-9103c6cd9406", | ||
"Name": "FMManagedWebACLV2-FMS-TEST-1656966584517", | ||
"ARN": "arn:aws:wafv2:us-east-1:012345678912:regional/webacl/FMManagedWebACLV2-FMS-TEST-1656966584517/96494e83-ee49-4505-9f68-9103c6cd9406" | ||
} | ||
] | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
.../test_graphql_api_action_wafv2_regex_multiple_webacl_match/appsync.ListGraphqlApis_1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
{ | ||
"status_code": 200, | ||
"data": { | ||
"graphqlApis": [ | ||
{ | ||
"name": "My AppSync Api1", | ||
"apiId": "lopd6grtrnctrfi7g7ywvfkzta", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678901:apis/lopd6grtrnctrfi7g7ywvfkzta", | ||
"uris": { | ||
"REALTIME": "wss://az5joslekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://az5joslekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false, | ||
"wafWebAclArn": "arn:aws:wafv2:us-east-1:012345678912:regional/webacl/FMManagedWebACLV2-FMS-TEST-1656966584517/96494e83-ee49-4505-9f68-9103c6cd9406" | ||
}, | ||
{ | ||
"name": "My AppSync Api2", | ||
"apiId": "mlpaw0grtrnctrfi7g7ywvfk908", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678901:apis/mlpaw0grtrnctrfi7g7ywvfk908", | ||
"uris": { | ||
"REALTIME": "wss://kslwp0lekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://kslwp0lekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false | ||
}, | ||
{ | ||
"name": "My AppSync Api3", | ||
"apiId": "p012w0grtrnctrfi7g7ywvf4y67", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678901:apis/p012w0grtrnctrfi7g7ywvf4y67", | ||
"uris": { | ||
"REALTIME": "wss://pqlap0lekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://pqlap0lekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false, | ||
"wafWebAclArn": "arn:aws:wafv2:us-east-1:012345678901:regional/webacl/WebACL_TESTv2/887bbaec-c70b-4884-b290-ec7c7b5a43kl" | ||
} | ||
] | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...lacebo/test_graphql_api_action_wafv2_regex_multiple_webacl_match/wafv2.ListWebACLs_1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"status_code": 200, | ||
"data": { | ||
"NextMarker": "791f9fc9-16bb-4d32-8f6a-b55e9b6f11c8", | ||
"WebACLs": [ | ||
{ | ||
"Id": "96494e83-ee49-4505-9f68-9103c6cd9406", | ||
"Name": "FMManagedWebACLV2-FMS-TEST-1656966584517", | ||
"ARN": "arn:aws:wafv2:us-east-1:123456789123:regional/webacl/FMManagedWebACLV2-FMS-TEST-1656966584517/96494e83-ee49-4505-9f68-9103c6cd9406" | ||
}, | ||
{ | ||
"Id": "3c5f3db9-04c1-47f4-a6ab-23b70a3a8509", | ||
"Name": "FMManagedWebACLV2-FMS-TEST2-1656966576062", | ||
"ARN": "arn:aws:wafv2:us-east-1:123456789123:regional/webacl/FMManagedWebACLV2-FMS-TEST2-1656966576062/3c5f3db9-04c1-47f4-a6ab-23b70a3a8509" | ||
} | ||
], | ||
"ResponseMetadata": {} | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
tests/data/placebo/test_graphql_api_filter_wafv2/appsync.ListGraphqlApis_1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
{ | ||
"status_code": 200, | ||
"data": { | ||
"graphqlApis": [ | ||
{ | ||
"name": "My AppSync Api1", | ||
"apiId": "lopd6grtrnctrfi7g7ywvfkzta", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678901:apis/lopd6grtrnctrfi7g7ywvfkzta", | ||
"uris": { | ||
"REALTIME": "wss://az5joslekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://az5joslekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false, | ||
"wafWebAclArn": "arn:aws:wafv2:us-east-1:012345678912:regional/webacl/FMManagedWebACLV2-FMS-TEST-1656966584517/96494e83-ee49-4505-9f68-9103c6cd9406" | ||
}, | ||
{ | ||
"name": "My AppSync Api2", | ||
"apiId": "mlpaw0grtrnctrfi7g7ywvfk908", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678901:apis/mlpaw0grtrnctrfi7g7ywvfk908", | ||
"uris": { | ||
"REALTIME": "wss://kslwp0lekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://kslwp0lekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false | ||
}, | ||
{ | ||
"name": "My AppSync Api3", | ||
"apiId": "p012w0grtrnctrfi7g7ywvf4y67", | ||
"authenticationType": "API_KEY", | ||
"arn": "arn:aws:appsync:us-east-1:012345678901:apis/p012w0grtrnctrfi7g7ywvf4y67", | ||
"uris": { | ||
"REALTIME": "wss://pqlap0lekdcedka43ordq3fcvq.appsync-realtime-api.us-east-1.amazonaws.com/graphql", | ||
"GRAPHQL": "https://pqlap0lekdcedka43ordq3fcvq.appsync-api.us-east-1.amazonaws.com/graphql" | ||
}, | ||
"tags": { | ||
"waf": "test" | ||
}, | ||
"xrayEnabled": false, | ||
"wafWebAclArn": "arn:aws:wafv2:us-east-1:012345678901:regional/webacl/WebACL_TESTv2/887bbaec-c70b-4884-b290-ec7c7b5a43kl" | ||
} | ||
] | ||
} | ||
} |
Oops, something went wrong.