Пример #1
0
    def test_with_templates(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))

        test_templates = glob.glob(f"{dir_path}/test_templates/*.*")
        for template in test_templates:
            with open(template) as cf_script:
                cf_template = convert_json_or_yaml_to_dict(cf_script.read())

            config = Config(
                project_name=template, service_name=template, stack_name=template, rules=DEFAULT_RULES.keys()
            )

            # Scan result
            result = Result()

            rules = [DEFAULT_RULES.get(rule)(config, result) for rule in config.rules]
            processor = RuleProcessor(*rules)
            processor.process_cf_template(cf_template, config, result)

            # Use this to print the stack if there's an error
            if len(result.exceptions):
                print(template)
                traceback.print_tb(result.exceptions[0].__traceback__)

            no_resource_templates = ["vulgar_bad_syntax.yml", "rubbish.json"]

            if template.split("/")[-1] in no_resource_templates:
                assert len(result.exceptions) == 1
            else:
                assert len(result.exceptions) == 0
Пример #2
0
 def template(self):
     dir_path = os.path.dirname(os.path.realpath(__file__))
     with open(
             f"{dir_path}/test_templates/single_security_group_one_cidr_ingress.json"
     ) as cf_script:
         cf_template = convert_json_or_yaml_to_dict(cf_script.read())
     return pycfmodel.parse(cf_template)
Пример #3
0
 def template(self):
     dir_path = os.path.dirname(os.path.realpath(__file__))
     with open(
             f"{dir_path}/test_templates/s3_bucket_cross_account_and_normal.json"
     ) as cf_script:
         cf_template = convert_json_or_yaml_to_dict(cf_script.read())
     return pycfmodel.parse(cf_template)
 def template(self):
     dir_path = os.path.dirname(os.path.realpath(__file__))
     with open(
             f"{dir_path}/test_templates/rds_instance_plain_parameter.json"
     ) as cf_script:
         cf_template = convert_json_or_yaml_to_dict(cf_script.read())
     return pycfmodel.parse(cf_template)
Пример #5
0
def get_cfmodel(template: TextIOWrapper) -> CFModel:
    template_file = convert_json_or_yaml_to_dict(template.read())
    if not template_file:
        raise FileEmptyException(
            f"{template.name} is empty and not a valid template.")
    cfmodel = pycfmodel.parse(template_file)
    return cfmodel
Пример #6
0
 def template(self):
     dir_path = os.path.dirname(os.path.realpath(__file__))
     with open(
             f"{dir_path}/test_templates/iam_role_with_wildcard_action_on_trust.json"
     ) as cf_script:
         cf_template = convert_json_or_yaml_to_dict(cf_script.read())
     return pycfmodel.parse(cf_template)
Пример #7
0
def cli(templates, logging_level, resolve_parameters, **kwargs):
    """
    Analyse AWS Cloudformation templates passed by parameter.
    Exit codes:
      - 0 = all templates valid and scanned successfully
      - 1 = error / issue in scanning at least one template
      - 2 = at least one template is not valid according to CFRipper (template scanned successfully)
      - 3 = unknown / unhandled exception in scanning the templates
    """
    try:
        setup_logging(logging_level)

        if kwargs["resolve"] and resolve_parameters:
            resolve_parameters = convert_json_or_yaml_to_dict(
                resolve_parameters.read())

        results_of_templates = [
            process_template(template=template,
                             resolve_parameters=resolve_parameters,
                             **kwargs) for template in templates
        ]
        sys.exit(2 if False in results_of_templates else 0)
    except FileEmptyException as file_empty:
        sys.exit(file_empty)
    except Exception as e:
        logging.exception(
            "Unhandled exception raised, please create an issue with the error message at "
            "https://github.com/Skyscanner/cfripper/issues")
        try:
            sys.exit(e.errno)
        except AttributeError:
            sys.exit(3)
Пример #8
0
    def download_template_to_dictionary(self, s3_url):
        """
        Download a CloudFormation template from S3 into a Dictionary.

        :param s3_url: The URL to download from.
        :return: Dictionary version of the CF Template.
        """
        bucket_name, file_path = extract_bucket_name_and_path_from_url(s3_url)

        client = self.session.client("s3", region_name=self.region)
        response = client.get_object(Bucket=bucket_name, Key=file_path)
        file_contents = response["Body"].read().decode("utf-8")

        return convert_json_or_yaml_to_dict(file_contents)
