-
Notifications
You must be signed in to change notification settings - Fork 597
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
239 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"additionalProperties": true, | ||
"properties": { | ||
"assumeRole": { | ||
"type": "string" | ||
}, | ||
"description": { | ||
"type": "string" | ||
}, | ||
"schemaVersion": { | ||
"description": "The schema version to use.", | ||
"enum": [ | ||
"0.3", | ||
"1.2", | ||
"2.0", | ||
"2.2" | ||
], | ||
"type": "string" | ||
} | ||
}, | ||
"required": [ | ||
"schemaVersion" | ||
], | ||
"title": "JSON schema for AWS Automation Documents", | ||
"type": "object" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
""" | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
SPDX-License-Identifier: MIT-0 | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
from typing import Any | ||
|
||
import cfnlint.data.schemas.other.ssm | ||
from cfnlint.decode import decode_str | ||
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator | ||
from cfnlint.rules.jsonschema.CfnLintJsonSchema import CfnLintJsonSchema, SchemaDetails | ||
from cfnlint.schema.resolver import RefResolver | ||
|
||
|
||
class Document(CfnLintJsonSchema): | ||
id = "E3051" | ||
shortdesc = "Validate the structure of a SSM document" | ||
description = ( | ||
"SSM documents are nested JSON/YAML in CloudFormation " | ||
"this rule adds validation to those documents" | ||
) | ||
source_url = "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html" | ||
tags = ["properties", "ssm", "document"] | ||
|
||
def __init__(self): | ||
super().__init__( | ||
["Resources/AWS::SSM::Document/Properties/Content"], | ||
schema_details=SchemaDetails( | ||
module=cfnlint.data.schemas.other.ssm, | ||
filename="document.json", | ||
), | ||
) | ||
|
||
store = { | ||
"document": self.schema, | ||
} | ||
|
||
self.resolver = RefResolver.from_schema(self.schema, store=store) | ||
|
||
# pylint: disable=unused-argument | ||
def validate( | ||
self, | ||
validator: Validator, | ||
_: Any, | ||
instance: Any, | ||
schema: dict[str, Any], | ||
) -> ValidationResult: | ||
# First time child rules are configured against the rule | ||
# so we can run this now | ||
|
||
if validator.is_type(instance, "string"): | ||
ssm_validator = validator.evolve( | ||
context=validator.context.evolve( | ||
functions=[], | ||
strict_types=True, | ||
), | ||
resolver=self.resolver, | ||
schema=self.schema, | ||
) | ||
|
||
instance, errs = decode_str(instance) | ||
if errs: | ||
yield ValidationError( | ||
"Document is not of type 'object'", | ||
validator="type", | ||
rule=self, | ||
) | ||
return | ||
else: | ||
ssm_validator = validator.evolve( | ||
cfn=validator.cfn, | ||
context=validator.context.evolve( | ||
strict_types=True, | ||
), | ||
resolver=self.resolver, | ||
schema=self.schema, | ||
) | ||
|
||
for err in ssm_validator.iter_errors(instance): | ||
if not err.validator.startswith("fn_") and err.validator not in ["cfnLint"]: | ||
err.rule = self | ||
yield err |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
""" | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
SPDX-License-Identifier: MIT-0 | ||
""" | ||
|
||
from collections import deque | ||
|
||
import pytest | ||
|
||
from cfnlint.jsonschema.validators import ValidationError | ||
from cfnlint.rules.resources.ssm.Document import Document | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def rule(): | ||
rule = Document() | ||
yield rule | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"name,document,expected", | ||
[ | ||
( | ||
"Valid string yaml", | ||
""" | ||
schemaVersion: "2.2" | ||
mainSteps: | ||
- action: aws:runShellScript | ||
""", | ||
[], | ||
), | ||
( | ||
"Valid string json", | ||
""" | ||
{ | ||
"schemaVersion": "2.2", | ||
"mainSteps": [ | ||
{ | ||
"action": "aws:runShellScript" | ||
} | ||
] | ||
} | ||
""", | ||
[], | ||
), | ||
( | ||
"Valid object", | ||
{ | ||
"schemaVersion": "2.2", | ||
"mainSteps": [ | ||
{"action": "aws:runShellScript"}, | ||
], | ||
}, | ||
[], | ||
), | ||
( | ||
"InValid string yaml", | ||
""" | ||
schemaVersion: 2.2 | ||
mainSteps: | ||
- action: aws:runShellScript | ||
""", | ||
[ | ||
ValidationError( | ||
"2.2 is not of type 'string'", | ||
rule=Document(), | ||
validator="type", | ||
schema_path=deque(["properties", "schemaVersion", "type"]), | ||
path=deque(["schemaVersion"]), | ||
) | ||
], | ||
), | ||
( | ||
"Not a valid json or yaml object", | ||
"arn:aws-us-gov:iam::123456789012:role/test", | ||
[ | ||
ValidationError( | ||
"Document is not of type 'object'", | ||
rule=Document(), | ||
validator="type", | ||
schema_path=deque([]), | ||
path=deque([]), | ||
) | ||
], | ||
), | ||
( | ||
"Invalid schema version in object", | ||
{ | ||
"schemaVersion": 2.2, | ||
"mainSteps": [ | ||
{"action": "aws:runShellScript"}, | ||
], | ||
}, | ||
[ | ||
ValidationError( | ||
"2.2 is not of type 'string'", | ||
rule=Document(), | ||
validator="type", | ||
schema_path=deque(["properties", "schemaVersion", "type"]), | ||
path=deque(["schemaVersion"]), | ||
) | ||
], | ||
), | ||
( | ||
"Invalid type", | ||
[], | ||
[ | ||
ValidationError( | ||
"[] is not of type 'object'", | ||
rule=Document(), | ||
validator="type", | ||
schema_path=deque(["type"]), | ||
path=deque([]), | ||
) | ||
], | ||
), | ||
], | ||
) | ||
def test_validate( | ||
name, | ||
document, | ||
expected, | ||
rule, | ||
validator, | ||
): | ||
errs = list(rule.validate(validator, {}, document, {})) | ||
|
||
assert errs == expected |