Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update E3615 to validate all CloudWatch Alarm periods #3556

Merged
merged 1 commit into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"additionalProperties": true,
"description": "The period, in seconds, over which the statistic is applied. This is required for an alarm based on a metric. Valid values are 10, 30, 60, and any multiple of 60.",
"if": {
"properties": {
"Period": {
"type": [
"integer",
"string"
]
}
},
"required": [
"Period"
],
"type": "object"
},
"then": {
"properties": {
"Period": {
"else": {
"multipleOf": 60
},
"if": {
"maximum": 60
},
"then": {
"enum": [
10,
30,
60
]
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,24 @@
from typing import Any

import cfnlint.data.schemas.extensions.aws_cloudwatch_alarm
from cfnlint.jsonschema import ValidationError
from cfnlint.jsonschema.exceptions import ValidationError
from cfnlint.rules.jsonschema.CfnLintJsonSchema import CfnLintJsonSchema, SchemaDetails


class AlarmAwsNamespacePeriod(CfnLintJsonSchema):
class AlarmPeriod(CfnLintJsonSchema):
id = "E3615"
shortdesc = "Validate CloudWatch Alarm using AWS metrics has a correct period"
description = (
"Period < 60 not supported for namespaces with the following prefix: AWS/"
)
tags = ["resources"]
shortdesc = "Validate the period is a valid value"
description = "Valid values are 10, 30, 60, and any multiple of 60."
tags = ["resources", "cloudwatch"]

def __init__(self) -> None:
super().__init__(
keywords=["Resources/AWS::CloudWatch::Alarm/Properties"],
schema_details=SchemaDetails(
module=cfnlint.data.schemas.extensions.aws_cloudwatch_alarm,
filename="aws_namespace_period.json",
filename="period.json",
),
)

def message(self, instance: Any, err: ValidationError) -> str:
return err.message
return f"{err.instance!r} is not one of [10, 30, 60] or a multiple of 60"

This file was deleted.

116 changes: 116 additions & 0 deletions test/unit/rules/resources/cloudwatch/test_alarm_period.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""

from collections import deque

import pytest

from cfnlint.jsonschema import ValidationError
from cfnlint.rules.resources.cloudwatch.AlarmPeriod import AlarmPeriod


@pytest.fixture(scope="module")
def rule():
rule = AlarmPeriod()
yield rule


@pytest.mark.parametrize(
"instance,expected",
[
(
{
"Period": 60,
},
[],
),
(
[], # wrong type
[],
),
(
{
"Period": {"Ref": "Period"}, # ignore when object
},
[],
),
(
{
"Period": 30,
},
[],
),
(
{
"Period": 600,
},
[],
),
(
{
"Period": 45,
},
[
ValidationError(
"45 is not one of [10, 30, 60] or a multiple of 60",
rule=AlarmPeriod(),
path=deque(["Period"]),
validator="enum",
schema_path=deque(["then", "properties", "Period", "then", "enum"]),
)
],
),
(
{
"Period": "45",
},
[
ValidationError(
"'45' is not one of [10, 30, 60] or a multiple of 60",
rule=AlarmPeriod(),
path=deque(["Period"]),
validator="enum",
schema_path=deque(["then", "properties", "Period", "then", "enum"]),
)
],
),
(
{
"Period": 121,
},
[
ValidationError(
"121 is not one of [10, 30, 60] or a multiple of 60",
rule=AlarmPeriod(),
path=deque(["Period"]),
validator="multipleOf",
schema_path=deque(
["then", "properties", "Period", "else", "multipleOf"]
),
)
],
),
(
{
"Period": "121",
},
[
ValidationError(
"'121' is not one of [10, 30, 60] or a multiple of 60",
rule=AlarmPeriod(),
path=deque(["Period"]),
validator="multipleOf",
schema_path=deque(
["then", "properties", "Period", "else", "multipleOf"]
),
)
],
),
],
)
def test_validate(instance, expected, rule, validator):
errs = list(rule.validate(validator, "", instance, {}))

assert errs == expected, f"Expected {expected} got {errs}"
Loading