Skip to content

Commit

Permalink
Switch event rule requiredXor to requiredOr (#3688)
Browse files Browse the repository at this point in the history
  • Loading branch information
kddejong authored Sep 13, 2024
1 parent 7b0ad97 commit 492b12a
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 20 deletions.
21 changes: 7 additions & 14 deletions docs/cfn-schema-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ _properties_ provides the key names and a value that represents the schema to va

_required_ defines a list of required properties. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/object#required)

##### requiredXor
##### requiredOr

_requiredXor_ is used to define when only one property from a set properties is required.
_requiredOr_ is used to define when at least one property from a set properties is required.

On the following defined object

Expand All @@ -104,15 +104,15 @@ The cfn-lint schema

```json
{
"requiredXor": ["a", "b", "c"]
"requiredOr": ["a", "b", "c"]
}
```

is equivalent to the JSON schema

```json
{
"oneOf": [
"anyOf": [
{
"required": ["a"]
},
Expand All @@ -126,9 +126,9 @@ is equivalent to the JSON schema
}
```

##### propertiesNand
##### requiredXor

_propertiesNand_ is used to define when none or only one property from a set properties can be defined.
_requiredXor_ is used to define when only one property from a set properties is required.

On the following defined object

Expand All @@ -147,7 +147,7 @@ The cfn-lint schema

```json
{
"propertiesNand": ["a", "b", "c"]
"requiredXor": ["a", "b", "c"]
}
```

Expand All @@ -164,13 +164,6 @@ is equivalent to the JSON schema
},
{
"required": ["c"]
},
{
"properties": {
"a": false,
"b": false,
"c": false
}
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/update_schemas_manually.py
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@
resource_type="AWS::Events::Rule",
patches=[
Patch(
values={"requiredXor": ["EventPattern", "ScheduleExpression"]},
values={"requiredOr": ["EventPattern", "ScheduleExpression"]},
path="/",
),
Patch(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"op": "add",
"path": "/requiredXor",
"path": "/requiredOr",
"value": [
"EventPattern",
"ScheduleExpression"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@
"readOnlyProperties": [
"/properties/Arn"
],
"requiredXor": [
"requiredOr": [
"EventPattern",
"ScheduleExpression"
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@
"/properties/Id",
"/properties/Arn"
],
"requiredXor": [
"requiredOr": [
"EventPattern",
"ScheduleExpression"
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@
"/properties/Id",
"/properties/Arn"
],
"requiredXor": [
"requiredOr": [
"EventPattern",
"ScheduleExpression"
],
Expand Down
2 changes: 1 addition & 1 deletion src/cfnlint/jsonschema/_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class FunctionFilter:
"minItems",
"minProperties",
"required",
"requiredAtLeastOne",
"requiredOr",
"requiredXor",
"then",
"uniqueItems",
Expand Down
11 changes: 11 additions & 0 deletions src/cfnlint/jsonschema/_keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,17 @@ def required(
yield ValidationError(f"{property!r} is a required property")


def requiredOr(
validator: Validator, required: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if not validator.is_type(instance, "object"):
return
matches = set(required).intersection(instance.keys())
if not matches:
yield ValidationError(f"One of {required!r} is a required property")
return


def requiredXor(
validator: Validator, required: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
Expand Down
1 change: 1 addition & 0 deletions src/cfnlint/jsonschema/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ def extend(
"properties": _keywords.properties,
"propertyNames": _keywords.propertyNames,
"required": _keywords.required,
"requiredOr": _keywords.requiredOr,
"requiredXor": _keywords.requiredXor,
"type": _keywords.type,
"uniqueItems": _keywords.uniqueItems,
Expand Down
1 change: 1 addition & 0 deletions src/cfnlint/rules/resources/properties/Properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def __init__(self):
"dependentExcluded": "E3020",
"dependentRequired": "E3021",
"required": "E3003",
"requiredOr": "E3058",
"requiredXor": "E3014",
"enum": "E3030",
"type": "E3012",
Expand Down
14 changes: 14 additions & 0 deletions src/cfnlint/rules/resources/properties/RequiredOr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""

from cfnlint.rules import CloudFormationLintRule


class RequiredOr(CloudFormationLintRule):
id = "E3058"
shortdesc = "Validate at least one of the properties are required"
description = "Make sure at least one of the resource properties are included"
source_url = "https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/cfn-schema-specification.md#requiredor"
tags = ["resources"]
22 changes: 22 additions & 0 deletions test/unit/module/jsonschema/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,28 @@ def test_validator(name, schema, instance, expected, validator):
)
],
),
(
"valid requiredOr",
{"requiredOr": ["foo", "bar"]},
{"foo": {}},
[],
),
(
"valid requiredOr with wrong type",
{"requiredOr": ["foo", "bar"]},
[],
[],
),
(
"invalid requiredOr with empty object",
{"requiredOr": ["foo", "bar"]},
{},
[
ValidationError(
"One of ['foo', 'bar'] is a required property",
)
],
),
(
"valid requiredXor",
{"requiredXor": ["foo", "bar"]},
Expand Down

0 comments on commit 492b12a

Please sign in to comment.