From c2c7cbb40819eed28a02be6e8dd434c4db0a2021 Mon Sep 17 00:00:00 2001 From: Pat Myron Date: Thu, 7 Jan 2021 21:05:31 -0800 Subject: [PATCH] catch common resource schema issues https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-licensemanager/pull/3 https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-iotwireless/pull/3 https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-ssm/pull/75 https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-auditmanager/pull/2 https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-codeartifact/pull/38 --- src/rpdk/core/data_loaders.py | 35 ++++++++++++++++++++++------------- src/rpdk/core/project.py | 7 +++++-- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/rpdk/core/data_loaders.py b/src/rpdk/core/data_loaders.py index ab9b50bb0..31a78d39b 100644 --- a/src/rpdk/core/data_loaders.py +++ b/src/rpdk/core/data_loaders.py @@ -123,13 +123,6 @@ def get_file_base_uri(file): return path.resolve().as_uri() -def _is_in(schema, key): - def contains(value): - return value in schema.get(key, []) - - return contains - - def load_resource_spec(resource_spec_file): # noqa: C901 """Load a resource provider definition from a file, and validate it.""" try: @@ -148,6 +141,24 @@ def load_resource_spec(resource_spec_file): # noqa: C901 LOG.debug("Resource spec validation failed", exc_info=True) raise SpecValidationError(str(e)) from e + if ( + "maxresults" in map(str.lower, resource_spec.get("properties", [])) + or "nexttoken" in map(str.lower, resource_spec.get("properties", [])) + or "nextmarker" in map(str.lower, resource_spec.get("properties", [])) + ): + LOG.warning( + "LIST API inputs like MaxResults, NextToken, NextMarker, and Filters are not resource properties" + ) + + if set(resource_spec.get("readOnlyProperties", [])) & set( + resource_spec.get("createOnlyProperties", []) + ) or set(resource_spec.get("readOnlyProperties", [])) & set( + resource_spec.get("writeOnlyProperties", []) + ): + LOG.warning( + "readOnlyProperties cannot be specified by customers and should not overlap with writeOnlyProperties or createOnlyProperties" + ) + try: additional_properties_validator.validate(resource_spec) except ValidationError as e: @@ -158,13 +169,11 @@ def load_resource_spec(resource_spec_file): # noqa: C901 in it. Please fix the warnings: %s", str(e), ) - in_readonly = _is_in(resource_spec, "readOnlyProperties") - in_createonly = _is_in(resource_spec, "createOnlyProperties") - - primary_ids = resource_spec["primaryIdentifier"] - for primary_id in primary_ids: - if not in_readonly(primary_id) and not in_createonly(primary_id): + for primary_id in resource_spec["primaryIdentifier"]: + if primary_id not in resource_spec.get( + "readOnlyProperties", [] + ) and primary_id not in resource_spec.get("createOnlyProperties", []): LOG.warning( "Property 'primaryIdentifier' - %s must be specified \ as either readOnly or createOnly", diff --git a/src/rpdk/core/project.py b/src/rpdk/core/project.py index efdc74604..1098db97c 100644 --- a/src/rpdk/core/project.py +++ b/src/rpdk/core/project.py @@ -330,8 +330,11 @@ def load_schema(self): LOG.critical(msg) raise InternalError(msg) - with self.schema_path.open("r", encoding="utf-8") as f: - self.schema = load_resource_spec(f) + for f in os.listdir(self.root): + if 'rpdk' in f: + continue + with open(os.path.join(self.root, f)) as schema: + self.schema = load_resource_spec(schema) @staticmethod def overwrite(path, contents):