Wafv2 initial Implementation
This commit is contained in:
		
							parent
							
								
									bc369679f2
								
							
						
					
					
						commit
						1b7e015e19
					
				| @ -128,6 +128,7 @@ mock_mediastore = lazy_load(".mediastore", "mock_mediastore") | |||||||
| mock_eks = lazy_load(".eks", "mock_eks") | mock_eks = lazy_load(".eks", "mock_eks") | ||||||
| mock_mediastoredata = lazy_load(".mediastoredata", "mock_mediastoredata") | mock_mediastoredata = lazy_load(".mediastoredata", "mock_mediastoredata") | ||||||
| mock_efs = lazy_load(".efs", "mock_efs") | mock_efs = lazy_load(".efs", "mock_efs") | ||||||
|  | mock_wafv2 = lazy_load(".wafv2", "mock_wafv2") | ||||||
| 
 | 
 | ||||||
| # import logging | # import logging | ||||||
| # logging.getLogger('boto').setLevel(logging.CRITICAL) | # logging.getLogger('boto').setLevel(logging.CRITICAL) | ||||||
|  | |||||||
| @ -85,6 +85,7 @@ BACKENDS = { | |||||||
|     "mediastore-data": ("mediastoredata", "mediastoredata_backends"), |     "mediastore-data": ("mediastoredata", "mediastoredata_backends"), | ||||||
|     "eks": ("eks", "eks_backends"), |     "eks": ("eks", "eks_backends"), | ||||||
|     "efs": ("efs", "efs_backends"), |     "efs": ("efs", "efs_backends"), | ||||||
|  |     "wafv2": ("wafv2", "wafv2_backends"), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								moto/wafv2/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								moto/wafv2/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | from __future__ import unicode_literals | ||||||
|  | 
 | ||||||
|  | from .models import wafv2_backends | ||||||
|  | from ..core.models import base_decorator | ||||||
|  | 
 | ||||||
|  | wafv2_backend = wafv2_backends["us-east-1"] | ||||||
|  | mock_wafv2 = base_decorator(wafv2_backends) | ||||||
							
								
								
									
										14
									
								
								moto/wafv2/exceptions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								moto/wafv2/exceptions.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | from __future__ import unicode_literals | ||||||
|  | from moto.core.exceptions import RESTError | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class WAFv2ClientError(RESTError): | ||||||
|  |     code = 400 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class WAFV2DuplicateItemException(WAFv2ClientError): | ||||||
|  |     def __init__(self): | ||||||
|  |         super(WAFV2DuplicateItemException, self).__init__( | ||||||
|  |             "WafV2DuplicateItem", | ||||||
|  |             "AWS WAF could not perform the operation because some resource in your request is a duplicate of an existing one.", | ||||||
|  |         ) | ||||||
							
								
								
									
										130
									
								
								moto/wafv2/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								moto/wafv2/models.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | |||||||
|  | from __future__ import unicode_literals | ||||||
|  | from uuid import uuid4 | ||||||
|  | from boto3 import Session | ||||||
|  | from moto.core import BaseBackend, BaseModel | ||||||
|  | from moto.wafv2 import utils | ||||||
|  | 
 | ||||||
|  | # from moto.ec2.models import elbv2_backends | ||||||
|  | from .utils import make_arn_for_wacl, pascal_to_underscores_dict | ||||||
|  | from .exceptions import WAFV2DuplicateItemException | ||||||
|  | from moto.core.utils import iso_8601_datetime_with_milliseconds | ||||||
|  | import datetime | ||||||
|  | from collections import OrderedDict | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | US_EAST_1_REGION = "us-east-1" | ||||||
|  | GLOBAL_REGION = "global" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class VisibilityConfig(BaseModel): | ||||||
|  |     """ | ||||||
|  |     https://docs.aws.amazon.com/waf/latest/APIReference/API_VisibilityConfig.html | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__( | ||||||
|  |         self, metric_name, sampled_requests_enabled, cloud_watch_metrics_enabled | ||||||
|  |     ): | ||||||
|  |         self.cloud_watch_metrics_enabled = cloud_watch_metrics_enabled | ||||||
|  |         self.metric_name = metric_name | ||||||
|  |         self.sampled_requests_enabled = sampled_requests_enabled | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DefaultAction(BaseModel): | ||||||
|  |     """ | ||||||
|  |     https://docs.aws.amazon.com/waf/latest/APIReference/API_DefaultAction.html | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, allow={}, block={}): | ||||||
|  |         self.allow = allow | ||||||
|  |         self.block = block | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # TODO: Add remaining properties | ||||||
|  | class FakeWebACL(BaseModel): | ||||||
|  |     """ | ||||||
|  |     https://docs.aws.amazon.com/waf/latest/APIReference/API_WebACL.html | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, name, arn, id, visibility_config, default_action): | ||||||
|  |         self.name = name if name else utils.create_test_name("Mock-WebACL-name") | ||||||
|  |         self.created_time = iso_8601_datetime_with_milliseconds(datetime.datetime.now()) | ||||||
|  |         self.id = id | ||||||
|  |         self.arn = arn | ||||||
|  |         self.description = "Mock WebACL named {0}".format(self.name) | ||||||
|  |         self.capacity = 3 | ||||||
|  |         self.visibility_config = VisibilityConfig( | ||||||
|  |             **pascal_to_underscores_dict(visibility_config) | ||||||
|  |         ) | ||||||
|  |         self.default_action = DefaultAction( | ||||||
|  |             **pascal_to_underscores_dict(default_action) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def to_dict(self): | ||||||
|  |         # Format for summary https://docs.aws.amazon.com/waf/latest/APIReference/API_CreateWebACL.html (response syntax section) | ||||||
|  |         return { | ||||||
|  |             "ARN": self.arn, | ||||||
|  |             "Description": self.description, | ||||||
|  |             "Id": self.id, | ||||||
|  |             "LockToken": "Not Implemented", | ||||||
|  |             "Name": self.name, | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class WAFV2Backend(BaseBackend): | ||||||
|  |     """ | ||||||
|  |     https://docs.aws.amazon.com/waf/latest/APIReference/API_Operations_AWS_WAFV2.html | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __init__(self, region_name=None): | ||||||
|  |         super(WAFV2Backend, self).__init__() | ||||||
|  |         self.region_name = region_name | ||||||
|  |         self.wacls = OrderedDict()  # self.wacls[ARN] = FakeWacl | ||||||
|  |         # TODO: self.load_balancers = OrderedDict() | ||||||
|  | 
 | ||||||
|  |     def reset(self): | ||||||
|  |         region_name = self.region_name | ||||||
|  |         self.__dict__ = {} | ||||||
|  |         self.__init__(region_name) | ||||||
|  | 
 | ||||||
|  |     def create_web_acl(self, name, visibility_config, default_action, scope): | ||||||
|  |         wacl_id = str(uuid4()) | ||||||
|  |         arn = make_arn_for_wacl( | ||||||
|  |             name=name, region_name=self.region_name, id=wacl_id, scope=scope | ||||||
|  |         ) | ||||||
|  |         if arn in self.wacls or self._is_duplicate_name(name): | ||||||
|  |             raise WAFV2DuplicateItemException() | ||||||
|  |         new_wacl = FakeWebACL(name, arn, wacl_id, visibility_config, default_action) | ||||||
|  |         self.wacls[arn] = new_wacl | ||||||
|  |         return new_wacl | ||||||
|  | 
 | ||||||
|  |     def list_web_acls(self): | ||||||
|  |         return [wacl.to_dict() for wacl in self.wacls.values()] | ||||||
|  | 
 | ||||||
|  |     def _is_duplicate_name(self, name): | ||||||
|  |         allWaclNames = set(wacl.name for wacl in self.wacls.values()) | ||||||
|  |         return name in allWaclNames | ||||||
|  | 
 | ||||||
|  |     # TODO: This is how you link wacl to ALB | ||||||
|  |     # @property | ||||||
|  |     # def elbv2_backend(self): | ||||||
|  |     #     """ | ||||||
|  |     #     EC2 backend | ||||||
|  | 
 | ||||||
|  |     #     :return: EC2 Backend | ||||||
|  |     #     :rtype: moto.ec2.models.EC2Backend | ||||||
|  |     #     """ | ||||||
|  |     #     return ec2_backends[self.region_name] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | wafv2_backends = {} | ||||||
|  | wafv2_backends[GLOBAL_REGION] = WAFV2Backend( | ||||||
|  |     GLOBAL_REGION | ||||||
|  | )  # never used? cloudfront is global and uses us-east-1 | ||||||
|  | for region in Session().get_available_regions("waf-regional"): | ||||||
|  |     wafv2_backends[region] = WAFV2Backend(region) | ||||||
|  | for region in Session().get_available_regions( | ||||||
|  |     "waf-regional", partition_name="aws-us-gov" | ||||||
|  | ): | ||||||
|  |     wafv2_backends[region] = WAFV2Backend(region) | ||||||
|  | for region in Session().get_available_regions("waf-regional", partition_name="aws-cn"): | ||||||
|  |     wafv2_backends[region] = WAFV2Backend(region) | ||||||
							
								
								
									
										49
									
								
								moto/wafv2/responses.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								moto/wafv2/responses.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | from __future__ import unicode_literals | ||||||
|  | import json | ||||||
|  | from moto.core.utils import amzn_request_id | ||||||
|  | 
 | ||||||
|  | from moto.core.responses import BaseResponse | ||||||
|  | from .models import GLOBAL_REGION, wafv2_backends | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class WAFV2Response(BaseResponse): | ||||||
|  |     @property | ||||||
|  |     def wafv2_backend(self): | ||||||
|  |         return wafv2_backends[self.region]  # default region is "us-east-1" | ||||||
|  | 
 | ||||||
|  |     @amzn_request_id | ||||||
|  |     def create_web_acl(self): | ||||||
|  |         """  https://docs.aws.amazon.com/waf/latest/APIReference/API_CreateWebACL.html (response syntax section) """ | ||||||
|  | 
 | ||||||
|  |         scope = self._get_param("Scope") | ||||||
|  |         if scope == "CLOUDFRONT": | ||||||
|  |             self.region = GLOBAL_REGION | ||||||
|  |         name = self._get_param("Name") | ||||||
|  |         body = json.loads(self.body) | ||||||
|  |         web_acl = self.wafv2_backend.create_web_acl( | ||||||
|  |             name, body["VisibilityConfig"], body["DefaultAction"], scope | ||||||
|  |         ) | ||||||
|  |         response = { | ||||||
|  |             "Summary": web_acl.to_dict(), | ||||||
|  |         } | ||||||
|  |         response_headers = {"Content-Type": "application/json"} | ||||||
|  |         return 200, response_headers, json.dumps(response) | ||||||
|  | 
 | ||||||
|  |     @amzn_request_id | ||||||
|  |     def list_web_ac_ls(self): | ||||||
|  |         """  https://docs.aws.amazon.com/waf/latest/APIReference/API_ListWebACLs.html (response syntax section) """ | ||||||
|  | 
 | ||||||
|  |         scope = self._get_param("Scope") | ||||||
|  |         if scope == "CLOUDFRONT": | ||||||
|  |             self.region = GLOBAL_REGION | ||||||
|  |         all_web_acls = self.wafv2_backend.list_web_acls() | ||||||
|  |         response = {"NextMarker": "Not Implemented", "WebACLs": all_web_acls} | ||||||
|  |         response_headers = {"Content-Type": "application/json"} | ||||||
|  |         return 200, response_headers, json.dumps(response) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # notes about region and scope | ||||||
|  | # --scope = CLOUDFRONT is ALWAYS us-east-1 (but we use "global" instead to differentiate between REGIONAL us-east-1) | ||||||
|  | # --scope = REGIONAL defaults to us-east-1, but could be anything if specified with --region=<anyRegion> | ||||||
|  | # region is grabbed from the auth header, NOT from the body - even with --region flag | ||||||
|  | # The CLOUDFRONT wacls in aws console are located in us-east-1 but the us-east-1 REGIONAL wacls are not included | ||||||
							
								
								
									
										11
									
								
								moto/wafv2/urls.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								moto/wafv2/urls.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | from __future__ import unicode_literals | ||||||
|  | 
 | ||||||
|  | from .responses import WAFV2Response | ||||||
|  | 
 | ||||||
|  | url_bases = [ | ||||||
|  |     "https?://wafv2.(.+).amazonaws.com", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | url_paths = { | ||||||
|  |     "{0}/": WAFV2Response.dispatch, | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								moto/wafv2/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								moto/wafv2/utils.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | from moto.core import ACCOUNT_ID | ||||||
|  | from moto.core.utils import pascal_to_camelcase, camelcase_to_underscores | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def make_arn_for_wacl(name, region_name, id, scope): | ||||||
|  |     """https://docs.aws.amazon.com/waf/latest/developerguide/how-aws-waf-works.html - explains --scope (cloudfront vs regional)""" | ||||||
|  | 
 | ||||||
|  |     if scope == "REGIONAL": | ||||||
|  |         scope = "regional" | ||||||
|  |     elif scope == "CLOUDFRONT": | ||||||
|  |         scope = "global" | ||||||
|  |     return "arn:aws:wafv2:{}:{}:{}/webacl/{}/{}".format( | ||||||
|  |         region_name, ACCOUNT_ID, scope, name, id | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def pascal_to_underscores_dict(original_dict): | ||||||
|  |     outdict = {} | ||||||
|  |     for k, v in original_dict.items(): | ||||||
|  |         outdict[camelcase_to_underscores(pascal_to_camelcase(k))] = v | ||||||
|  |     return outdict | ||||||
							
								
								
									
										0
									
								
								tests/test_wafv2/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/test_wafv2/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										15
									
								
								tests/test_wafv2/test_helper_functions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/test_wafv2/test_helper_functions.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | def CREATE_WEB_ACL_BODY(name: str, scope: str) -> dict: | ||||||
|  |     return { | ||||||
|  |         "Scope": scope, | ||||||
|  |         "Name": name, | ||||||
|  |         "DefaultAction": {"Allow": {}}, | ||||||
|  |         "VisibilityConfig": { | ||||||
|  |             "SampledRequestsEnabled": False, | ||||||
|  |             "CloudWatchMetricsEnabled": False, | ||||||
|  |             "MetricName": "idk", | ||||||
|  |         }, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def LIST_WEB_ACL_BODY(scope: str) -> dict: | ||||||
|  |     return {"Scope": scope} | ||||||
							
								
								
									
										105
									
								
								tests/test_wafv2/test_server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								tests/test_wafv2/test_server.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | |||||||
|  | from __future__ import unicode_literals | ||||||
|  | import json | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import sure  # noqa | ||||||
|  | 
 | ||||||
|  | import boto3 | ||||||
|  | import botocore | ||||||
|  | from botocore.exceptions import ClientError | ||||||
|  | import moto.server as server | ||||||
|  | from moto import mock_wafv2 | ||||||
|  | from .test_helper_functions import CREATE_WEB_ACL_BODY, LIST_WEB_ACL_BODY | ||||||
|  | from moto.core import ACCOUNT_ID | ||||||
|  | 
 | ||||||
|  | CREATE_WEB_ACL_HEADERS = { | ||||||
|  |     "X-Amz-Target": "AWSWAF_20190729.CreateWebACL", | ||||||
|  |     "Content-Type": "application/json", | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | LIST_WEB_ACL_HEADERS = { | ||||||
|  |     "X-Amz-Target": "AWSWAF_20190729.ListWebACLs", | ||||||
|  |     "Content-Type": "application/json", | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_wafv2 | ||||||
|  | def test_create_web_acl(): | ||||||
|  |     backend = server.create_backend_app("wafv2") | ||||||
|  |     test_client = backend.test_client() | ||||||
|  | 
 | ||||||
|  |     res = test_client.post( | ||||||
|  |         "/", | ||||||
|  |         headers=CREATE_WEB_ACL_HEADERS, | ||||||
|  |         json=CREATE_WEB_ACL_BODY("John", "REGIONAL"), | ||||||
|  |     ) | ||||||
|  |     assert res.status_code == 200 | ||||||
|  | 
 | ||||||
|  |     web_acl = res.json["Summary"] | ||||||
|  |     assert web_acl.get("Name") == "John" | ||||||
|  |     assert web_acl.get("ARN").startswith( | ||||||
|  |         "arn:aws:wafv2:us-east-1:{}:regional/webacl/John/".format(ACCOUNT_ID) | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     # Duplicate name - should raise error | ||||||
|  |     res = test_client.post( | ||||||
|  |         "/", | ||||||
|  |         headers=CREATE_WEB_ACL_HEADERS, | ||||||
|  |         json=CREATE_WEB_ACL_BODY("John", "REGIONAL"), | ||||||
|  |     ) | ||||||
|  |     assert res.status_code == 400 | ||||||
|  |     assert ( | ||||||
|  |         b"AWS WAF could not perform the operation because some resource in your request is a duplicate of an existing one." | ||||||
|  |         in res.data | ||||||
|  |     ) | ||||||
|  |     assert b"WafV2DuplicateItem" in res.data | ||||||
|  | 
 | ||||||
|  |     res = test_client.post( | ||||||
|  |         "/", | ||||||
|  |         headers=CREATE_WEB_ACL_HEADERS, | ||||||
|  |         json=CREATE_WEB_ACL_BODY("Carl", "CLOUDFRONT"), | ||||||
|  |     ) | ||||||
|  |     web_acl = res.json["Summary"] | ||||||
|  |     assert web_acl.get("ARN").startswith( | ||||||
|  |         "arn:aws:wafv2:global:{}:global/webacl/Carl/".format(ACCOUNT_ID) | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_wafv2 | ||||||
|  | def test_list_web_ac_ls(): | ||||||
|  |     backend = server.create_backend_app("wafv2") | ||||||
|  |     test_client = backend.test_client() | ||||||
|  | 
 | ||||||
|  |     test_client.post( | ||||||
|  |         "/", | ||||||
|  |         headers=CREATE_WEB_ACL_HEADERS, | ||||||
|  |         json=CREATE_WEB_ACL_BODY("John", "REGIONAL"), | ||||||
|  |     ) | ||||||
|  |     test_client.post( | ||||||
|  |         "/", | ||||||
|  |         headers=CREATE_WEB_ACL_HEADERS, | ||||||
|  |         json=CREATE_WEB_ACL_BODY("JohnSon", "REGIONAL"), | ||||||
|  |     ) | ||||||
|  |     test_client.post( | ||||||
|  |         "/", | ||||||
|  |         headers=CREATE_WEB_ACL_HEADERS, | ||||||
|  |         json=CREATE_WEB_ACL_BODY("Sarah", "CLOUDFRONT"), | ||||||
|  |     ) | ||||||
|  |     res = test_client.post( | ||||||
|  |         "/", headers=LIST_WEB_ACL_HEADERS, json=LIST_WEB_ACL_BODY("REGIONAL") | ||||||
|  |     ) | ||||||
|  |     assert res.status_code == 200 | ||||||
|  | 
 | ||||||
|  |     web_acls = res.json["WebACLs"] | ||||||
|  |     assert len(web_acls) == 2 | ||||||
|  |     assert web_acls[0]["Name"] == "John" | ||||||
|  |     assert web_acls[1]["Name"] == "JohnSon" | ||||||
|  | 
 | ||||||
|  |     res = test_client.post( | ||||||
|  |         "/", headers=LIST_WEB_ACL_HEADERS, json=LIST_WEB_ACL_BODY("CLOUDFRONT") | ||||||
|  |     ) | ||||||
|  |     assert res.status_code == 200 | ||||||
|  |     web_acls = res.json["WebACLs"] | ||||||
|  |     assert len(web_acls) == 1 | ||||||
|  |     assert web_acls[0]["Name"] == "Sarah" | ||||||
							
								
								
									
										24
									
								
								tests/test_wafv2/test_utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								tests/test_wafv2/test_utils.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | import random | ||||||
|  | import string | ||||||
|  | import uuid | ||||||
|  | 
 | ||||||
|  | from moto.wafv2 import utils | ||||||
|  | from moto.wafv2.utils import make_arn_for_wacl | ||||||
|  | from moto.core import ACCOUNT_ID | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_make_arn_for_wacl(): | ||||||
|  |     uniqueID = str(uuid.uuid4()) | ||||||
|  |     region = "us-east-1" | ||||||
|  |     name = "testName" | ||||||
|  |     scope = "REGIONAL" | ||||||
|  |     arn = make_arn_for_wacl(name, region, uniqueID, scope) | ||||||
|  |     assert arn == "arn:aws:wafv2:{}:{}:regional/webacl/{}/{}".format( | ||||||
|  |         region, ACCOUNT_ID, name, uniqueID | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     scope = "CLOUDFRONT" | ||||||
|  |     arn = make_arn_for_wacl(name, region, uniqueID, scope) | ||||||
|  |     assert arn == "arn:aws:wafv2:{}:{}:global/webacl/{}/{}".format( | ||||||
|  |         region, ACCOUNT_ID, name, uniqueID | ||||||
|  |     ) | ||||||
							
								
								
									
										55
									
								
								tests/test_wafv2/test_wafv2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								tests/test_wafv2/test_wafv2.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | from __future__ import unicode_literals | ||||||
|  | import json | ||||||
|  | import pytest | ||||||
|  | 
 | ||||||
|  | import sure  # noqa | ||||||
|  | import boto3 | ||||||
|  | from botocore.exceptions import ClientError | ||||||
|  | from moto import mock_wafv2 | ||||||
|  | from .test_helper_functions import CREATE_WEB_ACL_BODY, LIST_WEB_ACL_BODY | ||||||
|  | from moto.core import ACCOUNT_ID | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_wafv2 | ||||||
|  | def test_create_web_acl(): | ||||||
|  | 
 | ||||||
|  |     conn = boto3.client("wafv2", region_name="us-east-1") | ||||||
|  |     res = conn.create_web_acl(**CREATE_WEB_ACL_BODY("John", "REGIONAL")) | ||||||
|  |     web_acl = res["Summary"] | ||||||
|  |     assert web_acl.get("Name") == "John" | ||||||
|  |     assert web_acl.get("ARN").startswith( | ||||||
|  |         "arn:aws:wafv2:us-east-1:{}:regional/webacl/John/".format(ACCOUNT_ID) | ||||||
|  |     ) | ||||||
|  |     # Duplicate name - should raise error | ||||||
|  |     with pytest.raises(ClientError) as ex: | ||||||
|  |         conn.create_web_acl(**CREATE_WEB_ACL_BODY("John", "REGIONAL")) | ||||||
|  |     err = ex.value.response["Error"] | ||||||
|  |     err["Message"].should.contain( | ||||||
|  |         "AWS WAF could not perform the operation because some resource in your request is a duplicate of an existing one." | ||||||
|  |     ) | ||||||
|  |     err["Code"].should.equal("400") | ||||||
|  | 
 | ||||||
|  |     res = conn.create_web_acl(**CREATE_WEB_ACL_BODY("Carl", "CLOUDFRONT")) | ||||||
|  |     web_acl = res["Summary"] | ||||||
|  |     assert web_acl.get("ARN").startswith( | ||||||
|  |         "arn:aws:wafv2:global:{}:global/webacl/Carl/".format(ACCOUNT_ID) | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_wafv2 | ||||||
|  | def test_list_web_acl(): | ||||||
|  | 
 | ||||||
|  |     conn = boto3.client("wafv2", region_name="us-east-1") | ||||||
|  |     conn.create_web_acl(**CREATE_WEB_ACL_BODY("Daphne", "REGIONAL")) | ||||||
|  |     conn.create_web_acl(**CREATE_WEB_ACL_BODY("Penelope", "CLOUDFRONT")) | ||||||
|  |     conn.create_web_acl(**CREATE_WEB_ACL_BODY("Sarah", "REGIONAL")) | ||||||
|  |     res = conn.list_web_acls(**LIST_WEB_ACL_BODY("REGIONAL")) | ||||||
|  |     web_acls = res["WebACLs"] | ||||||
|  |     assert len(web_acls) == 2 | ||||||
|  |     assert web_acls[0]["Name"] == "Daphne" | ||||||
|  |     assert web_acls[1]["Name"] == "Sarah" | ||||||
|  | 
 | ||||||
|  |     res = conn.list_web_acls(**LIST_WEB_ACL_BODY("CLOUDFRONT")) | ||||||
|  |     web_acls = res["WebACLs"] | ||||||
|  |     assert len(web_acls) == 1 | ||||||
|  |     assert web_acls[0]["Name"] == "Penelope" | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user