Пример #9
0
def test_with_templates(cf_path):
    with open(cf_path) as cf_script:
        cf_template = convert_json_or_yaml_to_dict(cf_script.read())

    config = Config(project_name=cf_path, service_name=cf_path, stack_name=cf_path, rules=DEFAULT_RULES.keys())

    # Scan result

    cfmodel = pycfmodel.parse(cf_template).resolve()

    rules = [DEFAULT_RULES.get(rule)(config) for rule in config.rules]
    processor = RuleProcessor(*rules)
    result = processor.process_cf_template(cfmodel, config)

    # Use this to print the stack if there'IAMManagedPolicyWildcardActionRule an error
    if len(result.exceptions):
        print(cf_path)
        traceback.print_tb(result.exceptions[0].__traceback__)

    assert len(result.exceptions) == 0
Пример #10
0
def test_script(script_name, service_name, project_name, stack):
    event = {
        "stack_template_url": "https://fake/bucket/key",
        "project": project_name,
        "serviceName": service_name,
        "stack": stack,
    }
    mock_boto3_client_object = Mock()
    with open(f"{dir_path}/test_cf_scripts/{script_name}") as cf_script:
        mock_boto3_client_object.download_template_to_dictionary.return_value = convert_json_or_yaml_to_dict(
            cf_script.read()
        )

    mock_boto3_client = Mock(return_value=mock_boto3_client_object)

    with patch("cfripper.main.Boto3Client", new=mock_boto3_client):
        from cfripper.main import handler

        event_result = handler(event, "None")
        print(f"{script_name} -- valid: {event_result['valid']}\n {event_result['reason']}")
Пример #11
0
def cli(templates, logging_level, resolve_parameters, **kwargs):
    """Analyse AWS Cloudformation templates passed by parameter."""
    try:
        setup_logging(logging_level)

        if kwargs["resolve"] and resolve_parameters:
            resolve_parameters = convert_json_or_yaml_to_dict(
                resolve_parameters.read())

        for template in templates:
            process_template(template=template,
                             resolve_parameters=resolve_parameters,
                             **kwargs)

    except Exception as e:
        logging.exception(
            "Unhandled exception raised, please create an issue wit the error message at "
            "https://github.com/Skyscanner/cfripper/issues")
        try:
            sys.exit(e.errno)
        except AttributeError:
            sys.exit(1)
Пример #12
0
def get_cfmodel_from(path: str) -> CFModel:
    with Path(FIXTURE_ROOT_PATH / path).open() as f:
        content = f.read()
    return parse(convert_json_or_yaml_to_dict(content))
Пример #13
0
    def test_valid_yaml_as_bytes(self):
        yaml_content = bytes("hello: this is valid", "utf8")

        result = convert_json_or_yaml_to_dict(yaml_content)

        assert result["hello"] == "this is valid"
Пример #14
0
def test_invalid_yaml_as_bytes(patched_logger):
    result = convert_json_or_yaml_to_dict(bytes("Abc: g\nh:f", "utf8"),
                                          "bad-stack")
    assert result is None
    patched_logger.assert_called_once_with(
        "Could not parse JSON template for bad-stack")
Пример #15
0
def test_valid_yaml_as_bytes():
    result = convert_json_or_yaml_to_dict(bytes("hello: this is valid",
                                                "utf8"))
    assert result["hello"] == "this is valid"
 def template(self):
     dir_path = os.path.dirname(os.path.realpath(__file__))
     with open(f"{dir_path}/test_templates/s3_read_plus_list.json"
               ) as cf_script:
         cf_template = convert_json_or_yaml_to_dict(cf_script.read())
     return pycfmodel.parse(cf_template)
Пример #17
0
 def template_good(self):
     dir_path = os.path.dirname(os.path.realpath(__file__))
     with open(f"{dir_path}/test_templates/cfn_authentication_good.json"
               ) as cf_script:
         cf_template = convert_json_or_yaml_to_dict(cf_script.read())
     return pycfmodel.parse(cf_template)
Пример #18
0
def get_cfmodel(template: TextIOWrapper) -> CFModel:
    template = convert_json_or_yaml_to_dict(template.read())
    cfmodel = pycfmodel.parse(template)
    return cfmodel