kopia lustrzana https://github.com/simonw/s3-credentials
s3-credentials delete-user command, closes #10
rodzic
217f790089
commit
eec24e0866
17
README.md
17
README.md
|
@ -132,6 +132,23 @@ You can pass any number of usernames here. If you don't specify a username the t
|
|||
|
||||
s3-credentials list-user-policies
|
||||
|
||||
### delete-user
|
||||
|
||||
In trying out this tool it's possible you will create several different user accounts that you later decide to clean up.
|
||||
|
||||
Deleting AWS users is a little fiddly: you first need to delete their access keys, then their inline policies and finally the user themselves.
|
||||
|
||||
The `s3-credentials delete-user` handles this for you:
|
||||
|
||||
```
|
||||
% s3-credentials delete-user s3.read-write.simonw-test-bucket-10
|
||||
User: s3.read-write.simonw-test-bucket-10
|
||||
Deleted policy: s3.read-write.simonw-test-bucket-10
|
||||
Deleted access key: AKIAWXFXAIOZK3GPEIWR
|
||||
Deleted user
|
||||
```
|
||||
You can pass it multiple usernames to delete multiple users at a time.
|
||||
|
||||
## Development
|
||||
|
||||
To contribute to this tool, first checkout the code. Then create a new virtual environment:
|
||||
|
|
|
@ -233,3 +233,38 @@ def list_buckets(array, nl):
|
|||
click.echo(json.dumps(bucket, indent=4, default=str))
|
||||
if gathered:
|
||||
click.echo(json.dumps(gathered, indent=4, default=str))
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.argument("usernames", nargs=-1, required=True)
|
||||
def delete_user(usernames):
|
||||
"Delete specified users, their access keys and their inline policies"
|
||||
iam = boto3.client("iam")
|
||||
policy_paginator = iam.get_paginator("list_user_policies")
|
||||
access_key_paginator = iam.get_paginator("list_access_keys")
|
||||
for username in usernames:
|
||||
click.echo("User: {}".format(username))
|
||||
# Fetch and delete their policies
|
||||
policy_names = []
|
||||
for response in policy_paginator.paginate(UserName=username):
|
||||
for policy_name in response["PolicyNames"]:
|
||||
policy_names.append(policy_name)
|
||||
for policy_name in policy_names:
|
||||
iam.delete_user_policy(
|
||||
UserName=username,
|
||||
PolicyName=policy_name,
|
||||
)
|
||||
click.echo(" Deleted policy: {}".format(policy_name))
|
||||
# Fetch and delete their access keys
|
||||
access_key_ids = []
|
||||
for response in access_key_paginator.paginate(UserName=username):
|
||||
for access_key in response["AccessKeyMetadata"]:
|
||||
access_key_ids.append(access_key["AccessKeyId"])
|
||||
for access_key_id in access_key_ids:
|
||||
iam.delete_access_key(
|
||||
UserName=username,
|
||||
AccessKeyId=access_key_id,
|
||||
)
|
||||
click.echo(" Deleted access key: {}".format(access_key_id))
|
||||
iam.delete_user(UserName=username)
|
||||
click.echo(" Deleted user")
|
||||
|
|
|
@ -141,3 +141,44 @@ def test_list_user_policies(mocker):
|
|||
call().get_user_policy(UserName="two", PolicyName="policy-one"),
|
||||
call().get_user_policy(UserName="two", PolicyName="policy-two"),
|
||||
]
|
||||
|
||||
|
||||
def test_delete_user(mocker):
|
||||
boto3 = mocker.patch("boto3.client")
|
||||
boto3.return_value = Mock()
|
||||
boto3.return_value.get_user_policy.return_value = {
|
||||
"PolicyDocument": {"policy": "here"}
|
||||
}
|
||||
|
||||
def get_paginator(type):
|
||||
m = Mock()
|
||||
if type == "list_access_keys":
|
||||
m.paginate.return_value = [
|
||||
{"AccessKeyMetadata": [{"AccessKeyId": "one"}, {"AccessKeyId": "two"}]}
|
||||
]
|
||||
elif type == "list_user_policies":
|
||||
m.paginate.return_value = [{"PolicyNames": ["policy-one"]}]
|
||||
return m
|
||||
|
||||
boto3().get_paginator.side_effect = get_paginator
|
||||
runner = CliRunner()
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(cli, ["delete-user", "user-123"], catch_exceptions=False)
|
||||
assert result.exit_code == 0
|
||||
assert result.output == (
|
||||
"User: user-123\n"
|
||||
" Deleted policy: policy-one\n"
|
||||
" Deleted access key: one\n"
|
||||
" Deleted access key: two\n"
|
||||
" Deleted user\n"
|
||||
)
|
||||
assert boto3.mock_calls == [
|
||||
call(),
|
||||
call("iam"),
|
||||
call().get_paginator("list_user_policies"),
|
||||
call().get_paginator("list_access_keys"),
|
||||
call().delete_user_policy(UserName="user-123", PolicyName="policy-one"),
|
||||
call().delete_access_key(UserName="user-123", AccessKeyId="one"),
|
||||
call().delete_access_key(UserName="user-123", AccessKeyId="two"),
|
||||
call().delete_user(UserName="user-123"),
|
||||
]
|
||||
|
|
Ładowanie…
Reference in New Issue