Add tag & untag user (#3638)
* Add iam.tag_user * Add iam.untag_user * Fix Python2 error
This commit is contained in:
parent
f918635ab5
commit
fe9f1dfe14
@ -45,6 +45,7 @@ from .utils import (
|
|||||||
random_resource_id,
|
random_resource_id,
|
||||||
random_policy_id,
|
random_policy_id,
|
||||||
)
|
)
|
||||||
|
from ..utilities.tagging_service import TaggingService
|
||||||
|
|
||||||
|
|
||||||
class MFADevice(object):
|
class MFADevice(object):
|
||||||
@ -924,7 +925,7 @@ class Group(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class User(CloudFormationModel):
|
class User(CloudFormationModel):
|
||||||
def __init__(self, name, path=None, tags=None):
|
def __init__(self, name, path=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.id = random_resource_id()
|
self.id = random_resource_id()
|
||||||
self.path = path if path else "/"
|
self.path = path if path else "/"
|
||||||
@ -937,7 +938,6 @@ class User(CloudFormationModel):
|
|||||||
self.password = None
|
self.password = None
|
||||||
self.password_reset_required = False
|
self.password_reset_required = False
|
||||||
self.signing_certificates = {}
|
self.signing_certificates = {}
|
||||||
self.tags = tags
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def arn(self):
|
def arn(self):
|
||||||
@ -1135,7 +1135,8 @@ class User(CloudFormationModel):
|
|||||||
):
|
):
|
||||||
properties = cloudformation_json.get("Properties", {})
|
properties = cloudformation_json.get("Properties", {})
|
||||||
path = properties.get("Path")
|
path = properties.get("Path")
|
||||||
return iam_backend.create_user(resource_physical_name, path)
|
user, _ = iam_backend.create_user(resource_physical_name, path)
|
||||||
|
return user
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_from_cloudformation_json(
|
def update_from_cloudformation_json(
|
||||||
@ -1415,6 +1416,8 @@ class IAMBackend(BaseBackend):
|
|||||||
self.account_summary = AccountSummary(self)
|
self.account_summary = AccountSummary(self)
|
||||||
self.inline_policies = {}
|
self.inline_policies = {}
|
||||||
self.access_keys = {}
|
self.access_keys = {}
|
||||||
|
|
||||||
|
self.tagger = TaggingService()
|
||||||
super(IAMBackend, self).__init__()
|
super(IAMBackend, self).__init__()
|
||||||
|
|
||||||
def _init_managed_policies(self):
|
def _init_managed_policies(self):
|
||||||
@ -1978,16 +1981,16 @@ class IAMBackend(BaseBackend):
|
|||||||
"EntityAlreadyExists", "User {0} already exists".format(user_name)
|
"EntityAlreadyExists", "User {0} already exists".format(user_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
user = User(user_name, path, tags)
|
user = User(user_name, path)
|
||||||
|
self.tagger.tag_resource(user.arn, tags or [])
|
||||||
self.users[user_name] = user
|
self.users[user_name] = user
|
||||||
return user
|
return user, self.tagger.list_tags_for_resource(user.arn)
|
||||||
|
|
||||||
def get_user(self, user_name):
|
def get_user(self, name):
|
||||||
user = None
|
user = self.users.get(name)
|
||||||
try:
|
|
||||||
user = self.users[user_name]
|
if not user:
|
||||||
except KeyError:
|
raise NoSuchEntity("The user with name {} cannot be found.".format(name))
|
||||||
raise IAMNotFoundException("User {0} not found".format(user_name))
|
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
@ -2147,7 +2150,7 @@ class IAMBackend(BaseBackend):
|
|||||||
|
|
||||||
def list_user_tags(self, user_name):
|
def list_user_tags(self, user_name):
|
||||||
user = self.get_user(user_name)
|
user = self.get_user(user_name)
|
||||||
return user.tags
|
return self.tagger.list_tags_for_resource(user.arn)
|
||||||
|
|
||||||
def put_user_policy(self, user_name, policy_name, policy_json):
|
def put_user_policy(self, user_name, policy_name, policy_json):
|
||||||
user = self.get_user(user_name)
|
user = self.get_user(user_name)
|
||||||
@ -2204,7 +2207,7 @@ class IAMBackend(BaseBackend):
|
|||||||
try: # User may have been deleted before their access key...
|
try: # User may have been deleted before their access key...
|
||||||
user = self.get_user(key.user_name)
|
user = self.get_user(key.user_name)
|
||||||
user.delete_access_key(key.access_key_id)
|
user.delete_access_key(key.access_key_id)
|
||||||
except IAMNotFoundException:
|
except NoSuchEntity:
|
||||||
pass
|
pass
|
||||||
del self.access_keys[name]
|
del self.access_keys[name]
|
||||||
|
|
||||||
@ -2250,7 +2253,7 @@ class IAMBackend(BaseBackend):
|
|||||||
"CreateDate": user.created_iso_8601,
|
"CreateDate": user.created_iso_8601,
|
||||||
"PasswordLastUsed": None, # not supported
|
"PasswordLastUsed": None, # not supported
|
||||||
"PermissionsBoundary": {}, # ToDo: add put_user_permissions_boundary() functionality
|
"PermissionsBoundary": {}, # ToDo: add put_user_permissions_boundary() functionality
|
||||||
"Tags": {}, # ToDo: add tag_user() functionality
|
"Tags": self.tagger.list_tags_for_resource(user.arn)["Tags"],
|
||||||
}
|
}
|
||||||
|
|
||||||
user.enable_mfa_device(
|
user.enable_mfa_device(
|
||||||
@ -2355,6 +2358,7 @@ class IAMBackend(BaseBackend):
|
|||||||
code="DeleteConflict",
|
code="DeleteConflict",
|
||||||
message="Cannot delete entity, must delete policies first.",
|
message="Cannot delete entity, must delete policies first.",
|
||||||
)
|
)
|
||||||
|
self.tagger.delete_all_tags_for_resource(user.arn)
|
||||||
del self.users[user_name]
|
del self.users[user_name]
|
||||||
|
|
||||||
def report_generated(self):
|
def report_generated(self):
|
||||||
@ -2574,5 +2578,15 @@ class IAMBackend(BaseBackend):
|
|||||||
inline_policy.unapply_policy(self)
|
inline_policy.unapply_policy(self)
|
||||||
del self.inline_policies[policy_id]
|
del self.inline_policies[policy_id]
|
||||||
|
|
||||||
|
def tag_user(self, name, tags):
|
||||||
|
user = self.get_user(name)
|
||||||
|
|
||||||
|
self.tagger.tag_resource(user.arn, tags)
|
||||||
|
|
||||||
|
def untag_user(self, name, tag_keys):
|
||||||
|
user = self.get_user(name)
|
||||||
|
|
||||||
|
self.tagger.untag_resource_using_names(user.arn, tag_keys)
|
||||||
|
|
||||||
|
|
||||||
iam_backend = IAMBackend()
|
iam_backend = IAMBackend()
|
||||||
|
@ -471,9 +471,9 @@ class IamResponse(BaseResponse):
|
|||||||
user_name = self._get_param("UserName")
|
user_name = self._get_param("UserName")
|
||||||
path = self._get_param("Path")
|
path = self._get_param("Path")
|
||||||
tags = self._get_multi_param("Tags.member")
|
tags = self._get_multi_param("Tags.member")
|
||||||
user = iam_backend.create_user(user_name, path, tags)
|
user, user_tags = iam_backend.create_user(user_name, path, tags)
|
||||||
template = self.response_template(USER_TEMPLATE)
|
template = self.response_template(USER_TEMPLATE)
|
||||||
return template.render(action="Create", user=user)
|
return template.render(action="Create", user=user, tags=user_tags["Tags"])
|
||||||
|
|
||||||
def get_user(self):
|
def get_user(self):
|
||||||
user_name = self._get_param("UserName")
|
user_name = self._get_param("UserName")
|
||||||
@ -572,7 +572,7 @@ class IamResponse(BaseResponse):
|
|||||||
user_name = self._get_param("UserName")
|
user_name = self._get_param("UserName")
|
||||||
tags = iam_backend.list_user_tags(user_name)
|
tags = iam_backend.list_user_tags(user_name)
|
||||||
template = self.response_template(LIST_USER_TAGS_TEMPLATE)
|
template = self.response_template(LIST_USER_TAGS_TEMPLATE)
|
||||||
return template.render(user_tags=tags or [])
|
return template.render(user_tags=tags["Tags"])
|
||||||
|
|
||||||
def put_user_policy(self):
|
def put_user_policy(self):
|
||||||
user_name = self._get_param("UserName")
|
user_name = self._get_param("UserName")
|
||||||
@ -989,6 +989,24 @@ class IamResponse(BaseResponse):
|
|||||||
template = self.response_template(GET_ACCOUNT_SUMMARY_TEMPLATE)
|
template = self.response_template(GET_ACCOUNT_SUMMARY_TEMPLATE)
|
||||||
return template.render(summary_map=account_summary.summary_map)
|
return template.render(summary_map=account_summary.summary_map)
|
||||||
|
|
||||||
|
def tag_user(self):
|
||||||
|
name = self._get_param("UserName")
|
||||||
|
tags = self._get_multi_param("Tags.member")
|
||||||
|
|
||||||
|
iam_backend.tag_user(name, tags)
|
||||||
|
|
||||||
|
template = self.response_template(TAG_USER_TEMPLATE)
|
||||||
|
return template.render()
|
||||||
|
|
||||||
|
def untag_user(self):
|
||||||
|
name = self._get_param("UserName")
|
||||||
|
tag_keys = self._get_multi_param("TagKeys.member")
|
||||||
|
|
||||||
|
iam_backend.untag_user(name, tag_keys)
|
||||||
|
|
||||||
|
template = self.response_template(UNTAG_USER_TEMPLATE)
|
||||||
|
return template.render()
|
||||||
|
|
||||||
|
|
||||||
LIST_ENTITIES_FOR_POLICY_TEMPLATE = """<ListEntitiesForPolicyResponse>
|
LIST_ENTITIES_FOR_POLICY_TEMPLATE = """<ListEntitiesForPolicyResponse>
|
||||||
<ListEntitiesForPolicyResult>
|
<ListEntitiesForPolicyResult>
|
||||||
@ -1684,9 +1702,9 @@ USER_TEMPLATE = """<{{ action }}UserResponse>
|
|||||||
<UserId>{{ user.id }}</UserId>
|
<UserId>{{ user.id }}</UserId>
|
||||||
<CreateDate>{{ user.created_iso_8601 }}</CreateDate>
|
<CreateDate>{{ user.created_iso_8601 }}</CreateDate>
|
||||||
<Arn>{{ user.arn }}</Arn>
|
<Arn>{{ user.arn }}</Arn>
|
||||||
{% if user.tags %}
|
{% if tags %}
|
||||||
<Tags>
|
<Tags>
|
||||||
{% for tag in user.tags %}
|
{% for tag in tags %}
|
||||||
<member>
|
<member>
|
||||||
<Key>{{ tag['Key'] }}</Key>
|
<Key>{{ tag['Key'] }}</Key>
|
||||||
<Value>{{ tag['Value'] }}</Value>
|
<Value>{{ tag['Value'] }}</Value>
|
||||||
@ -2039,13 +2057,23 @@ LIST_VIRTUAL_MFA_DEVICES_TEMPLATE = """<ListVirtualMFADevicesResponse xmlns="htt
|
|||||||
{% if device.enable_date %}
|
{% if device.enable_date %}
|
||||||
<EnableDate>{{ device.enabled_iso_8601 }}</EnableDate>
|
<EnableDate>{{ device.enabled_iso_8601 }}</EnableDate>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if device.user %}
|
{% if device.user_attribute %}
|
||||||
<User>
|
<User>
|
||||||
<Path>{{ device.user.path }}</Path>
|
<Path>{{ device.user_attribute.Path }}</Path>
|
||||||
<UserName>{{ device.user.name }}</UserName>
|
<UserName>{{ device.user_attribute.UserName }}</UserName>
|
||||||
<UserId>{{ device.user.id }}</UserId>
|
<UserId>{{ device.user_attribute.UserId }}</UserId>
|
||||||
<CreateDate>{{ device.user.created_iso_8601 }}</CreateDate>
|
<CreateDate>{{ device.user_attribute.CreateDate }}</CreateDate>
|
||||||
<Arn>{{ device.user.arn }}</Arn>
|
<Arn>{{ device.user_attribute.Arn }}</Arn>
|
||||||
|
{% if device.user_attribute.Tags %}
|
||||||
|
<Tags>
|
||||||
|
{% for tag in device.user_attribute.Tags %}
|
||||||
|
<member>
|
||||||
|
<Key>{{ tag['Key'] }}</Key>
|
||||||
|
<Value>{{ tag['Value'] }}</Value>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Tags>
|
||||||
|
{% endif %}
|
||||||
</User>
|
</User>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</member>
|
</member>
|
||||||
@ -2514,3 +2542,17 @@ GET_ACCOUNT_SUMMARY_TEMPLATE = """<GetAccountSummaryResponse xmlns="https://iam.
|
|||||||
<RequestId>85cb9b90-ac28-11e4-a88d-97964EXAMPLE</RequestId>
|
<RequestId>85cb9b90-ac28-11e4-a88d-97964EXAMPLE</RequestId>
|
||||||
</ResponseMetadata>
|
</ResponseMetadata>
|
||||||
</GetAccountSummaryResponse>"""
|
</GetAccountSummaryResponse>"""
|
||||||
|
|
||||||
|
|
||||||
|
TAG_USER_TEMPLATE = """<TagUserResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>EXAMPLE8-90ab-cdef-fedc-ba987EXAMPLE</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</TagUserResponse>"""
|
||||||
|
|
||||||
|
|
||||||
|
UNTAG_USER_TEMPLATE = """<UntagUserResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>EXAMPLE8-90ab-cdef-fedc-ba987EXAMPLE</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</UntagUserResponse>"""
|
||||||
|
@ -1140,8 +1140,9 @@ def test_enable_virtual_mfa_device():
|
|||||||
client = boto3.client("iam", region_name="us-east-1")
|
client = boto3.client("iam", region_name="us-east-1")
|
||||||
response = client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
response = client.create_virtual_mfa_device(VirtualMFADeviceName="test-device")
|
||||||
serial_number = response["VirtualMFADevice"]["SerialNumber"]
|
serial_number = response["VirtualMFADevice"]["SerialNumber"]
|
||||||
|
tags = [{"Key": "key", "Value": "value"}]
|
||||||
|
|
||||||
client.create_user(UserName="test-user")
|
client.create_user(UserName="test-user", Tags=tags)
|
||||||
client.enable_mfa_device(
|
client.enable_mfa_device(
|
||||||
UserName="test-user",
|
UserName="test-user",
|
||||||
SerialNumber=serial_number,
|
SerialNumber=serial_number,
|
||||||
@ -1165,6 +1166,7 @@ def test_enable_virtual_mfa_device():
|
|||||||
"arn:aws:iam::{}:user/test-user".format(ACCOUNT_ID)
|
"arn:aws:iam::{}:user/test-user".format(ACCOUNT_ID)
|
||||||
)
|
)
|
||||||
device["User"]["CreateDate"].should.be.a(datetime)
|
device["User"]["CreateDate"].should.be.a(datetime)
|
||||||
|
device["User"]["Tags"].should.equal(tags)
|
||||||
device["EnableDate"].should.be.a(datetime)
|
device["EnableDate"].should.be.a(datetime)
|
||||||
response["IsTruncated"].should_not.be.ok
|
response["IsTruncated"].should_not.be.ok
|
||||||
|
|
||||||
@ -2924,7 +2926,7 @@ def test_list_user_tags():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
response = conn.list_user_tags(UserName="kenny-bania")
|
response = conn.list_user_tags(UserName="kenny-bania")
|
||||||
response["Tags"].should.equal([])
|
response["Tags"].should.have.length_of(0)
|
||||||
response["IsTruncated"].should_not.be.ok
|
response["IsTruncated"].should_not.be.ok
|
||||||
|
|
||||||
response = conn.list_user_tags(UserName="jackie-chiles")
|
response = conn.list_user_tags(UserName="jackie-chiles")
|
||||||
@ -4047,3 +4049,80 @@ def test_create_user_with_tags():
|
|||||||
|
|
||||||
resp = conn.create_user(UserName="test-create-user-no-tags")
|
resp = conn.create_user(UserName="test-create-user-no-tags")
|
||||||
assert "Tags" not in resp["User"]
|
assert "Tags" not in resp["User"]
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam
|
||||||
|
def test_tag_user():
|
||||||
|
# given
|
||||||
|
client = boto3.client("iam", region_name="eu-central-1")
|
||||||
|
name = "test-user"
|
||||||
|
tags = sorted(
|
||||||
|
[{"Key": "key", "Value": "value"}, {"Key": "key-2", "Value": "value-2"}],
|
||||||
|
key=lambda item: item["Key"],
|
||||||
|
)
|
||||||
|
client.create_user(UserName=name)
|
||||||
|
|
||||||
|
# when
|
||||||
|
client.tag_user(UserName=name, Tags=tags)
|
||||||
|
|
||||||
|
# then
|
||||||
|
response = client.list_user_tags(UserName=name)
|
||||||
|
sorted(response["Tags"], key=lambda item: item["Key"],).should.equal(tags)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam
|
||||||
|
def test_tag_user_error_unknown_user_name():
|
||||||
|
# given
|
||||||
|
client = boto3.client("iam", region_name="eu-central-1")
|
||||||
|
name = "unknown"
|
||||||
|
|
||||||
|
# when
|
||||||
|
with pytest.raises(ClientError) as e:
|
||||||
|
client.tag_user(UserName=name, Tags=[{"Key": "key", "Value": "value"}])
|
||||||
|
|
||||||
|
# then
|
||||||
|
ex = e.value
|
||||||
|
ex.operation_name.should.equal("TagUser")
|
||||||
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(404)
|
||||||
|
ex.response["Error"]["Code"].should.contain("NoSuchEntity")
|
||||||
|
ex.response["Error"]["Message"].should.equal(
|
||||||
|
"The user with name {} cannot be found.".format(name)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam
|
||||||
|
def test_untag_user():
|
||||||
|
# given
|
||||||
|
client = boto3.client("iam", region_name="eu-central-1")
|
||||||
|
name = "test-user"
|
||||||
|
client.create_user(
|
||||||
|
UserName=name,
|
||||||
|
Tags=[{"Key": "key", "Value": "value"}, {"Key": "key-2", "Value": "value"}],
|
||||||
|
)
|
||||||
|
|
||||||
|
# when
|
||||||
|
client.untag_user(UserName=name, TagKeys=["key-2"])
|
||||||
|
|
||||||
|
# then
|
||||||
|
response = client.list_user_tags(UserName=name)
|
||||||
|
response["Tags"].should.equal([{"Key": "key", "Value": "value"}])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_iam
|
||||||
|
def test_untag_user_error_unknown_user_name():
|
||||||
|
# given
|
||||||
|
client = boto3.client("iam", region_name="eu-central-1")
|
||||||
|
name = "unknown"
|
||||||
|
|
||||||
|
# when
|
||||||
|
with pytest.raises(ClientError) as e:
|
||||||
|
client.untag_user(UserName=name, TagKeys=["key"])
|
||||||
|
|
||||||
|
# then
|
||||||
|
ex = e.value
|
||||||
|
ex.operation_name.should.equal("UntagUser")
|
||||||
|
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(404)
|
||||||
|
ex.response["Error"]["Code"].should.contain("NoSuchEntity")
|
||||||
|
ex.response["Error"]["Message"].should.equal(
|
||||||
|
"The user with name {} cannot be found.".format(name)
|
||||||
|
)
|
||||||
|
@ -967,59 +967,6 @@ Outputs:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
|
||||||
@mock_cloudformation
|
|
||||||
def test_iam_cloudformation_delete_users_access_key():
|
|
||||||
cf_client = boto3.client("cloudformation", region_name="us-east-1")
|
|
||||||
|
|
||||||
stack_name = "MyStack"
|
|
||||||
|
|
||||||
template = """
|
|
||||||
Resources:
|
|
||||||
TheUser:
|
|
||||||
Type: AWS::IAM::User
|
|
||||||
TheAccessKey:
|
|
||||||
Type: AWS::IAM::AccessKey
|
|
||||||
Properties:
|
|
||||||
UserName: !Ref TheUser
|
|
||||||
""".strip()
|
|
||||||
|
|
||||||
cf_client.create_stack(StackName=stack_name, TemplateBody=template)
|
|
||||||
|
|
||||||
provisioned_resources = cf_client.list_stack_resources(StackName=stack_name)[
|
|
||||||
"StackResourceSummaries"
|
|
||||||
]
|
|
||||||
|
|
||||||
provisioned_user = [
|
|
||||||
resource
|
|
||||||
for resource in provisioned_resources
|
|
||||||
if resource["LogicalResourceId"] == "TheUser"
|
|
||||||
][0]
|
|
||||||
user_name = provisioned_user["PhysicalResourceId"]
|
|
||||||
|
|
||||||
provisioned_access_key = [
|
|
||||||
resource
|
|
||||||
for resource in provisioned_resources
|
|
||||||
if resource["LogicalResourceId"] == "TheAccessKey"
|
|
||||||
][0]
|
|
||||||
access_key_id = provisioned_access_key["PhysicalResourceId"]
|
|
||||||
|
|
||||||
iam_client = boto3.client("iam", region_name="us-east-1")
|
|
||||||
user = iam_client.get_user(UserName=user_name)
|
|
||||||
access_keys = iam_client.list_access_keys(UserName=user_name)
|
|
||||||
|
|
||||||
access_key_id.should.equal(access_keys["AccessKeyMetadata"][0]["AccessKeyId"])
|
|
||||||
|
|
||||||
cf_client.delete_stack(StackName=stack_name)
|
|
||||||
|
|
||||||
iam_client.get_user.when.called_with(UserName=user_name).should.throw(
|
|
||||||
iam_client.exceptions.NoSuchEntityException
|
|
||||||
)
|
|
||||||
iam_client.list_access_keys.when.called_with(UserName=user_name).should.throw(
|
|
||||||
iam_client.exceptions.NoSuchEntityException
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
@mock_cloudformation
|
@mock_cloudformation
|
||||||
def test_iam_cloudformation_delete_users_access_key():
|
def test_iam_cloudformation_delete_users_access_key():
|
||||||
@ -1055,13 +1002,15 @@ def test_iam_cloudformation_delete_users_access_key():
|
|||||||
for resource in provisioned_resources
|
for resource in provisioned_resources
|
||||||
if resource["LogicalResourceId"] == "TheAccessKey"
|
if resource["LogicalResourceId"] == "TheAccessKey"
|
||||||
]
|
]
|
||||||
len(provisioned_access_keys).should.equal(1)
|
provisioned_access_keys.should.have.length_of(1)
|
||||||
|
access_key_id = provisioned_access_keys[0]["PhysicalResourceId"]
|
||||||
|
|
||||||
iam_client = boto3.client("iam", region_name="us-east-1")
|
iam_client = boto3.client("iam", region_name="us-east-1")
|
||||||
user = iam_client.get_user(UserName=user_name)["User"]
|
user = iam_client.get_user(UserName=user_name)["User"]
|
||||||
user["UserName"].should.equal(user_name)
|
user["UserName"].should.equal(user_name)
|
||||||
access_keys = iam_client.list_access_keys(UserName=user_name)
|
access_keys = iam_client.list_access_keys(UserName=user_name)
|
||||||
access_keys["AccessKeyMetadata"][0]["UserName"].should.equal(user_name)
|
access_keys["AccessKeyMetadata"][0]["UserName"].should.equal(user_name)
|
||||||
|
access_key_id.should.equal(access_keys["AccessKeyMetadata"][0]["AccessKeyId"])
|
||||||
|
|
||||||
cf_client.delete_stack(StackName=stack_name)
|
cf_client.delete_stack(StackName=stack_name)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user