Esempio n. 1
0
class TestInclude(BaseTestCase):
    """Used for Testing Rules"""
    def setUp(self):
        """Setup"""
        self.collection = RulesCollection()
        self.collection.register(Configuration())

    def tearDown(self):
        """Tear Down"""
        # Reset the Spec override to prevent other tests to fail
        cfnlint.helpers.initialize_specs()

    def test_fail_run(self):
        """Failure test required"""
        filename = 'test/fixtures/templates/bad/override/include.yaml'
        template = self.load_template(filename)

        with open('test/fixtures/templates/override_spec/include.json') as fp:
            custom_spec = json.load(fp)
        cfnlint.helpers.set_specs(custom_spec)

        bad_runner = Runner(self.collection, filename, template, ['us-east-1'],
                            [])
        errs = bad_runner.run()
        self.assertEqual(2, len(errs))
Esempio n. 2
0
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection(include_experimental=True)
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            "config_rule": {
                "filename": 'test/fixtures/templates/quickstart/config-rules.json',
                "failures": 6
            },
            "iam": {
                "filename": 'test/fixtures/templates/quickstart/iam.json',
                "failures": 5
            },
            "nat_instance": {
                "filename": 'test/fixtures/templates/quickstart/nat-instance.json',
                "failures": 2
            },
            "vpc_management": {
                "filename": 'test/fixtures/templates/quickstart/vpc-management.json',
                "failures": 35
            },
            "vpc": {
                "filename": 'test/fixtures/templates/quickstart/vpc.json',
                "failures": 40
            },
            "poller": {
                "filename": 'test/fixtures/templates/public/lambda-poller.json',
                "failures": 1
            }
        }
Esempio n. 3
0
 def setUp(self):
     """ SetUp template object"""
     self.rules = RulesCollection()
     self.rules.include_rules = ['I', 'W', 'E']
     rulesdirs = [DEFAULT_RULESDIR]
     for rulesdir in rulesdirs:
         self.rules.create_from_directory(rulesdir)
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection()
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            "generic_good": {
                "filename": 'test/fixtures/templates/good/generic.yaml'
            }
        }

        self.perfect_rule = 'test/fixtures/custom_rules/good/custom_rule_perfect.txt'
        self.valid_boolean = 'test/fixtures/custom_rules/good/custom_rule_boolean.txt'
        self.invalid_boolean = 'test/fixtures/custom_rules/bad/custom_rule_invalid_boolean.txt'
        self.invalid_op = 'test/fixtures/custom_rules/bad/custom_rule_invalid_op.txt'
        self.invalid_prop = 'test/fixtures/custom_rules/bad/custom_rule_invalid_prop.txt'
        self.invalid_propkey = 'test/fixtures/custom_rules/bad/custom_rule_invalid_propkey.txt'
        self.invalid_rt = 'test/fixtures/custom_rules/bad/custom_rule_invalid_rt.txt'
        self.invalid_equal = 'test/fixtures/custom_rules/bad/custom_rule_invalid_equal.txt'
        self.invalid_not_equal = 'test/fixtures/custom_rules/bad/custom_rule_invalid_not_equal.txt'
        self.invalid_set = 'test/fixtures/custom_rules/bad/custom_rule_invalid_set.txt'
        self.invalid_not_set = 'test/fixtures/custom_rules/bad/custom_rule_invalid_not_set.txt'
        self.invalid_greater_than = 'test/fixtures/custom_rules/bad/custom_rule_invalid_greater_than.txt'
        self.invalid_less_than = 'test/fixtures/custom_rules/bad/custom_rule_invalid_less_than.txt'
Esempio n. 5
0
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection(include_rules=['I'])
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            'generic': {
                "filename": 'test/fixtures/templates/good/generic.yaml',
                "failures": 0
            },
            'minimal': {
                "filename": 'test/fixtures/templates/good/minimal.yaml',
                "failures": 0
            },
            'transform': {
                "filename": 'test/fixtures/templates/good/transform.yaml',
                "failures": 0
            },
            'transform_bad': {
                "filename": 'test/fixtures/templates/bad/transform_serverless_template.yaml',
                "failures": 3
            },
            'conditions': {
                "filename": 'test/fixtures/templates/good/conditions.yaml',
                "failures": 0
            },
            'resources_codepipeline': {
                'filename': 'test/fixtures/templates/good/resources_codepipeline.yaml',
                'failures': 0
            },
            'transform_serverless_api': {
                'filename': 'test/fixtures/templates/good/transform_serverless_api.yaml',
                'failures': 0
            },
            'transform_serverless_function': {
                'filename': 'test/fixtures/templates/good/transform_serverless_function.yaml',
                'failures': 0
            },
            'transform_serverless_globals': {
                'filename': 'test/fixtures/templates/good/transform_serverless_globals.yaml',
                'failures': 1
            },
            'transform_list': {
                'filename': 'test/fixtures/templates/good/transform/list_transform.yaml',
                'failures': 0
            },
            'transform_list_many': {
                'filename': 'test/fixtures/templates/good/transform/list_transform_many.yaml',
                'failures': 0
            },
            'transform_list_not_sam': {
                'filename': 'test/fixtures/templates/good/transform/list_transform_not_sam.yaml',
                'failures': 0
            }
        }
