Skip to content

Commit

Permalink
fix(cfn-lint): backwards compatible support for cfn-lint 1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
dhutchison committed Oct 3, 2024
1 parent 2f5de08 commit e2ac815
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
42 changes: 32 additions & 10 deletions taskcat/_cfn_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,26 @@
import re
import textwrap

import cfnlint.config
import cfnlint.core
import cfnlint.helpers
import cfnlint.version
from cfnlint.config import ConfigMixIn as CfnLintConfig
from jsonschema.exceptions import ValidationError
from taskcat._common_utils import neglect_submodule_templates
from taskcat._config import Config
from taskcat._dataclasses import Templates

# Ignoring linting errors here as pylint doesn't seem to handle the conditional nature
if cfnlint.version.__version__.startswith("0."):
from cfnlint.core import ( # pylint:disable=no-name-in-module, ungrouped-imports
CfnLintExitException,
)
else:
from cfnlint.runner import ( # pylint:disable=no-name-in-module, ungrouped-imports
CfnLintExitException,
)

LOG = logging.getLogger(__name__)


Expand All @@ -32,8 +44,24 @@ def __init__(self, config: Config, templates: Templates, strict: bool = False):
except ValidationError as e:
LOG.error("Error parsing cfn-lint config file: %s", str(e))
raise

# There is a change in the way that the cfn lint config class functions between the 0.x and 1.x versions.
# In 1.x, the append_rules property getter includes the default rule set along with the loaded configuration
# https://github.com/aws-cloudformation/cfn-lint/blob/23ee527fadb43e4fd54238eeea5bc3a169175c91/src/cfnlint/config.py#L773
# In 0.x, it only returned the loaded configuration.
# https://github.com/aws-cloudformation/cfn-lint/blob/f006cb5d8c7056923f3f21b31c14edfeed3804b5/src/cfnlint/config.py#L730
#
# This causes issues for us as the get_rules method combines the supplied value with the default rule list,
# resulting in a duplicate rule error. get_rules has always behaved this way though, so not sure if we have just missed something
# in the intended approach to calling this.
if cfnlint.version.__version__.startswith("0."):
append_rules = self._cfnlint_config.append_rules
else:
append_rules = self._cfnlint_config.append_rules
append_rules.remove(cfnlint.config._DEFAULT_RULESDIR)

self._rules = cfnlint.core.get_rules(
self._cfnlint_config.append_rules,
append_rules,
self._cfnlint_config.ignore_checks,
self._cfnlint_config.include_checks,
self._cfnlint_config.configure_rules,
Expand Down Expand Up @@ -91,17 +119,11 @@ def _run_checks(self, template, name, lint_errors, lints):
tpath = str(template.template_path)
results = []
try:
(_, rules, template_matches) = cfnlint.core.get_template_rules(
tpath, self._cfnlint_config
results = cfnlint.core.run_checks(
tpath, template.template, self._rules, lints[name]["regions"]
)
if template_matches:
results = template_matches
else:
results = cfnlint.core.run_checks(
tpath, template.template, rules, lints[name]["regions"]
)
lints[name]["results"][tpath] = results
except cfnlint.core.CfnLintExitException as e:
except CfnLintExitException as e:
lint_errors.add(str(e))
lints[name]["results"][tpath] = results

Expand Down
24 changes: 18 additions & 6 deletions tests/test_cfn_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import yaml

import cfnlint.version
from taskcat._cfn_lint import Lint
from taskcat._config import Config

Expand All @@ -30,6 +31,22 @@ def __init__(self):
"(This code may only work with `package` cli command as the property"
"(Resources/Name/Properties/TemplateURL) is a string) matched /private/tmp/lint_test/test-config-three/templates/taskcat_test_template_test1:1"
)
if cfnlint.version.__version__.startswith("0."):
invalid_type_error = [
f"[E3001: Basic CloudFormation Resource Check] (Invalid or "
f"unsupported Type AWS::Not::Exist for resource Name in "
f"eu-west-1) matched "
f"{test_two_path}:1"
]
else:
# The format of this message seems to change in 1.3.0 onwards
# (prior 1.x versions were pre-releases so not supporting them)
invalid_type_error = [
f"[E3006: Validate the CloudFormation resource type] (Resource "
f"type 'AWS::Not::Exist' does not exist in "
f"'eu-west-1') matched "
f"{test_two_path}:1"
]
test_cases = [
{
"config": {
Expand Down Expand Up @@ -71,12 +88,7 @@ def __init__(self):
"/tmp/lint_test/test-config-two/templates/taskcat_test_"
"template_test1"
).resolve()
): [
f"[E3001: Basic CloudFormation Resource Check] (Invalid or "
f"unsupported Type AWS::Not::Exist for resource Name in "
f"eu-west-1) matched "
f"{test_two_path}:1"
]
): invalid_type_error
},
"template": Path(
"/tmp/lint_test/test-config-two/templates/taskcat_test_template"
Expand Down

0 comments on commit e2ac815

Please sign in to comment.