"""
Autogenerated using `pop-create-idem <https://gitlab.com/saltstack/pop/pop-create-idem>`__
hub.exec.boto3.client.iam.create_instance_profile
hub.exec.boto3.client.iam.delete_instance_profile
hub.exec.boto3.client.iam.get_instance_profile
hub.exec.boto3.client.iam.list_instance_profiles
hub.exec.boto3.client.iam.tag_instance_profile
hub.exec.boto3.client.iam.untag_instance_profile
resource = await hub.tool.boto3.resource.create(ctx, "iam", "InstanceProfile", name)
hub.tool.boto3.resource.exec(resource, add_role, *args, **kwargs)
hub.tool.boto3.resource.exec(resource, delete, *args, **kwargs)
hub.tool.boto3.resource.exec(resource, remove_role, *args, **kwargs)
"""
import copy
from dataclasses import field
from dataclasses import make_dataclass
from typing import Any
from typing import Dict
from typing import List
__contracts__ = ["resource"]
TREQ = {
"absent": {
"require": [
"aws.iam.role.absent",
],
},
}
[docs]async def present(
hub,
ctx,
name: str,
resource_id: str = None,
path: str = None,
roles: List = None,
tags: Dict[str, Any]
or List[
make_dataclass(
"Tag",
[("Key", str, field(default=None)), ("Value", str, field(default=None))],
)
] = None,
) -> Dict[str, Any]:
"""
**Autogenerated function**
Creates a new instance profile. For information about instance profiles, see Using roles for applications on
Amazon EC2 in the IAM User Guide, and Instance profiles in the Amazon EC2 User Guide. For information about the
number of instance profiles you can create, see IAM object quotas in the IAM User Guide.
Tags can be set on a newly created instance profile, or updated on an existing one.
Roles are set and updated as a day-2 operation.
Args:
name(str): AWS Instance Profile Name.
resource_id(str, Optional): AWS Instance Profile Name.
path(str, Optional): The path to the instance profile.
roles(str, Optional): A list with up to one role name. Instance profile can be associated with a single role.
tags(Dict or List, Optional): Dict in the format of {tag-key: tag-value} or List of tags in the format of
[{"Key": tag-key, "Value": tag-value}] to associate with the IAM instance profile. Each tag consists of
a key name and an associated value. Defaults to None.
* (Key): The key name that can be used to look up or retrieve the associated value. For example,
Department or Cost Center are common choices.
* (Value): The value associated with this tag. For example, tags with a key name of Department could have
values such as Human Resources, Accounting, and Support. Tags with a key name of Cost Center
might have values that consist of the number associated with the different cost centers in your
company. Typically, many resources have tags with the same key name but with different values.
Amazon Web Services always interprets the tag Value as a single string. If you need to store an
array, you can store comma-separated values in the string. However, you must interpret the value
in your code.
Returns:
Dict[str, Any]
Request Syntax:
[iam-instance-profile-name]:
aws.iam.instance_profile.present:
- name: 'string'
- resource_id: 'string'
- path: 'string'
- roles:
- RoleName: 'string'
- Tags:
- Key: 'string'
Value: 'string'
Example:
.. code-block:: sls
inst-profile-1:
aws.iam.instance_profile.present:
- name: inst-profile-1
- path: /aws-service-inst-profile/
- roles:
- RoleName: role-1
- Tags:
- Key: test-1
Value: test-1-val
"""
result = dict(comment=[], old_state=None, new_state=None, name=name, result=True)
before = await hub.exec.aws.iam.instance_profile.get(
ctx, name=name, resource_id=resource_id
)
if not before["result"]:
result["result"] = False
result["comment"] = before["comment"]
return result
if isinstance(tags, List):
tags = hub.tool.aws.tag_utils.convert_tag_list_to_dict(tags)
if before["ret"]:
result["old_state"] = before["ret"]
result["new_state"] = copy.deepcopy(before["ret"])
result["comment"] += [f"'{name}' already exists"]
# Update key tags if tags are specified
if tags is not None and tags != result["old_state"].get("tags", None):
hub.log.debug(f"aws.iam.instance_profile '{name}' tags update")
update_ret = (
await hub.exec.aws.iam.instance_profile.update_instance_profile_tags(
ctx=ctx,
instance_profile_name=resource_id if resource_id else name,
old_tags=result["old_state"].get("tags"),
new_tags=tags,
)
)
result["result"] = update_ret["result"]
result["comment"] += update_ret["comment"]
if not result["result"]:
return result
if ctx.get("test", False) and update_ret["ret"] is not None:
result["new_state"]["tags"] = update_ret["ret"]
else:
if ctx.get("test", False):
result["new_state"] = hub.tool.aws.test_state_utils.generate_test_state(
enforced_state={},
desired_state={
"name": name,
"path": path,
"roles": roles,
"tags": tags,
},
)
result["comment"] = hub.tool.aws.comment_utils.would_create_comment(
resource_type="aws.iam.instance_profile", name=name
)
return result
try:
ret = await hub.exec.boto3.client.iam.create_instance_profile(
ctx,
InstanceProfileName=name,
Path=path,
Tags=hub.tool.aws.tag_utils.convert_tag_dict_to_list(tags)
if tags
else None,
)
result["result"] = ret["result"]
if not ret["result"]:
result["comment"] = ret["comment"]
return result
result["comment"] = hub.tool.aws.comment_utils.create_comment(
resource_type="aws.iam.instance_profile", name=name
)
except hub.tool.boto3.exception.ClientError as e:
result["comment"] += [f"{e.__class__.__name__}: {e}"]
result["result"] = False
update_ret = None
if roles is not None:
# Instance profile can be associated only with a single role
# Remove existing role
curr_role = None
new_role = None
if before["ret"] and before["ret"].get("roles", []):
curr_role = before["ret"].get("roles")[0]["RoleName"]
if roles:
new_role = roles[0]["RoleName"]
if curr_role != new_role:
if curr_role is not None and not ctx.get("test", False):
hub.log.debug(
f"Removing role '{curr_role}' from instance profile '{name}'"
)
update_ret = (
await hub.exec.boto3.client.iam.remove_role_from_instance_profile(
ctx, InstanceProfileName=name, RoleName=curr_role
)
)
if not update_ret["result"]:
result["result"] = False
result["comment"] = update_ret["comment"]
return result
result["comment"] += [
f"Role '{curr_role}' was removed from instance profile '{name}'"
]
if new_role is not None and not ctx.get("test", False):
hub.log.debug(f"Adding role '{new_role}' to instance profile '{name}'")
update_ret = (
await hub.exec.boto3.client.iam.add_role_to_instance_profile(
ctx, InstanceProfileName=name, RoleName=new_role
)
)
if not update_ret["result"]:
result["result"] = False
result["comment"] = update_ret["comment"]
return result
result["comment"] += [
f"Role '{new_role}' was added to instance profile '{name}'"
]
# Test context when updating roles
if ctx.get("test", False):
result["comment"] += [f"Updated role in instance profile '{name}'."]
result["new_state"]["roles"] = (
[{"RoleName": new_role}] if new_role is not None else []
)
return result
if ctx.get("test", False):
return result
if before["ret"] and update_ret is None:
result["new_state"] = copy.deepcopy(result["old_state"])
else:
after = await hub.exec.aws.iam.instance_profile.get(
ctx, name=name, resource_id=resource_id
)
if not after["result"]:
result["result"] = False
result["comment"] = after["comment"]
return result
result["new_state"] = after["ret"]
return result
[docs]async def absent(hub, ctx, name: str, resource_id: str = None) -> Dict[str, Any]:
"""
**Autogenerated function**
Deletes the specified instance profile. The instance profile must not have an associated role. Make sure that
you do not have any Amazon EC2 instances running with the instance profile you are about to delete. Deleting a
role or instance profile that is associated with a running instance will break any applications running on the
instance. For more information about instance profiles, see About instance profiles.
Args:
name(str): AWS Instance Profile Name.
resource_id(str, Optional): AWS Instance Profile Name. If not specified, Idem will use "name"
parameter to identify the role policy on AWS.
Returns:
Dict[str, Any]
Request Syntax:
[iam-instance-profile-name]:
aws.iam.instance_profile.present:
- name: 'string'
Examples:
.. code-block:: sls
instance-profile-test:
aws.iam.instance_profile.absent:
- name: instance-profile-test
"""
result = dict(comment=[], old_state=None, new_state=None, name=name, result=True)
if not resource_id:
result["comment"] = hub.tool.aws.comment_utils.already_absent_comment(
resource_type="aws.iam.instance_profile", name=name
)
return result
before = await hub.exec.aws.iam.instance_profile.get(
ctx, name=name, resource_id=resource_id
)
if not before["result"]:
result["comment"] = before["comment"]
result["result"] = False
return result
if not before["ret"]:
result["comment"] = hub.tool.aws.comment_utils.already_absent_comment(
resource_type="aws.iam.instance_profile", name=name
)
return result
else:
try:
result["old_state"] = before["ret"]
if ctx.get("test", False):
result["comment"] = hub.tool.aws.comment_utils.would_delete_comment(
resource_type="aws.iam.instance_profile", name=name
)
return result
ret = await hub.exec.boto3.client.iam.delete_instance_profile(
ctx,
InstanceProfileName=name,
)
if not ret["result"]:
result["comment"] = ret["comment"]
result["result"] = False
return result
result["comment"] = hub.tool.aws.comment_utils.delete_comment(
resource_type="aws.iam.instance_profile", name=name
)
except hub.tool.boto3.exception.ClientError as e:
result["comment"] += [f"{e.__class__.__name__}: {e}"]
return result
[docs]async def describe(hub, ctx) -> Dict[str, Dict[str, Any]]:
"""
**Autogenerated function**
Describe the resource in a way that can be recreated/managed with the corresponding "present" function
Lists the instance profiles that have the specified path prefix. If there are none, the operation returns an
empty list. For more information about instance profiles, see About instance profiles. IAM resource-listing
operations return a subset of the available attributes for the resource. For example, this operation does not
return tags, even though they are an attribute of the returned object. To view all of the information for an
instance profile, see GetInstanceProfile. You can paginate the results using the MaxItems and Marker
parameters.
Returns:
Dict[str, Any]
Examples:
.. code-block:: bash
$ idem describe aws.iam.instance_profile
"""
result = {}
ret = await hub.exec.boto3.client.iam.list_instance_profiles(ctx)
if not ret["result"]:
hub.log.warning(f"Could not describe aws.iam.instance_profile {ret['comment']}")
return {}
for instance_profile in ret["ret"]["InstanceProfiles"]:
# This is required to get tags for each instance profile list_instance_profile_roles is not working
resource = await hub.exec.aws.iam.instance_profile.get(
ctx,
name=instance_profile["InstanceProfileName"],
resource_id=instance_profile["InstanceProfileName"],
)
if not resource["result"]:
hub.log.info(
f"Failed to retrieve aws.iam.instance_profile {instance_profile['InstanceProfileName']}: {resource['comment']}"
)
continue
resource_key = f"iam-instance-profile-{resource['ret']['name']}"
result[resource_key] = {
"aws.iam.instance_profile.present": [
{parameter_key: parameter_value}
for parameter_key, parameter_value in resource["ret"].items()
]
}
return result