Esempio n. 6
0
class TestYamlParse(BaseTestCase):
    """Test YAML Parsing """

    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection()
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            "config_rule": {
                "filename": 'test/fixtures/templates/public/lambda-poller.yaml',
                "failures": 1
            },
            "generic_bad": {
                "filename": 'test/fixtures/templates/bad/generic.yaml',
                "failures": 29
            }
        }

    def test_success_parse(self):
        """Test Successful YAML Parsing"""
        for _, values in self.filenames.items():
            filename = values.get('filename')
            failures = values.get('failures')
            template = cfnlint.decode.cfn_yaml.load(filename)
            cfn = Template(filename, template, ['us-east-1'])

            matches = []
            matches.extend(self.rules.run(filename, cfn))
            assert len(matches) == failures, 'Expected {} failures, got {} on {}'.format(
                failures, len(matches), filename)

    def test_success_parse_stdin(self):
        """Test Successful YAML Parsing through stdin"""
        for _, values in self.filenames.items():
            filename = '-'
            failures = values.get('failures')
            with open(values.get('filename'), 'r') as fp:
                file_content = fp.read()

            with patch('sys.stdin', StringIO(file_content)):
                template = cfnlint.decode.cfn_yaml.load(filename)
                cfn = Template(filename, template, ['us-east-1'])

                matches = []
                matches.extend(self.rules.run(filename, cfn))
                assert len(matches) == failures, 'Expected {} failures, got {} on {}'.format(
                    failures, len(matches), values.get('filename'))


    def test_map_failure(self):
        """Test a failure is passed on unhashable map"""
        filename = 'test/fixtures/templates/bad/core/parse_invalid_map.yaml'

        self.assertRaises(cfnlint.decode.cfn_yaml.CfnParseError, cfnlint.decode.cfn_yaml.load, filename)
Esempio n. 7
0
def get_rules(rulesdir, ignore_rules, include_rules, configure_rules=None, include_experimental=False):
    """Get rules"""
    rules = RulesCollection(ignore_rules, include_rules, configure_rules, include_experimental)
    rules_dirs = [DEFAULT_RULESDIR] + rulesdir
    try:
        for rules_dir in rules_dirs:
            rules.create_from_directory(rules_dir)
    except OSError as e:
        raise UnexpectedRuleException('Tried to append rules but got an error: %s' % str(e), 1)
    return rules
Esempio n. 8
0
 def run_tests(self, rulename):
     for _, values in self.filenames.items():
         filename = values.get('filename')
         template = cfnlint.decode.cfn_yaml.load(filename)
         cfn = Template(filename, template, ['us-east-1'])
         rules = RulesCollection(None, None, None, False, None)
         rules.create_from_custom_rules_file(rulename)
         runner = cfnlint.runner.Runner(rules, filename, template, None,
                                        None)
         return runner.run()
Esempio n. 9
0
class TestDuplicate(BaseTestCase):
    """Test Duplicates Parsing """

    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection()
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

    def test_success_run(self):
        """Test success run"""

        filename = 'test/fixtures/templates/good/generic.yaml'

        try:
            cfnlint.decode.cfn_yaml.load(filename)
        except cfnlint.decode.cfn_yaml.CfnParseError:
            assert(False)
            return

        assert(True)

    def test_fail_json_run(self):
        """Test failure run"""

    def test_fail_run(self):
        """Test failure run"""

        filename = 'test/fixtures/templates/bad/duplicate.json'

        try:
            with open(filename) as fp:
                json.load(fp, cls=cfnlint.decode.cfn_json.CfnJSONDecoder)
        except cfnlint.decode.cfn_json.JSONDecodeError:
            assert(True)
            return

        assert(False)

    def test_fail_yaml_run(self):
        """Test failure run"""

        filename = 'test/fixtures/templates/bad/duplicate.yaml'

        try:
            cfnlint.decode.cfn_yaml.load(filename)
        except cfnlint.decode.cfn_yaml.CfnParseError:
            assert(True)
            return

        assert(False)
