diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index f4b3cd3c0..e1ed8b2cb 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -3163,7 +3163,7 @@ - [ ] describe_events ## iam -59% implemented +60% implemented - [ ] add_client_id_to_open_id_connect_provider - [X] add_role_to_instance_profile - [X] add_user_to_group @@ -3208,7 +3208,7 @@ - [X] delete_user - [ ] delete_user_permissions_boundary - [X] delete_user_policy -- [ ] delete_virtual_mfa_device +- [X] delete_virtual_mfa_device - [X] detach_group_policy - [X] detach_role_policy - [X] detach_user_policy diff --git a/moto/iam/models.py b/moto/iam/models.py index 00aff40e5..5ac1ea3b5 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -1295,6 +1295,12 @@ class IAMBackend(BaseBackend): self.virtual_mfa_devices[device.serial_number] = device return device + def delete_virtual_mfa_device(self, serial_number): + device = self.virtual_mfa_devices.pop(serial_number, None) + + if not device: + raise IAMNotFoundException('VirtualMFADevice with serial number {0} doesn\'t exist.'.format(serial_number)) + def delete_user(self, user_name): try: del self.users[user_name] diff --git a/moto/iam/responses.py b/moto/iam/responses.py index c2df50137..8afe85e49 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -607,6 +607,14 @@ class IamResponse(BaseResponse): template = self.response_template(CREATE_VIRTUAL_MFA_DEVICE_TEMPLATE) return template.render(device=virtual_mfa_device) + def delete_virtual_mfa_device(self): + serial_number = self._get_param('SerialNumber') + + iam_backend.delete_virtual_mfa_device(serial_number) + + template = self.response_template(DELETE_VIRTUAL_MFA_DEVICE_TEMPLATE) + return template.render() + def delete_user(self): user_name = self._get_param('UserName') iam_backend.delete_user(user_name) @@ -1697,6 +1705,13 @@ CREATE_VIRTUAL_MFA_DEVICE_TEMPLATE = """ + + 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE + +""" + + LIST_ACCOUNT_ALIASES_TEMPLATE = """ false diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index 2a1e65d29..d765e4b87 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -800,6 +800,32 @@ def test_create_virtual_mfa_device_errors(): ) +@mock_iam +def test_delete_virtual_mfa_device(): + client = boto3.client('iam', region_name='us-east-1') + response = client.create_virtual_mfa_device( + VirtualMFADeviceName='test-device' + ) + serial_number = response['VirtualMFADevice']['SerialNumber'] + + client.delete_virtual_mfa_device( + SerialNumber=serial_number + ) + + +@mock_iam +def test_delete_virtual_mfa_device_errors(): + client = boto3.client('iam', region_name='us-east-1') + + serial_number = 'arn:aws:iam::123456789012:mfa/not-existing' + client.delete_virtual_mfa_device.when.called_with( + SerialNumber=serial_number + ).should.throw( + ClientError, + 'VirtualMFADevice with serial number {0} doesn\'t exist.'.format(serial_number) + ) + + @mock_iam_deprecated() def test_delete_user_deprecated(): conn = boto.connect_iam()