From 5a54deddc163a913aa18c18083ef337494b5f458 Mon Sep 17 00:00:00 2001 From: Kevin DeJong Date: Sat, 9 Nov 2019 15:02:50 -0600 Subject: [PATCH] Remove the need of setuptools (#1188) Signed-off-by: Kevin DeJong --- setup.py | 2 +- src/cfnlint/__init__.py | 1 - src/cfnlint/data/AdditionalSpecs/__init__.py | 0 src/cfnlint/data/CloudSpecs/__init__.py | 0 src/cfnlint/data/ExtendedSpecs/__init__.py | 0 .../all/03_value_types/__init__.py | 15 + .../all/04_property_values/__init__.py | 15 + .../data/ExtendedSpecs/all/__init__.py | 15 + .../data/ExtendedSpecs/ap-east-1/__init__.py | 15 + .../ExtendedSpecs/ap-northeast-1/__init__.py | 15 + .../ExtendedSpecs/ap-northeast-2/__init__.py | 15 + .../ExtendedSpecs/ap-northeast-3/__init__.py | 15 + .../data/ExtendedSpecs/ap-south-1/__init__.py | 15 + .../ExtendedSpecs/ap-southeast-1/__init__.py | 15 + .../ExtendedSpecs/ap-southeast-2/__init__.py | 15 + .../ExtendedSpecs/ca-central-1/__init__.py | 15 + .../data/ExtendedSpecs/cn-north-1/__init__.py | 15 + .../ExtendedSpecs/cn-northwest-1/__init__.py | 15 + .../ExtendedSpecs/eu-central-1/__init__.py | 15 + .../data/ExtendedSpecs/eu-north-1/__init__.py | 15 + .../data/ExtendedSpecs/eu-west-1/__init__.py | 15 + .../data/ExtendedSpecs/eu-west-2/__init__.py | 15 + .../data/ExtendedSpecs/eu-west-3/__init__.py | 15 + .../data/ExtendedSpecs/me-south-1/__init__.py | 15 + .../data/ExtendedSpecs/sa-east-1/__init__.py | 15 + .../data/ExtendedSpecs/us-east-1/__init__.py | 15 + .../data/ExtendedSpecs/us-east-2/__init__.py | 15 + .../ExtendedSpecs/us-gov-east-1/__init__.py | 15 + .../ExtendedSpecs/us-gov-west-1/__init__.py | 15 + .../data/ExtendedSpecs/us-west-1/__init__.py | 15 + .../data/ExtendedSpecs/us-west-2/__init__.py | 15 + src/cfnlint/data/Serverless/__init__.py | 15 + src/cfnlint/data/__init__.py | 15 + src/cfnlint/helpers.py | 25 +- src/cfnlint/maintenance.py | 24 +- .../rules/resources/iam/Permissions.py | 10 +- .../rules/resources/lmbd/DeprecatedRuntime.py | 5 +- .../rules/resources/properties/AtLeastOne.py | 12 +- .../rules/resources/properties/Exclusive.py | 9 +- .../rules/resources/properties/Inclusive.py | 9 +- .../rules/resources/properties/OnlyOne.py | 12 +- .../rules/resources/rds/InstanceSize.py | 12 +- src/cfnlint/transform.py | 5 +- test/__init__.py | 15 + test/fixtures/__init__.py | 15 + test/fixtures/configs/__init__.py | 15 + test/fixtures/results/__init__.py | 15 + test/fixtures/results/public/__init__.py | 15 + test/fixtures/results/quickstart/__init__.py | 15 + .../fixtures/results/quickstart/nist_iam.json | 18 +- .../results/quickstart/non_strict/__init__.py | 15 + test/fixtures/specs/__init__.py | 15 + test/fixtures/templates/__init__.py | 15 + .../fixtures/templates/quickstart/__init__.py | 15 + .../templates/quickstart/nist_iam.yaml | 403 +++++++++--------- test/integration/test_patched_specs.py | 72 ++-- test/module/maintenance/test_patch_spec.py | 25 +- .../properties/test_allowed_pattern.py | 20 +- tox.ini | 2 +- 59 files changed, 917 insertions(+), 319 deletions(-) create mode 100644 src/cfnlint/data/AdditionalSpecs/__init__.py create mode 100644 src/cfnlint/data/CloudSpecs/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/all/03_value_types/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/all/04_property_values/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/all/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ap-east-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ap-northeast-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ap-northeast-2/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ap-northeast-3/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ap-south-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ap-southeast-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ap-southeast-2/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/ca-central-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/cn-north-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/cn-northwest-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/eu-central-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/eu-north-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/eu-west-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/eu-west-2/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/eu-west-3/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/me-south-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/sa-east-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/us-east-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/us-east-2/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/us-gov-east-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/us-gov-west-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/us-west-1/__init__.py create mode 100644 src/cfnlint/data/ExtendedSpecs/us-west-2/__init__.py create mode 100644 src/cfnlint/data/Serverless/__init__.py create mode 100644 src/cfnlint/data/__init__.py create mode 100644 test/__init__.py create mode 100644 test/fixtures/__init__.py create mode 100644 test/fixtures/configs/__init__.py create mode 100644 test/fixtures/results/__init__.py create mode 100644 test/fixtures/results/public/__init__.py create mode 100644 test/fixtures/results/quickstart/__init__.py create mode 100644 test/fixtures/results/quickstart/non_strict/__init__.py create mode 100644 test/fixtures/specs/__init__.py create mode 100644 test/fixtures/templates/__init__.py create mode 100644 test/fixtures/templates/quickstart/__init__.py diff --git a/setup.py b/setup.py index fb431a79a5..32f76b3e94 100644 --- a/setup.py +++ b/setup.py @@ -81,7 +81,7 @@ def get_version(filename): 'jsonpatch', 'jsonschema~=3.0', 'pathlib2>=2.3.0;python_version<"3.4"', - 'setuptools', + 'importlib_resources~=1.0.2;python_version<"3.7"', ], python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', entry_points={ diff --git a/src/cfnlint/__init__.py b/src/cfnlint/__init__.py index 5c506e7de3..ab66d983cf 100644 --- a/src/cfnlint/__init__.py +++ b/src/cfnlint/__init__.py @@ -40,7 +40,6 @@ LOGGER = logging.getLogger(__name__) - # pylint: disable=too-many-lines def refactored(message): """ Decoreate for refactoring classes """ diff --git a/src/cfnlint/data/AdditionalSpecs/__init__.py b/src/cfnlint/data/AdditionalSpecs/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/cfnlint/data/CloudSpecs/__init__.py b/src/cfnlint/data/CloudSpecs/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/cfnlint/data/ExtendedSpecs/__init__.py b/src/cfnlint/data/ExtendedSpecs/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/cfnlint/data/ExtendedSpecs/all/03_value_types/__init__.py b/src/cfnlint/data/ExtendedSpecs/all/03_value_types/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/all/03_value_types/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/all/04_property_values/__init__.py b/src/cfnlint/data/ExtendedSpecs/all/04_property_values/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/all/04_property_values/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/all/__init__.py b/src/cfnlint/data/ExtendedSpecs/all/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/all/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ap-east-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/ap-east-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ap-east-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ap-northeast-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/ap-northeast-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ap-northeast-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ap-northeast-2/__init__.py b/src/cfnlint/data/ExtendedSpecs/ap-northeast-2/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ap-northeast-2/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ap-northeast-3/__init__.py b/src/cfnlint/data/ExtendedSpecs/ap-northeast-3/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ap-northeast-3/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ap-south-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/ap-south-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ap-south-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ap-southeast-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/ap-southeast-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ap-southeast-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ap-southeast-2/__init__.py b/src/cfnlint/data/ExtendedSpecs/ap-southeast-2/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ap-southeast-2/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/ca-central-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/ca-central-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/ca-central-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/cn-north-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/cn-north-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/cn-north-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/cn-northwest-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/cn-northwest-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/cn-northwest-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/eu-central-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/eu-central-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/eu-central-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/eu-north-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/eu-north-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/eu-north-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/eu-west-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/eu-west-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/eu-west-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/eu-west-2/__init__.py b/src/cfnlint/data/ExtendedSpecs/eu-west-2/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/eu-west-2/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/eu-west-3/__init__.py b/src/cfnlint/data/ExtendedSpecs/eu-west-3/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/eu-west-3/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/me-south-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/me-south-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/me-south-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/sa-east-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/sa-east-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/sa-east-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/us-east-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/us-east-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/us-east-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/us-east-2/__init__.py b/src/cfnlint/data/ExtendedSpecs/us-east-2/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/us-east-2/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/us-gov-east-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/us-gov-east-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/us-gov-east-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/us-gov-west-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/us-gov-west-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/us-gov-west-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/us-west-1/__init__.py b/src/cfnlint/data/ExtendedSpecs/us-west-1/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/us-west-1/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/ExtendedSpecs/us-west-2/__init__.py b/src/cfnlint/data/ExtendedSpecs/us-west-2/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/ExtendedSpecs/us-west-2/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/Serverless/__init__.py b/src/cfnlint/data/Serverless/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/Serverless/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/data/__init__.py b/src/cfnlint/data/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/src/cfnlint/data/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/src/cfnlint/helpers.py b/src/cfnlint/helpers.py index e7c5562a81..d9e2dd1677 100644 --- a/src/cfnlint/helpers.py +++ b/src/cfnlint/helpers.py @@ -29,8 +29,13 @@ from urllib.request import urlopen except ImportError: from urllib2 import urlopen -import pkg_resources +try: + import importlib.resources as pkg_resources +except ImportError: + # Try backported to PY<37 `importlib_resources`. + import importlib_resources as pkg_resources import six +from cfnlint.data import CloudSpecs from cfnlint.decode.node import dict_node, list_node, str_node LOGGER = logging.getLogger(__name__) @@ -165,16 +170,12 @@ def get_url_content(url): return content -def load_resources(filename='data/CloudSpecs/us-east-1.json'): - """Load resources""" - - filename = pkg_resources.resource_filename( - __name__, - filename - ) - - with open(filename) as fp: - return json.load(fp) +def load_resource(package, filename='us-east-1.json'): + """Load CloudSpec resources + :param filename: filename to load + :return: Json output of the resource laoded + """ + return json.loads(pkg_resources.read_text(package, filename, encoding='utf-8')) RESOURCE_SPECS = {} @@ -261,7 +262,7 @@ def bool_compare(first, second): def initialize_specs(): """ Reload Resource Specs """ for reg in REGIONS: - RESOURCE_SPECS[reg] = load_resources(filename=('data/CloudSpecs/%s.json' % reg)) + RESOURCE_SPECS[reg] = load_resource(CloudSpecs, filename=('%s.json' % reg)) initialize_specs() diff --git a/src/cfnlint/maintenance.py b/src/cfnlint/maintenance.py index bbae3963dc..9c409dd2ab 100644 --- a/src/cfnlint/maintenance.py +++ b/src/cfnlint/maintenance.py @@ -18,11 +18,11 @@ import json import logging import os -import pkg_resources import jsonpointer import jsonpatch import cfnlint from cfnlint.helpers import get_url_content +import cfnlint.data.ExtendedSpecs LOGGER = logging.getLogger(__name__) @@ -59,10 +59,8 @@ def update_resource_specs(): """ Update Resource Specs """ for region, url in SPEC_REGIONS.items(): - filename = pkg_resources.resource_filename( - __name__, - '/data/CloudSpecs/%s.json' % region, - ) + filename = os.path.join(os.path.dirname(cfnlint.__file__), + 'data/CloudSpecs/%s.json' % region) LOGGER.debug('Downloading template %s into %s', url, filename) spec = json.loads(get_url_content(url)) @@ -169,10 +167,11 @@ def patch_spec(content, region): for dirpath, _, filenames in os.walk(append_dir): filenames.sort() for filename in fnmatch.filter(filenames, '*.json'): - file_path = os.path.join(dirpath, filename).replace(append_dir, '') - LOGGER.info('Processing %s%s', region, file_path) - all_patches = jsonpatch.JsonPatch(cfnlint.helpers.load_resources( - 'data/ExtendedSpecs/{}{}'.format(region, file_path))) + file_path = os.path.basename(filename) + module = dirpath.replace('%s' % append_dir, '%s' % region).replace('/', '.') + LOGGER.info('Processing %s/%s', module, file_path) + all_patches = jsonpatch.JsonPatch(cfnlint.helpers.load_resource( + 'cfnlint.data.ExtendedSpecs.{}'.format(module), file_path)) # Process the generic patches 1 by 1 so we can "ignore" failed ones for all_patch in all_patches: @@ -193,10 +192,9 @@ def update_iam_policies(): url = 'https://awspolicygen.s3.amazonaws.com/js/policies.js' - filename = pkg_resources.resource_filename( - __name__, - '/data/AdditionalSpecs/Policies.json', - ) + filename = os.path.join( + os.path.dirname(cfnlint.data.AdditionalSpecs.__file__), + 'Policies.json') LOGGER.debug('Downloading policies %s into %s', url, filename) content = get_url_content(url) diff --git a/src/cfnlint/rules/resources/iam/Permissions.py b/src/cfnlint/rules/resources/iam/Permissions.py index 6ebfcc6d69..65b9e03d77 100644 --- a/src/cfnlint/rules/resources/iam/Permissions.py +++ b/src/cfnlint/rules/resources/iam/Permissions.py @@ -16,11 +16,10 @@ """ import json import six -from cfnlint.helpers import convert_dict +from cfnlint.helpers import convert_dict, load_resource from cfnlint.rules import CloudFormationLintRule from cfnlint.rules import RuleMatch - -import cfnlint.helpers +from cfnlint.data import AdditionalSpecs class Permissions(CloudFormationLintRule): @@ -56,7 +55,7 @@ def load_service_map(self): """ Convert policies.json into a simpler version for more efficient key lookup. """ - service_map = cfnlint.helpers.load_resources('data/AdditionalSpecs/Policies.json')['serviceMap'] + service_map = load_resource(AdditionalSpecs, 'Policies.json')['serviceMap'] policy_service_map = {} @@ -105,7 +104,8 @@ def check_policy_document(self, value, path, start_mark, end_mark): actions.extend(self.get_actions(effective_permission)) for action in actions: - matches.extend(self.check_permissions(action, p_p + ['Statement', index])) + matches.extend(self.check_permissions( + action, p_p + ['Statement', index])) return matches diff --git a/src/cfnlint/rules/resources/lmbd/DeprecatedRuntime.py b/src/cfnlint/rules/resources/lmbd/DeprecatedRuntime.py index 714ac4ad2e..78d82464aa 100644 --- a/src/cfnlint/rules/resources/lmbd/DeprecatedRuntime.py +++ b/src/cfnlint/rules/resources/lmbd/DeprecatedRuntime.py @@ -15,7 +15,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from datetime import datetime -from cfnlint.helpers import load_resources +from cfnlint.helpers import load_resource +from cfnlint.data import AdditionalSpecs from cfnlint.rules import CloudFormationLintRule @@ -26,7 +27,7 @@ def __init__(self): """Init""" super(DeprecatedRuntime, self).__init__() self.resource_property_types.append('AWS::Lambda::Function') - self.deprecated_runtimes = load_resources('data/AdditionalSpecs/LmbdRuntimeLifecycle.json') + self.deprecated_runtimes = load_resource(AdditionalSpecs, 'LmbdRuntimeLifecycle.json') current_date = datetime.today() diff --git a/src/cfnlint/rules/resources/properties/AtLeastOne.py b/src/cfnlint/rules/resources/properties/AtLeastOne.py index 3b5261e568..fb1b97b226 100644 --- a/src/cfnlint/rules/resources/properties/AtLeastOne.py +++ b/src/cfnlint/rules/resources/properties/AtLeastOne.py @@ -17,6 +17,7 @@ from cfnlint.rules import CloudFormationLintRule from cfnlint.rules import RuleMatch import cfnlint.helpers +from cfnlint.data import AdditionalSpecs class AtLeastOne(CloudFormationLintRule): @@ -32,7 +33,7 @@ class AtLeastOne(CloudFormationLintRule): def __init__(self): """Init""" super(AtLeastOne, self).__init__() - atleastonespec = cfnlint.helpers.load_resources('data/AdditionalSpecs/AtLeastOne.json') + atleastonespec = cfnlint.helpers.load_resource(AdditionalSpecs, 'AtLeastOne.json') self.resource_types_specs = atleastonespec['ResourceTypes'] self.property_types_specs = atleastonespec['PropertyTypes'] for resource_type_spec in self.resource_types_specs: @@ -56,14 +57,17 @@ def check(self, properties, atleastoneprops, path, cfn): message = 'At least one of [{0}] should be specified for {1}' matches.append(RuleMatch( path, - message.format(', '.join(map(str, atleastoneprop)), '/'.join(map(str, path))) + message.format(', '.join(map(str, atleastoneprop)), + '/'.join(map(str, path))) )) else: - scenario_text = ' and '.join(['when condition "%s" is %s' % (k, v) for (k, v) in property_set['Scenario'].items()]) + scenario_text = ' and '.join(['when condition "%s" is %s' % ( + k, v) for (k, v) in property_set['Scenario'].items()]) message = 'At least one of [{0}] should be specified {1} at {2}' matches.append(RuleMatch( path, - message.format(', '.join(map(str, atleastoneprop)), scenario_text, '/'.join(map(str, path))) + message.format(', '.join(map(str, atleastoneprop)), + scenario_text, '/'.join(map(str, path))) )) return matches diff --git a/src/cfnlint/rules/resources/properties/Exclusive.py b/src/cfnlint/rules/resources/properties/Exclusive.py index b64e8c89ab..95a0292061 100644 --- a/src/cfnlint/rules/resources/properties/Exclusive.py +++ b/src/cfnlint/rules/resources/properties/Exclusive.py @@ -17,6 +17,7 @@ from cfnlint.rules import CloudFormationLintRule from cfnlint.rules import RuleMatch import cfnlint.helpers +from cfnlint.data import AdditionalSpecs class Exclusive(CloudFormationLintRule): @@ -31,7 +32,7 @@ class Exclusive(CloudFormationLintRule): def __init__(self): """Init""" super(Exclusive, self).__init__() - exclusivespec = cfnlint.helpers.load_resources('data/AdditionalSpecs/Exclusive.json') + exclusivespec = cfnlint.helpers.load_resource(AdditionalSpecs, 'Exclusive.json') self.resource_types_specs = exclusivespec['ResourceTypes'] self.property_types_specs = exclusivespec['PropertyTypes'] for resource_type_spec in self.resource_types_specs: @@ -56,11 +57,13 @@ def check(self, properties, exclusions, path, cfn): message.format(excl_property, prop, '/'.join(map(str, path))) )) else: - scenario_text = ' and '.join(['when condition "%s" is %s' % (k, v) for (k, v) in property_set['Scenario'].items()]) + scenario_text = ' and '.join(['when condition "%s" is %s' % ( + k, v) for (k, v) in property_set['Scenario'].items()]) message = 'Property {0} should NOT exist with {1} {2} for {3}' matches.append(RuleMatch( path + [prop], - message.format(excl_property, prop, scenario_text, '/'.join(map(str, path))) + message.format(excl_property, prop, scenario_text, + '/'.join(map(str, path))) )) return matches diff --git a/src/cfnlint/rules/resources/properties/Inclusive.py b/src/cfnlint/rules/resources/properties/Inclusive.py index a6bdd755ee..0cc80a602e 100644 --- a/src/cfnlint/rules/resources/properties/Inclusive.py +++ b/src/cfnlint/rules/resources/properties/Inclusive.py @@ -17,6 +17,7 @@ from cfnlint.rules import CloudFormationLintRule from cfnlint.rules import RuleMatch import cfnlint.helpers +from cfnlint.data import AdditionalSpecs class Inclusive(CloudFormationLintRule): @@ -31,7 +32,7 @@ class Inclusive(CloudFormationLintRule): def __init__(self): """Init""" super(Inclusive, self).__init__() - inclusivespec = cfnlint.helpers.load_resources('data/AdditionalSpecs/Inclusive.json') + inclusivespec = cfnlint.helpers.load_resource(AdditionalSpecs, 'Inclusive.json') self.resource_types_specs = inclusivespec['ResourceTypes'] self.property_types_specs = inclusivespec['PropertyTypes'] for resource_type_spec in self.resource_types_specs: @@ -58,11 +59,13 @@ def check(self, properties, inclusions, path, cfn): message.format(incl_property, prop, '/'.join(map(str, path))) )) else: - scenario_text = ' and '.join(['when condition "%s" is %s' % (k, v) for (k, v) in property_set['Scenario'].items()]) + scenario_text = ' and '.join(['when condition "%s" is %s' % ( + k, v) for (k, v) in property_set['Scenario'].items()]) message = 'Property {0} should exist with {1} {2} for {3}' matches.append(RuleMatch( path, - message.format(incl_property, prop, scenario_text, '/'.join(map(str, path))) + message.format(incl_property, prop, scenario_text, + '/'.join(map(str, path))) )) return matches diff --git a/src/cfnlint/rules/resources/properties/OnlyOne.py b/src/cfnlint/rules/resources/properties/OnlyOne.py index e34b7f3af7..fb1e35ca07 100644 --- a/src/cfnlint/rules/resources/properties/OnlyOne.py +++ b/src/cfnlint/rules/resources/properties/OnlyOne.py @@ -17,6 +17,7 @@ from cfnlint.rules import CloudFormationLintRule from cfnlint.rules import RuleMatch import cfnlint.helpers +from cfnlint.data import AdditionalSpecs class OnlyOne(CloudFormationLintRule): @@ -32,7 +33,7 @@ class OnlyOne(CloudFormationLintRule): def __init__(self): """Init""" super(OnlyOne, self).__init__() - onlyonespec = cfnlint.helpers.load_resources('data/AdditionalSpecs/OnlyOne.json') + onlyonespec = cfnlint.helpers.load_resource(AdditionalSpecs, 'OnlyOne.json') self.resource_types_specs = onlyonespec['ResourceTypes'] self.property_types_specs = onlyonespec['PropertyTypes'] for resource_type_spec in self.resource_types_specs: @@ -56,14 +57,17 @@ def check(self, properties, onlyoneprops, path, cfn): message = 'Only one of [{0}] should be specified for {1}' matches.append(RuleMatch( path, - message.format(', '.join(map(str, onlyoneprop)), '/'.join(map(str, path))) + message.format(', '.join(map(str, onlyoneprop)), + '/'.join(map(str, path))) )) else: - scenario_text = ' and '.join(['when condition "%s" is %s' % (k, v) for (k, v) in property_set['Scenario'].items()]) + scenario_text = ' and '.join(['when condition "%s" is %s' % ( + k, v) for (k, v) in property_set['Scenario'].items()]) message = 'Only one of [{0}] should be specified {1} at {2}' matches.append(RuleMatch( path, - message.format(', '.join(map(str, onlyoneprop)), scenario_text, '/'.join(map(str, path))) + message.format(', '.join(map(str, onlyoneprop)), + scenario_text, '/'.join(map(str, path))) )) return matches diff --git a/src/cfnlint/rules/resources/rds/InstanceSize.py b/src/cfnlint/rules/resources/rds/InstanceSize.py index d247ca49d5..a68dbc3bb7 100644 --- a/src/cfnlint/rules/resources/rds/InstanceSize.py +++ b/src/cfnlint/rules/resources/rds/InstanceSize.py @@ -18,6 +18,7 @@ import cfnlint.helpers from cfnlint.rules import CloudFormationLintRule from cfnlint.rules import RuleMatch +from cfnlint.data import AdditionalSpecs class InstanceSize(CloudFormationLintRule): @@ -29,7 +30,7 @@ class InstanceSize(CloudFormationLintRule): source_url = 'https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html' tags = ['resources', 'rds'] - valid_instance_types = cfnlint.helpers.load_resources('data/AdditionalSpecs/RdsProperties.json') + valid_instance_types = cfnlint.helpers.load_resource(AdditionalSpecs, 'RdsProperties.json') def _get_license_model(self, engine, license_model): """ Logic to get the correct license model""" @@ -40,7 +41,8 @@ def _get_license_model(self, engine, license_model): license_model = 'bring-your-own-license' else: license_model = 'general-public-license' - self.logger.debug('Based on Engine: %s we determined the default license will be %s', engine, license_model) + self.logger.debug( + 'Based on Engine: %s we determined the default license will be %s', engine, license_model) return license_model @@ -70,9 +72,11 @@ def get_resources(self, cfn): 'LicenseModel': license_model }) else: - self.logger.debug('Skip evaluation based on [LicenseModel] not being a string.') + self.logger.debug( + 'Skip evaluation based on [LicenseModel] not being a string.') else: - self.logger.debug('Skip evaluation based on [Engine] or [DBInstanceClass] not being strings.') + self.logger.debug( + 'Skip evaluation based on [Engine] or [DBInstanceClass] not being strings.') return results diff --git a/src/cfnlint/transform.py b/src/cfnlint/transform.py index a8cdd90688..3c36c08062 100644 --- a/src/cfnlint/transform.py +++ b/src/cfnlint/transform.py @@ -22,7 +22,8 @@ from samtranslator.translator.translator import Translator from samtranslator.public.exceptions import InvalidDocumentException -from cfnlint.helpers import load_resources, convert_dict, format_json_string +from cfnlint.helpers import load_resource, convert_dict, format_json_string +from cfnlint.data import Serverless from cfnlint.rules import Match, TransformError LOGGER = logging.getLogger('cfnlint') @@ -55,7 +56,7 @@ def load_managed_policies(self): Load the ManagedPolicies locally, based on the AWS-CLI: https://github.com/awslabs/aws-sam-cli/blob/develop/samcli/lib/samlib/default_managed_policies.json """ - return load_resources('data/Serverless/ManagedPolicies.json') + return load_resource(Serverless, 'ManagedPolicies.json') def _replace_local_codeuri(self): """ diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/__init__.py b/test/fixtures/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/configs/__init__.py b/test/fixtures/configs/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/configs/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/results/__init__.py b/test/fixtures/results/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/results/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/results/public/__init__.py b/test/fixtures/results/public/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/results/public/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/results/quickstart/__init__.py b/test/fixtures/results/quickstart/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/results/quickstart/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/results/quickstart/nist_iam.json b/test/fixtures/results/quickstart/nist_iam.json index c9294871ea..f3d7f42add 100644 --- a/test/fixtures/results/quickstart/nist_iam.json +++ b/test/fixtures/results/quickstart/nist_iam.json @@ -5,7 +5,7 @@ "Location": { "End": { "ColumnNumber": 14, - "LineNumber": 56 + "LineNumber": 57 }, "Path": [ "Resources", @@ -14,7 +14,7 @@ ], "Start": { "ColumnNumber": 5, - "LineNumber": 56 + "LineNumber": 57 } }, "Message": "Obsolete DependsOn on resource (rIAMAdminRole), dependency already enforced by a \"Ref\" at Resources/rIAMAdminProfile/Properties/Roles/0/Ref/rIAMAdminRole", @@ -31,7 +31,7 @@ "Location": { "End": { "ColumnNumber": 14, - "LineNumber": 136 + "LineNumber": 137 }, "Path": [ "Resources", @@ -40,7 +40,7 @@ ], "Start": { "ColumnNumber": 5, - "LineNumber": 136 + "LineNumber": 137 } }, "Message": "Obsolete DependsOn on resource (rInstanceOpsRole), dependency already enforced by a \"Ref\" at Resources/rInstanceOpsProfile/Properties/Roles/0/Ref/rInstanceOpsRole", @@ -57,7 +57,7 @@ "Location": { "End": { "ColumnNumber": 14, - "LineNumber": 235 + "LineNumber": 236 }, "Path": [ "Resources", @@ -66,7 +66,7 @@ ], "Start": { "ColumnNumber": 5, - "LineNumber": 235 + "LineNumber": 236 } }, "Message": "Obsolete DependsOn on resource (rReadOnlyAdminRole), dependency already enforced by a \"Ref\" at Resources/rReadOnlyAdminProfile/Properties/Roles/0/Ref/rReadOnlyAdminRole", @@ -83,7 +83,7 @@ "Location": { "End": { "ColumnNumber": 14, - "LineNumber": 311 + "LineNumber": 312 }, "Path": [ "Resources", @@ -92,7 +92,7 @@ ], "Start": { "ColumnNumber": 5, - "LineNumber": 311 + "LineNumber": 312 } }, "Message": "Obsolete DependsOn on resource (rSysAdminRole), dependency already enforced by a \"Ref\" at Resources/rSysAdminProfile/Properties/Roles/0/Ref/rSysAdminRole", @@ -103,4 +103,4 @@ "Source": "https://aws.amazon.com/blogs/devops/optimize-aws-cloudformation-templates/" } } -] +] \ No newline at end of file diff --git a/test/fixtures/results/quickstart/non_strict/__init__.py b/test/fixtures/results/quickstart/non_strict/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/results/quickstart/non_strict/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/specs/__init__.py b/test/fixtures/specs/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/specs/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/templates/__init__.py b/test/fixtures/templates/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/templates/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/templates/quickstart/__init__.py b/test/fixtures/templates/quickstart/__init__.py new file mode 100644 index 0000000000..b04428689c --- /dev/null +++ b/test/fixtures/templates/quickstart/__init__.py @@ -0,0 +1,15 @@ +""" + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +""" diff --git a/test/fixtures/templates/quickstart/nist_iam.yaml b/test/fixtures/templates/quickstart/nist_iam.yaml index 4f04512450..c9f230bb58 100644 --- a/test/fixtures/templates/quickstart/nist_iam.yaml +++ b/test/fixtures/templates/quickstart/nist_iam.yaml @@ -1,5 +1,6 @@ -AWSTemplateFormatVersion: '2010-09-09' -Description: Provides the base security, IAM, and access configuration for the AWS +AWSTemplateFormatVersion: "2010-09-09" +Description: + Provides the base security, IAM, and access configuration for the AWS account Metadata: Identifier: @@ -9,9 +10,9 @@ Metadata: Output: Description: Outputs ID of all deployed resources Stack: - Value: '1' + Value: "1" VersionDate: - Value: '20160510' + Value: "20160510" Outputs: rIAMAdminGroup: Value: @@ -36,39 +37,39 @@ Resources: rIAMAdminPolicy: Properties: Groups: - - Ref: rIAMAdminGroup + - Ref: rIAMAdminGroup PolicyDocument: Statement: - - Action: iam:* - Condition: - Bool: - aws:MultiFactorAuthPresent: 'true' - Effect: Allow - Resource: '*' - - Action: aws-portal:*Billing - Effect: Deny - Resource: '*' - Version: '2012-10-17' + - Action: iam:* + Condition: + Bool: + aws:MultiFactorAuthPresent: "true" + Effect: Allow + Resource: "*" + - Action: aws-portal:*Billing + Effect: Deny + Resource: "*" + Version: "2012-10-17" Roles: - - Ref: rIAMAdminRole + - Ref: rIAMAdminRole Type: AWS::IAM::ManagedPolicy rIAMAdminProfile: DependsOn: rIAMAdminRole Properties: Path: / Roles: - - Ref: rIAMAdminRole + - Ref: rIAMAdminRole Type: AWS::IAM::InstanceProfile rIAMAdminRole: Properties: AssumeRolePolicyDocument: Statement: - - Action: - - sts:AssumeRole - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com Type: AWS::IAM::Role rInstanceOpsGroup: Properties: @@ -77,78 +78,78 @@ Resources: rInstanceOpsPolicy: Properties: Groups: - - Ref: rInstanceOpsGroup + - Ref: rInstanceOpsGroup PolicyDocument: Statement: - - Action: ec2:* - Effect: Allow - Resource: '*' - - Action: elasticloadbalancing:* - Effect: Allow - Resource: '*' - - Action: cloudwatch:* - Effect: Allow - Resource: '*' - - Action: autoscaling:* - Effect: Allow - Resource: '*' - - Action: - - ec2:CreateVpc* - - ec2:DeleteVpc* - - ec2:ModifyVpc* - - ec2:CreateSubnet* - - ec2:DeleteSubnet* - - ec2:ModifySubnet* - - ec2:Create*Route* - - ec2:DeleteRoute* - - ec2:AssociateRoute* - - ec2:ReplaceRoute* - - ec2:CreateVpn* - - ec2:DeleteVpn* - - ec2:AttachVpn* - - ec2:DetachVpn* - - ec2:CreateNetworkAcl* - - ec2:DeleteNetworkAcl* - - ec2:ReplaceNetworkAcl* - - ec2:*Gateway* - - ec2:*PeeringConnection* - Effect: Deny - Resource: '*' - - Action: aws-portal:*Billing - Effect: Deny - Resource: '*' - - Action: - - kms:Create* - - kms:Revoke* - - kms:Enable* - - kms:Get* - - kms:Disable* - - kms:Delete* - - kms:Put* - - kms:Update* - Effect: Deny - Resource: '*' - Version: '2012-10-17' + - Action: ec2:* + Effect: Allow + Resource: "*" + - Action: elasticloadbalancing:* + Effect: Allow + Resource: "*" + - Action: cloudwatch:* + Effect: Allow + Resource: "*" + - Action: autoscaling:* + Effect: Allow + Resource: "*" + - Action: + - ec2:CreateVpc* + - ec2:DeleteVpc* + - ec2:ModifyVpc* + - ec2:CreateSubnet* + - ec2:DeleteSubnet* + - ec2:ModifySubnet* + - ec2:Create*Route* + - ec2:DeleteRoute* + - ec2:AssociateRoute* + - ec2:ReplaceRoute* + - ec2:CreateVpn* + - ec2:DeleteVpn* + - ec2:AttachVpn* + - ec2:DetachVpn* + - ec2:CreateNetworkAcl* + - ec2:DeleteNetworkAcl* + - ec2:ReplaceNetworkAcl* + - ec2:*Gateway* + - ec2:*PeeringConnection* + Effect: Deny + Resource: "*" + - Action: aws-portal:*Billing + Effect: Deny + Resource: "*" + - Action: + - kms:Create* + - kms:Revoke* + - kms:Enable* + - kms:Get* + - kms:Disable* + - kms:Delete* + - kms:Put* + - kms:Update* + Effect: Deny + Resource: "*" + Version: "2012-10-17" Roles: - - Ref: rInstanceOpsRole + - Ref: rInstanceOpsRole Type: AWS::IAM::ManagedPolicy rInstanceOpsProfile: DependsOn: rInstanceOpsRole Properties: Path: / Roles: - - Ref: rInstanceOpsRole + - Ref: rInstanceOpsRole Type: AWS::IAM::InstanceProfile rInstanceOpsRole: Properties: AssumeRolePolicyDocument: Statement: - - Action: - - sts:AssumeRole - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com Type: AWS::IAM::Role rReadOnlyAdminGroup: Properties: @@ -158,96 +159,96 @@ Resources: DependsOn: rReadOnlyAdminProfile Properties: Groups: - - Ref: rReadOnlyAdminGroup + - Ref: rReadOnlyAdminGroup PolicyDocument: Statement: - - Action: - - appstream:Get* - - autoscaling:Describe* - - cloudformation:DescribeStacks - - cloudformation:DescribeStackEvents - - cloudformation:DescribeStackResource - - cloudformation:DescribeStackResources - - cloudformation:GetTemplate - - cloudformation:List* - - cloudfront:Get* - - cloudfront:List* - - cloudtrail:DescribeTrails - - cloudtrail:GetTrailStatus - - cloudwatch:Describe* - - cloudwatch:Get* - - cloudwatch:List* - - directconnect:Describe* - - dynamodb:GetItem - - dynamodb:BatchGetItem - - dynamodb:Query - - dynamodb:Scan - - dynamodb:DescribeTable - - dynamodb:ListTables - - ec2:Describe* - - elasticache:Describe* - - elasticbeanstalk:Check* - - elasticbeanstalk:Describe* - - elasticbeanstalk:List* - - elasticbeanstalk:RequestEnvironmentInfo - - elasticbeanstalk:RetrieveEnvironmentInfo - - elasticloadbalancing:Describe* - - elastictranscoder:Read* - - elastictranscoder:List* - - iam:List* - - iam:Get* - - kinesis:Describe* - - kinesis:Get* - - kinesis:List* - - opsworks:Describe* - - opsworks:Get* - - route53:Get* - - route53:List* - - redshift:Describe* - - redshift:ViewQueriesInConsole - - rds:Describe* - - rds:ListTagsForResource - - s3:Get* - - s3:List* - - sdb:GetAttributes - - sdb:List* - - sdb:Select* - - ses:Get* - - ses:List* - - sns:Get* - - sns:List* - - sqs:GetQueueAttributes - - sqs:ListQueues - - sqs:ReceiveMessage - - storagegateway:List* - - storagegateway:Describe* - - trustedadvisor:Describe* - Effect: Allow - Resource: '*' - - Action: aws-portal:*Billing - Effect: Deny - Resource: '*' - Version: '2012-10-17' + - Action: + - appstream:Get* + - autoscaling:Describe* + - cloudformation:DescribeStacks + - cloudformation:DescribeStackEvents + - cloudformation:DescribeStackResource + - cloudformation:DescribeStackResources + - cloudformation:GetTemplate + - cloudformation:List* + - cloudfront:Get* + - cloudfront:List* + - cloudtrail:DescribeTrails + - cloudtrail:GetTrailStatus + - cloudwatch:Describe* + - cloudwatch:Get* + - cloudwatch:List* + - directconnect:Describe* + - dynamodb:GetItem + - dynamodb:BatchGetItem + - dynamodb:Query + - dynamodb:Scan + - dynamodb:DescribeTable + - dynamodb:ListTables + - ec2:Describe* + - elasticache:Describe* + - elasticbeanstalk:Check* + - elasticbeanstalk:Describe* + - elasticbeanstalk:List* + - elasticbeanstalk:RequestEnvironmentInfo + - elasticbeanstalk:RetrieveEnvironmentInfo + - elasticloadbalancing:Describe* + - elastictranscoder:Read* + - elastictranscoder:List* + - iam:List* + - iam:Get* + - kinesis:Describe* + - kinesis:Get* + - kinesis:List* + - opsworks:Describe* + - opsworks:Get* + - route53:Get* + - route53:List* + - redshift:Describe* + - redshift:ViewQueriesInConsole + - rds:Describe* + - rds:ListTagsForResource + - s3:Get* + - s3:List* + - sdb:GetAttributes + - sdb:List* + - sdb:Select* + - ses:Get* + - ses:List* + - sns:Get* + - sns:List* + - sqs:GetQueueAttributes + - sqs:ListQueues + - sqs:ReceiveMessage + - storagegateway:List* + - storagegateway:Describe* + - trustedadvisor:Describe* + Effect: Allow + Resource: "*" + - Action: aws-portal:*Billing + Effect: Deny + Resource: "*" + Version: "2012-10-17" Roles: - - Ref: rReadOnlyAdminRole + - Ref: rReadOnlyAdminRole Type: AWS::IAM::ManagedPolicy rReadOnlyAdminProfile: DependsOn: rReadOnlyAdminRole Properties: Path: / Roles: - - Ref: rReadOnlyAdminRole + - Ref: rReadOnlyAdminRole Type: AWS::IAM::InstanceProfile rReadOnlyAdminRole: Properties: AssumeRolePolicyDocument: Statement: - - Action: - - sts:AssumeRole - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com Type: AWS::IAM::Role rReadOnlyBillingGroup: Properties: @@ -256,16 +257,16 @@ Resources: rReadOnlyBillingPolicy: Properties: Groups: - - Ref: rReadOnlyBillingGroup + - Ref: rReadOnlyBillingGroup PolicyDocument: Statement: - - Action: aws-portal:View* - Effect: Allow - Resource: '*' - - Action: aws-portal:*Account - Effect: Deny - Resource: '*' - Version: '2012-10-17' + - Action: aws-portal:View* + Effect: Allow + Resource: "*" + - Action: aws-portal:*Account + Effect: Deny + Resource: "*" + Version: "2012-10-17" Type: AWS::IAM::ManagedPolicy rSysAdmin: Properties: @@ -274,54 +275,54 @@ Resources: rSysAdminPolicy: Properties: Groups: - - Ref: rSysAdmin + - Ref: rSysAdmin PolicyDocument: Statement: - - Condition: - Bool: - aws:MultiFactorAuthPresent: 'true' - Effect: Allow - NotAction: iam:* - Resource: '*' - - Action: aws-portal:*Billing - Effect: Deny - Resource: '*' - - Action: - - cloudtrail:DeleteTrail - - cloudtrail:StopLogging - - cloudtrail:UpdateTrail - Effect: Deny - Resource: '*' - - Action: - - kms:Create* - - kms:Revoke* - - kms:Enable* - - kms:Get* - - kms:Disable* - - kms:Delete* - - kms:Put* - - kms:Update* - Effect: Deny - Resource: '*' - Version: '2012-10-17' + - Condition: + Bool: + aws:MultiFactorAuthPresent: "true" + Effect: Allow + NotAction: iam:* + Resource: "*" + - Action: aws-portal:*Billing + Effect: Deny + Resource: "*" + - Action: + - cloudtrail:DeleteTrail + - cloudtrail:StopLogging + - cloudtrail:UpdateTrail + Effect: Deny + Resource: "*" + - Action: + - kms:Create* + - kms:Revoke* + - kms:Enable* + - kms:Get* + - kms:Disable* + - kms:Delete* + - kms:Put* + - kms:Update* + Effect: Deny + Resource: "*" + Version: "2012-10-17" Roles: - - Ref: rSysAdminRole + - Ref: rSysAdminRole Type: AWS::IAM::ManagedPolicy rSysAdminProfile: DependsOn: rSysAdminRole Properties: Path: / Roles: - - Ref: rSysAdminRole + - Ref: rSysAdminRole Type: AWS::IAM::InstanceProfile rSysAdminRole: Properties: AssumeRolePolicyDocument: Statement: - - Action: - - sts:AssumeRole - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com Type: AWS::IAM::Role diff --git a/test/integration/test_patched_specs.py b/test/integration/test_patched_specs.py index c9bd311d39..559835c44e 100644 --- a/test/integration/test_patched_specs.py +++ b/test/integration/test_patched_specs.py @@ -14,26 +14,19 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -import json import six -import pkg_resources +from cfnlint.helpers import load_resource +from cfnlint.data import CloudSpecs from testlib.testcase import BaseTestCase class TestPatchedSpecs(BaseTestCase): """Test Patched spec files """ + def setUp(self): """ SetUp template object""" - filename = '../../src/cfnlint/data/CloudSpecs/us-east-1.json' - - filename = pkg_resources.resource_filename( - __name__, - filename - ) - - with open(filename) as fp: - self.spec = json.load(fp) + self.spec = load_resource(CloudSpecs, 'us-east-1.json') def test_resource_type_values(self): """Test Resource Type Value""" @@ -41,24 +34,28 @@ def test_resource_type_values(self): for p_name, p_values in r_values.get('Properties').items(): p_value_type = p_values.get('Value', {}).get('ValueType') if p_value_type: - self.assertIn(p_value_type, self.spec.get('ValueTypes'), 'ResourceType: %s, Property: %s' % (r_name, p_name)) + self.assertIn(p_value_type, self.spec.get('ValueTypes'), + 'ResourceType: %s, Property: %s' % (r_name, p_name)) # List Value if a singular value is set and the type is List if p_values.get('Type') == 'List': p_list_value_type = p_values.get('Value', {}).get('ListValueType') if p_list_value_type: - self.assertIn(p_list_value_type, self.spec.get('ValueTypes'), 'ResourceType: %s, Property: %s' % (r_name, p_name)) + self.assertIn(p_list_value_type, self.spec.get('ValueTypes'), + 'ResourceType: %s, Property: %s' % (r_name, p_name)) def test_property_type_values(self): """Test Property Type Values""" def _test_property_type_values(values, r_name, p_name): p_value_type = values.get('Value', {}).get('ValueType') if p_value_type: - self.assertIn(p_value_type, self.spec.get('ValueTypes'), 'PropertyType: %s, Property: %s' % (r_name, p_name)) + self.assertIn(p_value_type, self.spec.get('ValueTypes'), + 'PropertyType: %s, Property: %s' % (r_name, p_name)) # List Value if a singular value is set and the type is List if values.get('Type') == 'List': p_list_value_type = values.get('Value', {}).get('ListValueType') if p_list_value_type: - self.assertIn(p_list_value_type, self.spec.get('ValueTypes'), 'ResourceType: %s, Property: %s' % (r_name, p_name)) + self.assertIn(p_list_value_type, self.spec.get('ValueTypes'), + 'ResourceType: %s, Property: %s' % (r_name, p_name)) for r_name, r_values in self.spec.get('PropertyTypes').items(): if r_values.get('Properties') is None: @@ -86,7 +83,8 @@ def _test_sub_properties(self, resource_name, v_propertyname, v_propertyvalues): # If the subproperty is not found, check if it exists with the resource in the property property_exists = True - self.assertEqual(property_exists, True, 'Specified property type {} not found for property {}'.format(v_subproperty_type, v_propertyname)) + self.assertEqual(property_exists, True, 'Specified property type {} not found for property {}'.format( + v_subproperty_type, v_propertyname)) def test_sub_properties(self): """Test Resource sub-Property definitions""" @@ -128,7 +126,8 @@ def test_property_value_types(self): number_max = 0 number_min = 0 for p_name, p_values in v_values.items(): - self.assertIn(p_name, ['Ref', 'GetAtt', 'AllowedValues', 'AllowedPattern', 'AllowedPatternRegex', 'ListMin', 'ListMax', 'JsonMax', 'NumberMax', 'NumberMin', 'StringMax', 'StringMin']) + self.assertIn(p_name, ['Ref', 'GetAtt', 'AllowedValues', 'AllowedPattern', 'AllowedPatternRegex', + 'ListMin', 'ListMax', 'JsonMax', 'NumberMax', 'NumberMin', 'StringMax', 'StringMin']) if p_name == 'NumberMin': number_min = p_values @@ -141,34 +140,47 @@ def test_property_value_types(self): if p_name in ['StringMin', 'StringMax']: string_count += 1 if p_name == 'Ref': - self.assertIsInstance(p_values, dict, 'ValueTypes: %s, Type: %s' % (v_name, p_name)) + self.assertIsInstance( + p_values, dict, 'ValueTypes: %s, Type: %s' % (v_name, p_name)) for r_name, r_value in p_values.items(): - self.assertIn(r_name, ['Resources', 'Parameters'], 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) - self.assertIsInstance(r_value, list, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) + self.assertIn(r_name, ['Resources', 'Parameters'], 'ValueTypes: %s, Type: %s, Additional Type: %s' % ( + v_name, p_name, r_name)) + self.assertIsInstance( + r_value, list, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) if r_name == 'Parameters': for r_list_value in r_value: - self.assertIsInstance(r_list_value, six.string_types, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) - self.assertIn(r_list_value, self.spec.get('ParameterTypes'), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) + self.assertIsInstance( + r_list_value, six.string_types, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) + self.assertIn(r_list_value, self.spec.get( + 'ParameterTypes'), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) elif r_name == 'Resources': for r_list_value in r_value: - self.assertIsInstance(r_list_value, six.string_types, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) - self.assertIn(r_list_value, self.spec.get('ResourceTypes'), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) + self.assertIsInstance( + r_list_value, six.string_types, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) + self.assertIn(r_list_value, self.spec.get( + 'ResourceTypes'), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, r_name)) elif p_name == 'GetAtt': - self.assertIsInstance(p_values, dict, 'ValueTypes: %s, Type: %s' % (v_name, p_name)) + self.assertIsInstance( + p_values, dict, 'ValueTypes: %s, Type: %s' % (v_name, p_name)) for g_name, g_value in p_values.items(): - self.assertIsInstance(g_value, six.string_types, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, g_name)) - self.assertIn(g_name, self.spec.get('ResourceTypes'), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, g_name)) - self.assertIn(g_value, self.spec.get('ResourceTypes', {}).get(g_name, {}).get('Attributes', {}), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, g_name)) + self.assertIsInstance( + g_value, six.string_types, 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, g_name)) + self.assertIn(g_name, self.spec.get( + 'ResourceTypes'), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, g_name)) + self.assertIn(g_value, self.spec.get('ResourceTypes', {}).get(g_name, {}).get( + 'Attributes', {}), 'ValueTypes: %s, Type: %s, Additional Type: %s' % (v_name, p_name, g_name)) elif p_name == 'AllowedValues': self.assertIsInstance(p_values, list) for l_value in p_values: - self.assertIsInstance(l_value, six.string_types, 'ValueTypes: %s, Type: %s' % (v_name, p_name)) + self.assertIsInstance(l_value, six.string_types, + 'ValueTypes: %s, Type: %s' % (v_name, p_name)) self.assertIn(list_count, [0, 2], 'Both ListMin and ListMax must be specified') self.assertIn(number_count, [0, 2], 'Both NumberMin and NumberMax must be specified') self.assertIn(string_count, [0, 2], 'Both StringMin and StringMax must be specified') if number_count == 2: - self.assertTrue((number_max > number_min), 'NumberMax must be greater than NumberMin') + self.assertTrue((number_max > number_min), + 'NumberMax must be greater than NumberMin') def test_parameter_types(self): """Test Parameter Types""" diff --git a/test/module/maintenance/test_patch_spec.py b/test/module/maintenance/test_patch_spec.py index 3fbd9fc052..972fbebefc 100644 --- a/test/module/maintenance/test_patch_spec.py +++ b/test/module/maintenance/test_patch_spec.py @@ -14,27 +14,25 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -import json import logging -import pkg_resources +import test.fixtures.specs +from test.testlib.testcase import BaseTestCase +import cfnlint.helpers from cfnlint.maintenance import patch_spec -from testlib.testcase import BaseTestCase + LOGGER = logging.getLogger('cfnlint.maintenance') LOGGER.addHandler(logging.NullHandler()) + class TestPatchJson(BaseTestCase): """Used for Testing Rules""" def setUp(self): """Setup""" region = 'us-east-1' - filename = pkg_resources.resource_filename( - __name__, - '../../fixtures/specs/%s.json' % region, - ) - with open(filename, 'r') as f: - self.spec = json.loads(f.read()) + + self.spec = cfnlint.helpers.load_resource(test.fixtures.specs, '%s.json' % region) def test_success_rds_dbcluster(self): """Success test""" @@ -43,9 +41,12 @@ def test_success_rds_dbcluster(self): patched['PropertyTypes']['AWS::CloudFront::Distribution.DistributionConfig']['Properties']['DefaultCacheBehavior']['Required']) self.assertTrue( patched['PropertyTypes']['AWS::CloudFront::Distribution.DistributionConfig']['Properties']['Origins']['Required']) - self.assertTrue(patched['PropertyTypes']['AWS::Cognito::UserPool.SmsConfiguration']['Properties']['ExternalId']['Required']) - self.assertEqual(patched['ResourceTypes']['AWS::ServiceDiscovery::Instance']['Properties']['InstanceAttributes']['Type'], 'Map') - self.assertEqual(patched['ResourceTypes']['AWS::ServiceDiscovery::Instance']['Properties']['InstanceAttributes']['PrimitiveItemType'], 'String') + self.assertTrue(patched['PropertyTypes']['AWS::Cognito::UserPool.SmsConfiguration'] + ['Properties']['ExternalId']['Required']) + self.assertEqual(patched['ResourceTypes']['AWS::ServiceDiscovery::Instance'] + ['Properties']['InstanceAttributes']['Type'], 'Map') + self.assertEqual(patched['ResourceTypes']['AWS::ServiceDiscovery::Instance'] + ['Properties']['InstanceAttributes']['PrimitiveItemType'], 'String') def test_success_sbd_domain_removed(self): """Success removal of SBD Domain form unsupported regions""" diff --git a/test/rules/resources/properties/test_allowed_pattern.py b/test/rules/resources/properties/test_allowed_pattern.py index 02712028f1..f61add6cf3 100644 --- a/test/rules/resources/properties/test_allowed_pattern.py +++ b/test/rules/resources/properties/test_allowed_pattern.py @@ -14,15 +14,18 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -import json -import pkg_resources import re +import json + from cfnlint.rules.resources.properties.AllowedPattern import AllowedPattern # pylint: disable=E0401 +from cfnlint.helpers import load_resource +from cfnlint.data import CloudSpecs from ... import BaseRuleTestCase class TestAllowedPattern(BaseRuleTestCase): """Test Allowed Value Property Configuration""" + def setUp(self): """Setup""" super(TestAllowedPattern, self).setUp() @@ -31,15 +34,7 @@ def setUp(self): 'test/fixtures/templates/good/resources/properties/allowed_pattern.yaml' ] - # Load the specfile to validate all the regexes specified - filename = '../../../../src/cfnlint/data/CloudSpecs/us-east-1.json' - filename = pkg_resources.resource_filename( - __name__, - filename - ) - - with open(filename) as fp: - self.spec = json.load(fp) + self.spec = load_resource(CloudSpecs, 'us-east-1.json') def test_file_positive(self): """Test Positive""" @@ -57,4 +52,5 @@ def test_valid_regex(self): try: re.compile(p_regex) except re.error: - self.fail("Invalid regex value %s specified for ValueType %s" % (p_regex, r_name)) + self.fail("Invalid regex value %s specified for ValueType %s" % + (p_regex, r_name)) diff --git a/tox.ini b/tox.ini index 9acc340b08..bc82553afe 100644 --- a/tox.ini +++ b/tox.ini @@ -53,4 +53,4 @@ deps = pylint commands = pip install -e . - pylint --load-plugins pylint_quotes src/cfnlint + pylint --ignored-modules=cfnlint --load-plugins pylint_quotes src/cfnlint