Esempio n. 10
0
class TestBaseTemplate(BaseRuleTestCase):
    """Test base template"""
    def setUp(self):
        """Setup"""
        self.collection = RulesCollection()
        self.collection.register(Base())

    def test_file_negative(self):
        """Failure test"""
        failure = 'test/fixtures/templates/bad/template.yaml'
        try:
            Runner(self.collection, failure, True)
            self.assertEqual(1, 0)
        except Exception:
            pass
Esempio n. 11
0
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection()
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            "config_rule": {
                "filename": 'test/fixtures/templates/public/lambda-poller.yaml',
                "failures": 1
            },
            "generic_bad": {
                "filename": 'test/fixtures/templates/bad/generic.yaml',
                "failures": 29
            }
        }
Esempio n. 12
0
    def test_success_filtering_of_rules_exclude_longer(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_e0010(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0010'

        class rule_e0002(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0002'

        rules_to_add = [rule_e0000(), rule_e0010(), rule_e0002()]
        rules = RulesCollection(ignore_rules=['E0002'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 2)
        for rule in rules:
            self.assertIn(rule.id, ['E0000', 'E0010'])
Esempio n. 13
0
    def test_success_filtering_of_rules_include_info(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_w0000(CloudFormationLintRule):
            """Warning Rule"""
            id = 'W0000'

        class rule_i0000(CloudFormationLintRule):
            """Info Rule"""
            id = 'I0000'

        rules_to_add = [rule_e0000(), rule_w0000(), rule_i0000()]
        rules = RulesCollection(ignore_rules=None, include_rules=['I'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 3)
        for rule in rules:
            self.assertIn(rule.id, ['I0000', 'W0000', 'E0000'])
Esempio n. 14
0
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection(
            include_rules=['I'],
            include_experimental=True,
            configure_rules={'E3012': {
                'strict': 'false'
            }})
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            'nist_high_master': {
                'filename':
                'test/fixtures/templates/quickstart/nist_high_master.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/nist_high_master.json'
            },
            'nist_application': {
                'filename':
                'test/fixtures/templates/quickstart/nist_application.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/nist_application.json'
            },
            'openshift': {
                'filename':
                'test/fixtures/templates/quickstart/openshift.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/openshift.json'
            },
            'cis_benchmark': {
                'filename':
                'test/fixtures/templates/quickstart/cis_benchmark.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/cis_benchmark.json'
            }
        }
Esempio n. 15
0
def get_rules(append_rules, ignore_rules, include_rules, configure_rules=None, include_experimental=False,
              mandatory_rules=None, custom_rules=None):
    rules = RulesCollection(ignore_rules, include_rules, configure_rules,
                            include_experimental, mandatory_rules)
    rules_paths = [DEFAULT_RULESDIR] + append_rules
    try:
        for rules_path in rules_paths:
            if rules_path and os.path.isdir(os.path.expanduser(rules_path)):
                rules.create_from_directory(rules_path)
            else:
                rules.create_from_module(rules_path)

        rules.create_from_custom_rules_file(custom_rules)
    except (OSError, ImportError) as e:
        raise UnexpectedRuleException('Tried to append rules but got an error: %s' % str(e), 1)
    return rules
class TestDirectives(BaseTestCase):
    """Test Directives """
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection(include_rules=['I'])
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

    def test_templates(self):
        """Test ignoring certain rules"""
        filename = 'test/fixtures/templates/bad/core/directives.yaml'
        failures = 5

        template = cfnlint.decode.cfn_yaml.load(filename)
        runner = Runner(self.rules, filename, template, ['us-east-1'])
        matches = []
        matches.extend(runner.transform())
        if not matches:
            matches.extend(runner.run())
        assert len(
            matches) == failures, 'Expected {} failures, got {} on {}'.format(
                failures, len(matches), filename)
Esempio n. 17
0
class TestNulls(BaseTestCase):
    """Test Null Value Parsing """
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection()
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

    def test_success_run(self):
        """Test success run"""

        filename = 'test/fixtures/templates/good/generic.yaml'

        try:
            cfnlint.decode.cfn_yaml.load(filename)
        except cfnlint.decode.cfn_yaml.CfnParseError:
            assert (False)
            return

        assert (True)

    def test_fail_json_run(self):
        """Test failure run"""
    def test_success_filtering_of_rules_exclude_mandatory_long(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_e0010(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0010'

        class rule_e0002(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0002'

        class rule_w0000(CloudFormationLintRule):
            """Warning Rule"""
            id = 'W0000'

        rules_to_add = [rule_e0000, rule_e0010, rule_e0002, rule_w0000]
        rules = RulesCollection(ignore_rules=['E'], mandatory_rules=['E000'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 3)
        for rule in rules:
            self.assertIn(rule.id, ['E0000', 'E0002', 'W0000'])
    def test_update_docs(self):
        collection = RulesCollection(include_rules=['I'],
                                     include_experimental=True)

        if sys.version_info.major == 3:
            builtin_module_name = 'builtins'
        else:
            builtin_module_name = '__builtin__'

        mo = mock_open(read_data=self.TEST_TEXT)
        mo.return_value.__iter__ = lambda self: self
        mo.return_value.__iter__ = lambda self: iter(self.readline, '')
        with patch('{}.open'.format(builtin_module_name),
                   mo) as mock_builtin_open:
            cfnlint.maintenance.update_documentation(collection)

            expected_calls = [
                call('\n'),
                call('Regular Text\n'),
                call('## Rules\n'),
                call(
                    '(_This documentation is generated by running `cfn-lint --update-documentation`, do not alter this manually_)\n\n'
                ),
                call(
                    'The following **{}** rules are applied by this linter:\n\n'
                    .format(len(collection) + 3)),
                call(
                    '| Rule ID  | Title | Description | Config<br />(Name:Type:Default) | Source | Tags |\n'
                ),
                call(
                    '| -------- | ----- | ----------- | ---------- | ------ | ---- |\n'
                ),
                call(
                    '| [E0000<a name="E0000"></a>](../src/cfnlint/rules/__init__.py) | Parsing error found when parsing the template | Checks for JSON/YAML formatting errors in your template |  | [Source](https://github.com/aws-cloudformation/cfn-python-lint) | `base` |\n'
                ),
                call(
                    '| [E0001<a name="E0001"></a>](../src/cfnlint/rules/__init__.py) | Error found when transforming the template | Errors found when performing transformation on the template |  | [Source](https://github.com/aws-cloudformation/cfn-python-lint) | `base`,`transform` |\n'
                ),
                call(
                    '| [E0002<a name="E0002"></a>](../src/cfnlint/rules/__init__.py) | Error processing rule on the template | Errors found when processing a rule on the template |  | [Source](https://github.com/aws-cloudformation/cfn-python-lint) | `base`,`rule` |\n'
                ),
                call('\n\\* experimental rules\n'),
            ]
            mock_builtin_open.return_value.write.assert_has_calls(
                expected_calls)
            self.assertEqual(len(expected_calls),
                             mock_builtin_open.return_value.write.call_count)
Esempio n. 20
0
class TestQuickStartTemplates(BaseTestCase):
    """Test QuickStart Templates Parsing """

    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection(include_rules=['I'])
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            'generic': {
                "filename": 'test/fixtures/templates/good/generic.yaml',
                "failures": 0
            },
            'minimal': {
                "filename": 'test/fixtures/templates/good/minimal.yaml',
                "failures": 0
            },
            'transform': {
                "filename": 'test/fixtures/templates/good/transform.yaml',
                "failures": 0
            },
            'transform_bad': {
                "filename": 'test/fixtures/templates/bad/transform_serverless_template.yaml',
                "failures": 3
            },
            'conditions': {
                "filename": 'test/fixtures/templates/good/conditions.yaml',
                "failures": 0
            },
            'resources_codepipeline': {
                'filename': 'test/fixtures/templates/good/resources_codepipeline.yaml',
                'failures': 0
            },
            'transform_serverless_api': {
                'filename': 'test/fixtures/templates/good/transform_serverless_api.yaml',
                'failures': 0
            },
            'transform_serverless_function': {
                'filename': 'test/fixtures/templates/good/transform_serverless_function.yaml',
                'failures': 0
            },
            'transform_serverless_globals': {
                'filename': 'test/fixtures/templates/good/transform_serverless_globals.yaml',
                'failures': 1
            },
            'transform_list': {
                'filename': 'test/fixtures/templates/good/transform/list_transform.yaml',
                'failures': 0
            },
            'transform_list_many': {
                'filename': 'test/fixtures/templates/good/transform/list_transform_many.yaml',
                'failures': 0
            },
            'transform_list_not_sam': {
                'filename': 'test/fixtures/templates/good/transform/list_transform_not_sam.yaml',
                'failures': 0
            }
        }

    def test_templates(self):
        """Test Successful JSON Parsing"""
        for _, values in self.filenames.items():
            filename = values.get('filename')
            failures = values.get('failures')
            template = cfnlint.decode.cfn_yaml.load(filename)

            runner = Runner(self.rules, filename, template, ['us-east-1'])
            matches = []
            matches.extend(runner.transform())
            if not matches:
                matches.extend(runner.run())
            assert len(matches) == failures, 'Expected {} failures, got {} on {}'.format(
                failures, len(matches), filename)
Esempio n. 21
0
 def setUp(self):
     """Setup"""
     self.collection = RulesCollection()
     self.collection.register(Configuration())
Esempio n. 22
0
 def setUp(self):
     """Setup"""
     self.collection = RulesCollection(include_rules=['I'],
                                       include_experimental=True)
Esempio n. 23
0
class TestCustomRuleParsing(BaseTestCase):
    """Test Node Objects """
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection()
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            "generic_good": {
                "filename": 'test/fixtures/templates/good/generic.yaml'
            }
        }

        self.perfect_rule = 'test/fixtures/custom_rules/good/custom_rule_perfect.txt'
        self.invalid_op = 'test/fixtures/custom_rules/bad/custom_rule_invalid_op.txt'
        self.invalid_prop = 'test/fixtures/custom_rules/bad/custom_rule_invalid_prop.txt'
        self.invalid_propkey = 'test/fixtures/custom_rules/bad/custom_rule_invalid_propkey.txt'
        self.invalid_rt = 'test/fixtures/custom_rules/bad/custom_rule_invalid_rt.txt'
        self.invalid_equal = 'test/fixtures/custom_rules/bad/custom_rule_invalid_equal.txt'
        self.invalid_not_equal = 'test/fixtures/custom_rules/bad/custom_rule_invalid_not_equal.txt'
        self.invalid_set = 'test/fixtures/custom_rules/bad/custom_rule_invalid_set.txt'
        self.invalid_not_set = 'test/fixtures/custom_rules/bad/custom_rule_invalid_not_set.txt'
        self.invalid_greater_than = 'test/fixtures/custom_rules/bad/custom_rule_invalid_greater_than.txt'
        self.invalid_less_than = 'test/fixtures/custom_rules/bad/custom_rule_invalid_less_than.txt'

    def test_perfect_parse(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(self.perfect_rule) == [])

    def test_invalid_op(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(
            self.invalid_op)[0].message.find('not in supported') > -1)

    def test_invalid_set(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(
            self.invalid_set)[0].message.find('In set check') > -1)

    def test_invalid_not_set(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(
            self.invalid_not_set)[0].message.find('Not in set') > -1)

    def test_invalid_equal(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(
            self.invalid_equal)[0].message.find('Must equal check') > -1)

    def test_invalid_not_equal(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(
            self.invalid_not_equal)[0].message.find('Must not equal') > -1)

    def test_invalid_greater_than(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(
            self.invalid_greater_than)[0].message.find('Greater than check') >
                -1)

    def test_invalid_less_than(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(
            self.invalid_less_than)[0].message.find('Lesser than check') > -1)

    def test_invalid_prop(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(self.invalid_prop) == [])

    def test_invalid_propKey(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(self.invalid_propkey) == [])

    def test_invalid_resource_type(self):
        """Test Successful Custom_Rule Parsing"""
        assert (self.run_tests(self.invalid_rt) == [])

    def run_tests(self, rulename):
        for _, values in self.filenames.items():
            filename = values.get('filename')
            template = cfnlint.decode.cfn_yaml.load(filename)
            cfn = Template(filename, template, ['us-east-1'])
            rules = RulesCollection(None, None, None, False, None)
            rules.create_from_custom_rules_file(rulename)
            runner = cfnlint.runner.Runner(rules, filename, template, None,
                                           None)
            return runner.run()
Esempio n. 24
0
class TestQuickStartTemplatesNonStrict(BaseTestCase):
    """Test QuickStart Templates Parsing """
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection(
            include_rules=['I'],
            include_experimental=True,
            configure_rules={'E3012': {
                'strict': 'false'
            }})
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            'nist_high_master': {
                'filename':
                'test/fixtures/templates/quickstart/nist_high_master.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/nist_high_master.json'
            },
            'nist_application': {
                'filename':
                'test/fixtures/templates/quickstart/nist_application.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/nist_application.json'
            },
            'openshift': {
                'filename':
                'test/fixtures/templates/quickstart/openshift.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/openshift.json'
            },
            'cis_benchmark': {
                'filename':
                'test/fixtures/templates/quickstart/cis_benchmark.yaml',
                'results_filename':
                'test/fixtures/results/quickstart/non_strict/cis_benchmark.json'
            }
        }

    def test_templates(self):
        """Test Successful JSON Parsing"""
        for _, values in self.filenames.items():
            filename = values.get('filename')
            failures = values.get('failures')
            results_filename = values.get('results_filename')
            template = cfnlint.decode.cfn_yaml.load(filename)

            runner = Runner(self.rules, filename, template, ['us-east-1'])
            matches = []
            matches.extend(runner.transform())
            if not matches:
                matches.extend(runner.run())

            if results_filename:
                with open(results_filename) as json_data:
                    correct = json.load(json_data)

                assert len(matches) == len(
                    correct), 'Expected {} failures, got {} on {}'.format(
                        len(correct), len(matches), filename)
                for c in correct:
                    matched = False
                    for match in matches:
                        if c['Location']['Start']['LineNumber'] == match.linenumber and \
                                c['Location']['Start']['ColumnNumber'] == match.columnnumber and \
                                c['Rule']['Id'] == match.rule.id:
                            matched = True
                    assert matched is True, 'Expected error {} at line {}, column {} in matches for {}'.format(
                        c['Rule']['Id'], c['Location']['Start']['LineNumber'],
                        c['Location']['Start']['ColumnNumber'], filename)
            else:
                assert len(
                    matches
                ) == failures, 'Expected {} failures, got {} on {}'.format(
                    failures, len(matches), filename)
Esempio n. 25
0
class TestCfnJson(BaseTestCase):
    """Test JSON Parsing """
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection(include_experimental=True)
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

        self.filenames = {
            "config_rule": {
                "filename":
                'test/fixtures/templates/quickstart/config-rules.json',
                "failures": 4
            },
            "iam": {
                "filename": 'test/fixtures/templates/quickstart/iam.json',
                "failures": 5
            },
            "nat_instance": {
                "filename":
                'test/fixtures/templates/quickstart/nat-instance.json',
                "failures": 2
            },
            "vpc_management": {
                "filename":
                'test/fixtures/templates/quickstart/vpc-management.json',
                "failures": 8
            },
            "vpc": {
                "filename": 'test/fixtures/templates/quickstart/vpc.json',
                "failures": 0
            },
            "poller": {
                "filename":
                'test/fixtures/templates/public/lambda-poller.json',
                "failures": 1
            }
        }

    def test_success_parse(self):
        """Test Successful JSON Parsing"""
        for _, values in self.filenames.items():
            filename = values.get('filename')
            failures = values.get('failures')

            template = cfnlint.decode.cfn_json.load(filename)
            cfn = Template(filename, template, ['us-east-1'])

            matches = []
            matches.extend(self.rules.run(filename, cfn))
            assert len(
                matches
            ) == failures, 'Expected {} failures, got {} on {}'.format(
                failures, len(matches), filename)

    def test_success_escape_character(self):
        """Test Successful JSON Parsing"""
        failures = 1
        filename = 'test/fixtures/templates/good/decode/parsing.json'
        template = cfnlint.decode.cfn_json.load(filename)
        cfn = Template(filename, template, ['us-east-1'])

        matches = []
        matches.extend(self.rules.run(filename, cfn))
        assert len(
            matches) == failures, 'Expected {} failures, got {} on {}'.format(
                failures, len(matches), filename)

    def test_success_parse_stdin(self):
        """Test Successful JSON Parsing through stdin"""
        for _, values in self.filenames.items():
            filename = '-'
            failures = values.get('failures')
            with open(values.get('filename'), 'r') as fp:
                file_content = fp.read()
            with patch('sys.stdin', StringIO(file_content)):

                template = cfnlint.decode.cfn_json.load(filename)
                cfn = Template(filename, template, ['us-east-1'])

                matches = []
                matches.extend(self.rules.run(filename, cfn))
                assert len(
                    matches
                ) == failures, 'Expected {} failures, got {} on {}'.format(
                    failures, len(matches), values.get('filename'))

    def test_fail_run(self):
        """Test failure run"""

        filename = 'test/fixtures/templates/bad/json_parse.json'

        try:
            template = cfnlint.decode.cfn_json.load(filename)
        except cfnlint.decode.cfn_json.JSONDecodeError:
            assert (True)
            return

        assert (False)
Esempio n. 26
0
    def print_matches(self, matches, rules=None, filenames=None):
        """Output all the matches"""

        if not rules:
            rules = RulesCollection()

        # These "base" rules are not passed into formatters
        rules.extend([ParseError(), TransformError(), RuleError()])

        results = []
        for match in matches:
            results.append(
                sarif.Result(
                    rule_id=match.rule.id,
                    message=sarif.Message(text=match.message),
                    level=self._to_sarif_level(match.rule.severity),
                    locations=[
                        sarif.Location(
                            physical_location=sarif.PhysicalLocation(
                                artifact_location=sarif.ArtifactLocation(
                                    uri=match.filename,
                                    uri_base_id=self.uri_base_id,
                                ),
                                region=sarif.Region(
                                    start_column=match.columnnumber,
                                    start_line=match.linenumber,
                                    end_column=match.columnnumberend,
                                    end_line=match.linenumberend,
                                ),
                            ))
                    ],
                ))

        # Output only the rules that have matches
        matched_rules = set(r.rule_id for r in results)
        rules_map = {r.id: r for r in list(rules)}

        rules = [
            sarif.ReportingDescriptor(
                id=rule_id,
                short_description=sarif.MultiformatMessageString(
                    text=rules_map[rule_id].shortdesc),
                full_description=sarif.MultiformatMessageString(
                    text=rules_map[rule_id].description),
                help_uri=rules_map[rule_id].source_url
                if rules_map[rule_id] else None) for rule_id in matched_rules
        ]

        run = sarif.Run(
            tool=sarif.Tool(driver=sarif.ToolComponent(
                name='cfn-lint',
                short_description=sarif.MultiformatMessageString(
                    text=('Validates AWS CloudFormation templates against'
                          ' the resource specification and additional'
                          ' checks.')),
                information_uri=
                'https://github.com/aws-cloudformation/cfn-lint',
                rules=rules,
                version=cfnlint.version.__version__,
            ), ),
            original_uri_base_ids={
                self.uri_base_id:
                sarif.ArtifactLocation(
                    description=sarif.MultiformatMessageString(
                        'The directory in which cfn-lint was run.'))
            },
            results=results,
        )

        log = sarif.SarifLog(version=self.version,
                             schema_uri=self.schema,
                             runs=[run])

        # IMPORTANT: 'warning' is the default level in SARIF and will be
        # stripped by serialization.
        return to_json(log)
Esempio n. 27
0
 def setUp(self):
     """Setup"""
     self.collection = RulesCollection()
     self.collection.register(Base())
Esempio n. 28
0
class TestRulesCollection(BaseTestCase):
    """Test Template RulesCollection in cfnlint """
    def setUp(self):
        """ SetUp template object"""
        self.rules = RulesCollection()
        self.rules.include_rules = ['I', 'W', 'E']
        rulesdirs = [DEFAULT_RULESDIR]
        for rulesdir in rulesdirs:
            self.rules.create_from_directory(rulesdir)

    def test_rule_ids_unique(self):
        """Test Rule IDs are Unique"""
        existing_rules = []
        for rule in self.rules:
            self.assertFalse(rule.id in existing_rules)
            existing_rules.append(rule.id)

    def test_rule_ids_are_formatted_correctly(self):
        """Test Rule IDs are property formmated"""
        for rule in self.rules:
            self.assertIn(rule.id[0], ['W', 'I', 'E'])
            self.assertEqual(len(rule.id), 5)
            self.assertTrue(isinstance(int(rule.id[1:]), int))

    def test_success_run(self):
        """ Test Run Logic"""
        filename = 'test/fixtures/templates/good/generic.yaml'
        template = cfnlint.decode.cfn_yaml.load(filename)
        cfn = Template(filename, template, ['us-east-1'])

        matches = []
        matches.extend(self.rules.run(filename, cfn))
        assert (matches == [])

    def test_fail_run(self):
        """Test failure run"""
        filename = 'test/fixtures/templates/bad/generic.yaml'
        template = cfnlint.decode.cfn_yaml.load(filename)
        cfn = Template(filename, template, ['us-east-1'])
        expected_err_count = 36
        matches = []
        matches.extend(self.rules.run(filename, cfn))
        assert len(
            matches
        ) == expected_err_count, 'Expected {} failures, got {}'.format(
            expected_err_count, len(matches))

    def test_fail_sub_properties_run(self):
        """Test failure run"""
        filename = 'test/fixtures/templates/bad/resources/properties/onlyone.yaml'
        template = cfnlint.decode.cfn_yaml.load(filename)
        cfn = Template(filename, template, ['us-east-1'])

        matches = []
        matches.extend(self.rules.run(filename, cfn))
        self.assertEqual(
            5, len(matches),
            'Expected {} failures, got {}'.format(5, len(matches)))

    def test_success_filtering_of_rules_default(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_w0000(CloudFormationLintRule):
            """Warning Rule"""
            id = 'W0000'

        class rule_i0000(CloudFormationLintRule):
            """Info Rule"""
            id = 'I0000'

        rules_to_add = [rule_e0000(), rule_w0000(), rule_i0000()]
        rules = RulesCollection(ignore_rules=None, include_rules=None)
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 2)
        for rule in rules:
            self.assertIn(rule.id, ['W0000', 'E0000'])

    def test_success_filtering_of_rules_include_info(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_w0000(CloudFormationLintRule):
            """Warning Rule"""
            id = 'W0000'

        class rule_i0000(CloudFormationLintRule):
            """Info Rule"""
            id = 'I0000'

        rules_to_add = [rule_e0000(), rule_w0000(), rule_i0000()]
        rules = RulesCollection(ignore_rules=None, include_rules=['I'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 3)
        for rule in rules:
            self.assertIn(rule.id, ['I0000', 'W0000', 'E0000'])

    def test_success_filtering_of_rules_exclude(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_w0000(CloudFormationLintRule):
            """Warning Rule"""
            id = 'W0000'

        class rule_i0000(CloudFormationLintRule):
            """Info Rule"""
            id = 'I0000'

        rules_to_add = [rule_e0000(), rule_w0000(), rule_i0000()]
        rules = RulesCollection(ignore_rules=['E'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 1)
        for rule in rules:
            self.assertIn(rule.id, ['W0000'])

    def test_success_filtering_of_rules_exclude_long(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_e0010(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0010'

        class rule_e0002(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0002'

        rules_to_add = [rule_e0000(), rule_e0010(), rule_e0002()]
        rules = RulesCollection(ignore_rules=['E000'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 1)
        for rule in rules:
            self.assertIn(rule.id, ['E0010'])

    def test_success_filtering_of_rules_exclude_longer(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_e0010(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0010'

        class rule_e0002(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0002'

        rules_to_add = [rule_e0000(), rule_e0010(), rule_e0002()]
        rules = RulesCollection(ignore_rules=['E0002'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 2)
        for rule in rules:
            self.assertIn(rule.id, ['E0000', 'E0010'])

    def test_success_filtering_of_rules_exclude_mandatory(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_w0000(CloudFormationLintRule):
            """Warning Rule"""
            id = 'W0000'

        class rule_i0000(CloudFormationLintRule):
            """Info Rule"""
            id = 'I0000'

        rules_to_add = [rule_e0000(), rule_w0000(), rule_i0000()]
        rules = RulesCollection(ignore_rules=['E'], mandatory_rules=['E'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 2)
        for rule in rules:
            self.assertIn(rule.id, ['E0000', 'W0000'])

    def test_success_filtering_of_rules_exclude_mandatory_long(self):
        """Test extend function"""
        class rule_e0000(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0000'

        class rule_e0010(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0010'

        class rule_e0002(CloudFormationLintRule):
            """Error Rule"""
            id = 'E0002'

        class rule_w0000(CloudFormationLintRule):
            """Warning Rule"""
            id = 'W0000'

        rules_to_add = [rule_e0000(), rule_e0010(), rule_e0002(), rule_w0000()]
        rules = RulesCollection(ignore_rules=['E'], mandatory_rules=['E000'])
        rules.extend(rules_to_add)
        self.assertEqual(len(rules), 3)
        for rule in rules:
            self.assertIn(rule.id, ['E0000', 'E0002', 'W0000'])
Esempio n. 29
0
 def setUp(self):
     """Setup"""
     self.collection = RulesCollection()
     self.collection.register(Required())
Esempio n. 30
0
 def test_create_from_module(self):
     """Load rules from a module"""
     rules = RulesCollection()
     rules.create_from_module("cfnlint.rules.templates.Base")
     self.assertIn('E1001', (r.id for r in rules))