Control Get Existing Resource With Id#
Idem resource provider plugins that implement “resource” contract look-up existing resource by resource_id. If resource_id is not provided as the “present” and “absent” function arguments, resource can be looked-up by name or any other attribute that uniquely identify resource in the provider.
However, it should be possible to control Idem plugins behaviour to look-up existing resource only if
resource_id specified in SLS or stored in ESM cache.
Command line argument --get-resource-only-with-resource-id
allows to control this behaviour.
idem state ~/instance_test.sls --get-resource-only-with-resource-id
All Idem resource provider plugins “present” and “absent” functions should read “get_resource_only_with_resource_id” property to control look-up existing resource logic.
import copy
__contracts__ = ["resource"]
async def present(hub, ctx, name, resource_id, **kwargs):
"""
Check if a resource exists, if it doesn't create it.
If the resource exists, make sure that it is in the state described by "kwargs"
"""
result = dict(comment=(), old_state=None, new_state=None, name=name, result=True)
if resource_id:
before = await hub.exec.cloud.resource.get(
ctx, name=name, resource_id=resource_id
)
if not before["result"] or not before["ret"]:
result["comment"] = before["comment"]
result["result"] = False
return result
result["old_state"] = copy.deepcopy(before["ret"])
elif not hub.OPT.idem.get("get_resource_only_with_resource_id", False):
before = await hub.exec.cloud.resource.get(ctx, name=name, **kwargs)
if not before["result"]:
result["comment"] = before["comment"]
result["result"] = False
return result
if before["ret"]:
result["old_state"] = copy.deepcopy(before["ret"])
if result["old_state"]:
# Update resource
update = await hub.exec.cloud.resource.update(
ctx, name=name, resource_id=resource_id, **kwargs
)
if not update["result"]:
result["comment"] = update["comment"]
result["result"] = False
return result
result["comment"] = f"Updated cloud.resource '{name}'"
result["new_state"] = copy.deepcopy(update["ret"])
else:
# Create resource
create = await hub.exec.cloud.resource.create(ctx, name=name, **kwargs)
if not create["result"]:
result["comment"] = create["comment"]
result["result"] = False
return result
result["comment"] = f"Created cloud.resource '{name}'"
result["new_state"] = copy.deepcopy(create["ret"])
return result
async def absent(hub, ctx, resource_id, name, **kwargs):
"""
Check if a resource exists, if it exists delete it
"""
result = dict(comment=(), old_state=None, new_state=None, name=name, result=True)
before = {}
if resource_id:
before = await hub.exec.cloud.resource.get(
ctx, name=name, resource_id=resource_id
)
if not before["result"]:
result["comment"] = before["comment"]
result["result"] = False
return result
if before["ret"]:
result["old_state"] = copy.deepcopy(before["ret"])
elif not hub.OPT.idem.get("get_resource_only_with_resource_id", False):
before = await hub.exec.cloud.resource.get(ctx, name=name, **kwargs)
if not before["result"]:
result["comment"] = before["comment"]
result["result"] = False
return result
if before["ret"]:
result["old_state"] = copy.deepcopy(before["ret"])
if result["old_state"]:
# Delete resource
delete = await hub.exec.cloud.resource.delete(
ctx, name=name, resource_id=resource_id, **kwargs
)
if not delete["result"]:
result["comment"] = delete["comment"]
result["result"] = False
return result
result["comment"] = f"Deleted cloud.resource '{name}'"
else:
# Resource doesn't exist
result["comment"] = f"cloud.resource '{name}' already absent"
return result
def describe(hub, ctx, name):
...