diff --git a/scripts/boto/update_schemas_from_boto.py b/scripts/boto/update_schemas_from_boto.py index 829cd3f629..4cfea803bd 100755 --- a/scripts/boto/update_schemas_from_boto.py +++ b/scripts/boto/update_schemas_from_boto.py @@ -29,7 +29,8 @@ ] exceptions = { - "ses": ["/definitions/EventDestination/properties/MatchingEventTypes/items"] + "ses": ["/definitions/EventDestination/properties/MatchingEventTypes/items"], + "ecs": ["/definitions/LogConfiguration/properties/LogDriver"], } diff --git a/src/cfnlint/data/schemas/extensions/aws_ecs_taskdefinition/fargate_properties.json b/src/cfnlint/data/schemas/extensions/aws_ecs_taskdefinition/fargate_properties.json index f0326beeb0..94885935c2 100644 --- a/src/cfnlint/data/schemas/extensions/aws_ecs_taskdefinition/fargate_properties.json +++ b/src/cfnlint/data/schemas/extensions/aws_ecs_taskdefinition/fargate_properties.json @@ -16,54 +16,119 @@ ] }, "then": { - "if": { - "properties": { - "Cpu": { - "type": [ - "string", - "integer" + "allOf": [ + { + "if": { + "properties": { + "NetworkMode": { + "type": "string" + } + }, + "required": [ + "NetworkMode" + ] + }, + "required": [ + "NetworkMode" + ], + "then": { + "properties": { + "NetworkMode": { + "enum": [ + "awsvpc" + ], + "type": "string" + } + }, + "required": [ + "NetworkMode" ] } }, - "required": [ - "Cpu" - ] - }, - "not": { - "required": [ - "PlacementConstraints" - ] - }, - "required": [ - "Cpu", - "Memory" - ], - "then": { - "properties": { - "Cpu": { - "else": { - "pattern": "^(\\.25|\\.5|1|2|4|8|16)\\s*(?i)vCpu$" - }, - "if": { - "pattern": "^\\d+$", - "type": [ - "integer", - "string" - ] + { + "properties": { + "ContainerDefinitions": { + "items": { + "properties": { + "LogConfiguration": { + "if": { + "properties": { + "LogDriver": { + "type": "string" + } + }, + "required": [ + "LogDriver" + ] + }, + "then": { + "properties": { + "LogDriver": { + "enum": [ + "awslogs", + "splunk", + "awsfirelens" + ] + } + } + } + } + } + } + } + } + }, + { + "if": { + "properties": { + "Cpu": { + "type": [ + "string", + "integer" + ] + } }, - "then": { - "enum": [ - "256", - "512", - "1024", - "2048", - "4096", - "8192", - "16384" - ] + "required": [ + "Cpu" + ] + }, + "not": { + "required": [ + "PlacementConstraints" + ] + }, + "required": [ + "Cpu", + "Memory" + ], + "then": { + "properties": { + "Cpu": { + "else": { + "pattern": "^(\\.25|\\.5|1|2|4|8|16)\\s*(?i)vCpu$" + }, + "if": { + "pattern": "^\\d+$", + "type": [ + "integer", + "string" + ] + }, + "then": { + "enum": [ + "256", + "512", + "1024", + "2048", + "4096", + "8192", + "16384" + ] + } + } } } } - } + ] } } diff --git a/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_service/boto.json b/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_service/boto.json index e6ad41c272..fd1d715eeb 100644 --- a/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_service/boto.json +++ b/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_service/boto.json @@ -9,20 +9,6 @@ "path": "/definitions/Tag/properties/Value/pattern", "value": "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$" }, - { - "op": "add", - "path": "/definitions/LogConfiguration/properties/LogDriver/enum", - "value": [ - "awsfirelens", - "awslogs", - "fluentd", - "gelf", - "journald", - "json-file", - "splunk", - "syslog" - ] - }, { "op": "add", "path": "/definitions/EBSTagSpecification/properties/ResourceType/enum", diff --git a/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_taskdefinition/boto.json b/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_taskdefinition/boto.json index fb8d335eb8..f0973d86f5 100644 --- a/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_taskdefinition/boto.json +++ b/src/cfnlint/data/schemas/patches/extensions/all/aws_ecs_taskdefinition/boto.json @@ -71,20 +71,6 @@ "stack" ] }, - { - "op": "add", - "path": "/definitions/LogConfiguration/properties/LogDriver/enum", - "value": [ - "awsfirelens", - "awslogs", - "fluentd", - "gelf", - "journald", - "json-file", - "splunk", - "syslog" - ] - }, { "op": "add", "path": "/definitions/ResourceRequirement/properties/Type/enum", diff --git a/src/cfnlint/data/schemas/providers/eu_central_1/aws-ecs-service.json b/src/cfnlint/data/schemas/providers/eu_central_1/aws-ecs-service.json index 39c164ea67..7065156406 100644 --- a/src/cfnlint/data/schemas/providers/eu_central_1/aws-ecs-service.json +++ b/src/cfnlint/data/schemas/providers/eu_central_1/aws-ecs-service.json @@ -174,16 +174,6 @@ "additionalProperties": false, "properties": { "LogDriver": { - "enum": [ - "awsfirelens", - "awslogs", - "fluentd", - "gelf", - "journald", - "json-file", - "splunk", - "syslog" - ], "type": "string" }, "Options": { diff --git a/src/cfnlint/data/schemas/providers/us_east_1/aws-ecs-taskdefinition.json b/src/cfnlint/data/schemas/providers/us_east_1/aws-ecs-taskdefinition.json index 8b9f473363..2db10e86bc 100644 --- a/src/cfnlint/data/schemas/providers/us_east_1/aws-ecs-taskdefinition.json +++ b/src/cfnlint/data/schemas/providers/us_east_1/aws-ecs-taskdefinition.json @@ -581,16 +581,6 @@ "additionalProperties": false, "properties": { "LogDriver": { - "enum": [ - "awsfirelens", - "awslogs", - "fluentd", - "gelf", - "journald", - "json-file", - "splunk", - "syslog" - ], "type": "string" }, "Options": { diff --git a/src/cfnlint/data/schemas/providers/us_west_2/aws-ecs-service.json b/src/cfnlint/data/schemas/providers/us_west_2/aws-ecs-service.json index 39c164ea67..7065156406 100644 --- a/src/cfnlint/data/schemas/providers/us_west_2/aws-ecs-service.json +++ b/src/cfnlint/data/schemas/providers/us_west_2/aws-ecs-service.json @@ -174,16 +174,6 @@ "additionalProperties": false, "properties": { "LogDriver": { - "enum": [ - "awsfirelens", - "awslogs", - "fluentd", - "gelf", - "journald", - "json-file", - "splunk", - "syslog" - ], "type": "string" }, "Options": { diff --git a/test/unit/rules/resources/ecs/test_ecs_task_fargate_properties.py b/test/unit/rules/resources/ecs/test_ecs_task_fargate_properties.py index b2935bd6b2..8d557e623c 100644 --- a/test/unit/rules/resources/ecs/test_ecs_task_fargate_properties.py +++ b/test/unit/rules/resources/ecs/test_ecs_task_fargate_properties.py @@ -22,6 +22,7 @@ def rule(): [ ( { + "NetworkMode": "awsvpc", "RequiresCompatibilities": ["FARGATE"], "Cpu": 256, "Memory": "512", @@ -30,6 +31,7 @@ def rule(): ), ( { + "NetworkMode": "awsvpc", "RequiresCompatibilities": ["FARGATE"], "Cpu": ".25 vCpU", "Memory": "512", @@ -38,6 +40,7 @@ def rule(): ), ( { + "NetworkMode": "awsvpc", "RequiresCompatibilities": ["FARGATE"], "Cpu": 16384, }, @@ -47,12 +50,13 @@ def rule(): rule=TaskFargateProperties(), path=deque([]), validator="required", - schema_path=deque(["then", "required"]), + schema_path=deque(["then", "allOf", 2, "required"]), ) ], ), ( { + "NetworkMode": "awsvpc", "RequiresCompatibilities": ["FARGATE"], "Memory": "512", }, @@ -62,12 +66,13 @@ def rule(): rule=TaskFargateProperties(), path=deque([]), validator="required", - schema_path=deque(["then", "required"]), + schema_path=deque(["then", "allOf", 2, "required"]), ) ], ), ( { + "NetworkMode": "awsvpc", "RequiresCompatibilities": ["FARGATE"], "Memory": "512", "Cpu": 256, @@ -79,12 +84,13 @@ def rule(): rule=TaskFargateProperties(), path=deque(["PlacementConstraints"]), validator="not", - schema_path=deque(["then", "not"]), + schema_path=deque(["then", "allOf", 2, "not"]), ) ], ), ( { + "NetworkMode": "awsvpc", "RequiresCompatibilities": ["FARGATE"], "Cpu": {"Ref": "MyParameter"}, "Memory": "512", @@ -93,6 +99,7 @@ def rule(): ), ( { + "NetworkMode": "awsvpc", "RequiresCompatibilities": ["FARGATE"], "Cpu": 128, "Memory": "512", @@ -107,7 +114,128 @@ def rule(): path=deque(["Cpu"]), validator="enum", schema_path=deque( - ["then", "then", "properties", "Cpu", "then", "enum"] + [ + "then", + "allOf", + 2, + "then", + "properties", + "Cpu", + "then", + "enum", + ] + ), + ) + ], + ), + ( + { + "RequiresCompatibilities": ["FARGATE"], + "Cpu": 256, + "Memory": "512", + "NetworkMode": {"Ref": "MyParameter"}, + }, + [], + ), + ( + { + "RequiresCompatibilities": ["FARGATE"], + "Cpu": 256, + "Memory": "512", + }, + [ + ValidationError( + ("'NetworkMode' is a required property"), + rule=TaskFargateProperties(), + path=deque([]), + validator="required", + schema_path=deque(["then", "allOf", 0, "required"]), + ) + ], + ), + ( + { + "RequiresCompatibilities": ["FARGATE"], + "Cpu": 256, + "Memory": "512", + "NetworkMode": "awsvpc", + "ContainerDefinitions": [ + { + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": "log-group", + "awslogs-region": "us-east-1", + "awslogs-stream-prefix": "ecs", + }, + } + } + ], + }, + [], + ), + ( + { + "RequiresCompatibilities": ["FARGATE"], + "Cpu": 256, + "Memory": "512", + "NetworkMode": "awsvpc", + "ContainerDefinitions": [ + { + "LogConfiguration": { + "LogDriver": {"Ref": "MyParameter"}, + "Options": { + "awslogs-group": "log-group", + "awslogs-region": "us-east-1", + "awslogs-stream-prefix": "ecs", + }, + } + } + ], + }, + [], + ), + ( + { + "RequiresCompatibilities": ["FARGATE"], + "Cpu": 256, + "Memory": "512", + "NetworkMode": "awsvpc", + "ContainerDefinitions": [ + { + "LogConfiguration": { + "LogDriver": "sumologic", + "Options": { + "sumo-url": "aurl", + "sumo-source-category": "access", + }, + } + } + ], + }, + [ + ValidationError( + ("'sumologic' is not one of ['awslogs', 'splunk', 'awsfirelens']"), + rule=TaskFargateProperties(), + path=deque( + ["ContainerDefinitions", 0, "LogConfiguration", "LogDriver"] + ), + validator="enum", + schema_path=deque( + [ + "then", + "allOf", + 1, + "properties", + "ContainerDefinitions", + "items", + "properties", + "LogConfiguration", + "then", + "properties", + "LogDriver", + "enum", + ] ), ) ],