cloudtools / troposphere

troposphere - Python library to create AWS CloudFormation descriptions
BSD 2-Clause "Simplified" License
4.93k stars 1.45k forks source link

ResponseHeadersPolicyConfig/CorsConfig/AccessControlAllowMethods/Items: expected type: JSONArray, found: String #2023

Closed FutureDigitalConsulting closed 2 years ago

FutureDigitalConsulting commented 2 years ago

I'm currently having a compile issue which seems to be related to troposhere.

embed_response_header_policy = t.add_resource(
    ResponseHeadersPolicy(
        "ResponseHeadersPolicy",
        ResponseHeadersPolicyConfig=ResponseHeadersPolicyConfig(
            Comment=Join('', ['Embed response header policy config for cloudfront: ',
                              Ref(AWS_STACK_NAME)]),
            CorsConfig=CorsConfig(AccessControlAllowCredentials=False,
                                  AccessControlAllowHeaders=AccessControlAllowHeaders(Items=[]),
                                  AccessControlAllowMethods=AccessControlAllowMethods(Items=["GET"]),
                                  AccessControlAllowOrigins=AccessControlAllowOrigins(Items=["*"]),
                                  AccessControlExposeHeaders=AccessControlExposeHeaders(Items=["-"]),
                                  AccessControlMaxAgeSec=600,
                                  OriginOverride=False),
            Name=Join("-", [Ref(AWS_STACK_NAME), "response-headers-policy"]),
            SecurityHeadersConfig=SecurityHeadersConfig(
                ContentSecurityPolicy=ContentSecurityPolicy(
                    ContentSecurityPolicy='max-age: 31536000 (seconds)',
                    Override=True,
                ),
                ContentTypeOptions=ContentTypeOptions(Override=False),
                FrameOptions=FrameOptions(
                    FrameOption='SAMEORIGIN',
                    Override='true',
                ),
                # ReferrerPolicy=ReferrerPolicy(
                # Override=True,
                # ReferrerPolicy='strict-origin-when-cross-origin',
                # ),
                StrictTransportSecurity=StrictTransportSecurity(
                    AccessControlMaxAgeSec=1,
                    Override=True,
                ),
                XSSProtection=XSSProtection(
                    ModeBlock=True,
                    Override=True,
                    Protection=True,
                ),
            )),
    ))

Results in the following compile error:

<class 'troposphere.cloudfront.AccessControlAllowMethods'>: None.Items function validator 'cloudfront_access_control_allow_methods' threw exception:
Traceback (most recent call last):
  File "templates/apps/embed-page/cloudfront.py", line 448, in <module>
    AccessControlAllowMethods=AccessControlAllowMethods(Items=["GET"]),
  File "/var/lib/jenkins/workspace/OPENMEDIA/GLOBAL-INFRA/pipeline-cloudfront-distribution-cfn-generic-infra/tools/cloudformation/.pythonEnv/lib/python3.7/site-packages/troposphere/__init__.py", line 374, in __init__
    super().__init__(title, **kwargs)
  File "/var/lib/jenkins/workspace/OPENMEDIA/GLOBAL-INFRA/pipeline-cloudfront-distribution-cfn-generic-infra/tools/cloudformation/.pythonEnv/lib/python3.7/site-packages/troposphere/__init__.py", line 133, in __init__
    self.__setattr__(k, v)
  File "/var/lib/jenkins/workspace/OPENMEDIA/GLOBAL-INFRA/pipeline-cloudfront-distribution-cfn-generic-infra/tools/cloudformation/.pythonEnv/lib/python3.7/site-packages/troposphere/__init__.py", line 189, in __setattr__
    value = expected_type(value)
  File "/var/lib/jenkins/workspace/OPENMEDIA/GLOBAL-INFRA/pipeline-cloudfront-distribution-cfn-generic-infra/tools/cloudformation/.pythonEnv/lib/python3.7/site-packages/troposphere/validators/cloudfront.py", line 33, in cloudfront_access_control_allow_methods
    'AccessControlAllowMethods must be of: "%s"' % (", ".join(valid_values))
ValueError: AccessControlAllowMethods must be of: "GET, DELETE, HEAD, OPTIONS, PATCH, POST, PUT, ALL"
 + Executing templates/apps/embed-page/cloudfront.py

This validator insists that the value must be of type string instead of JSONArray. When i change

AccessControlAllowMethods=AccessControlAllowMethods(Items=["GET"]),

to

AccessControlAllowMethods=AccessControlAllowMethods(Items="GET"),

It compiles but when deploying the cloudformation template i get the following error message:

Properties validation failed for resource ResponseHeadersPolicy with message: #/ResponseHeadersPolicyConfig/CorsConfig/AccessControlAllowMethods/Items: expected type: JSONArray, found: String

Which states that it should be a JSONArray just as the cloudformation documentation says here

From what i can understand this seems to be an internal troposphere issue.

benbridts commented 2 years ago

I think there is an error in the AccessControlAllowMethods class, It's not allowing a list of items

Instead of

"Items": (cloudfront_access_control_allow_methods, True),

It should probably look like (not tested)

"Items": ([cloudfront_access_control_allow_methods], True),
markpeek commented 2 years ago

@FutureDigitalConsulting thanks for the issue. Fixed via 16fc59cd0b95d07fb288cdf1dda29668467f2f29

@benbridts thank you for the proposed fix. Due to the new auto-gen I needed to fix it in the validator.

FutureDigitalConsulting commented 2 years ago

@markpeek will this be released to 3.x.x? And when? A project is currently blocked due to this.

markpeek commented 2 years ago

I do not plan to backport it to 3.x.x. This is fixed in Release 4.0.0 which I just released.