Closed
Description
Hello.
Version: cloudformation-cli-python-lib==2.1.8; python_version >= "3.6"
JSON Schema
{
"typeName": "MongoDb::Atlas::AwsIamDatabaseUser",
"description": "CRUD for AWS IAM MongoDB users in a project for your clusters/databases.",
"sourceUrl": "https://github.com/compose-x/mongodb-atlas-resources",
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"AwsIamResource": {
"description": "The AWS IAM user or role ARN used as the database username.",
"type": "string",
"pattern": "^arn:aws(?:-[a-z-]+)?:iam::[0-9]{12}:(role|user)/[\\S]+$"
},
"ApiKeys": {
"$ref": "#/definitions/apiKeyDefinition"
},
"ProjectId": {
"description": "Unique identifier of the Atlas project to which the user belongs.",
"type": "string",
"pattern": "^[a-zA-Z0-9]+$"
},
"DatabaseAccess": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-zA-Z0-9-_]+$": {
"$ref": "#/definitions/databaseAccessDefinition"
}
}
},
"Scopes": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-zA-Z0-9-_]+$": {
"type": "string",
"description": "Database/Lake name to the type",
"enum": [
"CLUSTER",
"DATA_LAKE"
]
}
}
},
"MongoDbUsername": {
"description": "MongoDB username for the AWS IAM resource.",
"type": "string"
}
},
"definitions": {
"databaseAccessDefinition": {
"type": "object",
"additionalProperties": false,
"required": [
"RoleName"
],
"properties": {
"RoleName": {
"type": "string"
},
"CollectionName": {
"type": "string"
}
}
},
"apiKeyDefinition": {
"additionalProperties": false,
"properties": {
"PrivateKey": {
"type": "string"
},
"PublicKey": {
"type": "string"
}
},
"type": "object",
"required": [
"PublicKey",
"PrivateKey"
]
},
"roleDefinition": {
"additionalProperties": false,
"properties": {
"CollectionName": {
"type": "string"
},
"DatabaseName": {
"type": "string"
},
"RoleName": {
"minLength": 1,
"type": "string"
}
},
"type": "object",
"required": [
"RoleName"
]
},
"scopeDefinition": {
"additionalProperties": false,
"properties": {
"ScopeName": {
"minLength": 1,
"type": "string"
},
"ScopeType": {
"enum": [
"CLUSTER",
"DATA_LAKE"
],
"type": "string"
}
},
"type": "object",
"required": [
"ScopeName",
"ScopeType"
]
}
},
"primaryIdentifier": [
"/properties/MongoDbUsername"
],
"readOnlyProperties": [
"/properties/MongoDbUsername"
],
"createOnlyProperties": [
"/properties/Username",
"/properties/ProjectId"
],
"required": [
"AwsIamResource",
"ProjectId",
"ApiKeys",
"DatabaseAccess"
],
"handlers": {
"create": {
"permissions": [
"secretsmanager:GetSecretValue"
]
},
"read": {
"permissions": [
"secretsmanager:GetSecretValue"
]
},
"update": {
"permissions": [
"secretsmanager:GetSecretValue"
]
},
"delete": {
"permissions": [
"secretsmanager:GetSecretValue"
]
}
}
}
stack trace
HELLO K DatabaseAccess <class 'str'>
HI V {'db0101': {'RoleName': 'readWrite'}, 'db2020': {'RoleName': 'readWriteAnyDatabase'}} <class 'dict'>
HELLO K db0101 <class 'str'>
HI V {'RoleName': 'readWrite'} <class 'dict'>
Handler error
Traceback (most recent call last):
File "/var/task/cloudformation_cli_python_lib/resource.py", line 176, in _cast_resource_request
).to_modelled(self._model_cls, self._type_configuration_model_cls)
File "/var/task/cloudformation_cli_python_lib/utils.py", line 148, in to_modelled
desiredResourceState=model_cls._deserialize(self.desiredResourceState),
File "/var/task/mongodb_atlas_awsiamdatabaseuser/models.py", line 63, in _deserialize
recast_object(cls, json_data, dataclasses)
File "/var/task/cloudformation_cli_python_lib/recast.py", line 24, in recast_object
recast_object(child_cls, v, classes)
File "/var/task/cloudformation_cli_python_lib/recast.py", line 23, in recast_object
child_cls = _field_to_type(cls.__dataclass_fields__[k].type, k, classes)
KeyError: 'db0101'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/var/task/cloudformation_cli_python_lib/resource.py", line 199, in __call__
request = self._cast_resource_request(event)
File "/var/task/cloudformation_cli_python_lib/resource.py", line 179, in _cast_resource_request
raise InvalidRequest(f"{e} ({type(e).__name__})") from e
cloudformation_cli_python_lib.exceptions.InvalidRequest: 'db0101' (KeyError)
So. what's happening is that the recast the first time around sees DatabaseAccess
as the key to value dict
{'db0101': {'RoleName': 'readWrite'}, 'db2020': {'RoleName': 'readWriteAnyDatabase'}}
Then goes into the nesting. But then it has lost the info that the dict in db0101
represents another class.
That seems to happen due to the "lack" of typing for DatabaseAccess
.{} objects
@dataclass
class ResourceModel(BaseModel):
AwsIamResource: Optional[str]
ApiKeys: Optional["_ApiKeyDefinition"]
ProjectId: Optional[str]
DatabaseAccess: Optional[MutableMapping[str, "_DatabaseAccessDefinition"]]
Scopes: Optional[MutableMapping[str, str]]
MongoDbUsername: Optional[str]
@classmethod
def _deserialize(
cls: Type["_ResourceModel"],
json_data: Optional[Mapping[str, Any]],
) -> Optional["_ResourceModel"]:
if not json_data:
return None
dataclasses = {n: o for n, o in getmembers(sys.modules[__name__]) if isclass(o)}
print(dataclasses.items())
print(json_data)
print(cls, type(cls))
for k, v in cls.__dict__.items():
print(k, v)
recast_object(cls, json_data, dataclasses)
return cls(
AwsIamResource=json_data.get("AwsIamResource"),
ApiKeys=ApiKeyDefinition._deserialize(json_data.get("ApiKeys")),
ProjectId=json_data.get("ProjectId"),
DatabaseAccess=json_data.get("DatabaseAccess"),
Scopes=json_data.get("Scopes"),
MongoDbUsername=json_data.get("MongoDbUsername"),
)
The input is totally valid (jsonschema approves).
I am trying to come up with a fix but thought that's worth others either telling me what I am doing wrong or knowing about it
Metadata
Metadata
Assignees
Labels
No labels