aws-cloudformation / cloudformation-cli-python-plugin

The CloudFormation Provider Development Toolkit Python Plugin allows you to autogenerate Python code based on an input schema.
Apache License 2.0
108 stars 45 forks source link

If a resource is created without Properties, request.desiredResourceState is None #230

Closed benbridts closed 1 year ago

benbridts commented 1 year ago

This is not technically against the type annotations, but it would be nice if this wasn't the case.

Some snippets to test this with:

Schema:

{
    "properties": {
        "Identifier": {"type": "string"},
    },   
    "required": [],
    "readOnlyProperties": ["/properties/Identifier"],
    "primaryIdentifier": ["/properties/Identifier"],
}

handlers.py inside of the create handler

# this fails with `AttributeError: 'NoneType' object has no attribute 'Identifier'`
model = request.desiredResourceState
model.Identifier = identifier_utils.generate_resource_identifier(
    request.stackId, request.logicalResourceIdentifier,
    request.clientRequestToken, 255
)

# this works
model = request.desiredResourceState if request.desiredResourceState else ResourceModel(Identifier=None)
model.Identifier = identifier_utils.generate_resource_identifier(
    request.stackId, request.logicalResourceIdentifier,
    request.clientRequestToken, 255
)

I believe this can be solved by changing this code in resource.py

from

return UnmodelledRequest(
    # [...]
    desiredResourceState=request.requestData.resourceProperties,
     # [...]
 ).to_modelled(self._model_cls, self._type_configuration_model_cls)

to

return UnmodelledRequest(
    # [...]
    desiredResourceState=request.requestData.resourceProperties if request.requestData.resourceProperties else {},
     # [...]
 ).to_modelled(self._model_cls, self._type_configuration_model_cls)

This probably also applies to previousResourceState and maybe even to the Tag-related properties

mmaeng commented 1 year ago

Hey Ben,

Taking a look!