mirror of
https://github.com/ceph/s3-tests.git
synced 2024-11-22 09:29:43 +00:00
iam: add account tests for Role apis
adds test cases for the following iam actions:
* CreateRole
* GetRole
* ListRoles
* DeleteRole
* UpdateRole
verified to pass against aws when an account root user's credentials are
provided in the [iam] section of s3tests.conf
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit d4ada317e1
)
This commit is contained in:
parent
a684c035fa
commit
7a5ef470d6
2 changed files with 207 additions and 0 deletions
|
@ -17,6 +17,7 @@ markers =
|
||||||
fails_on_s3
|
fails_on_s3
|
||||||
fails_with_subdomain
|
fails_with_subdomain
|
||||||
iam_account
|
iam_account
|
||||||
|
iam_role
|
||||||
iam_tenant
|
iam_tenant
|
||||||
iam_user
|
iam_user
|
||||||
lifecycle
|
lifecycle
|
||||||
|
|
|
@ -922,6 +922,32 @@ def nuke_users(client, **kwargs):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def nuke_role_policies(client, name):
|
||||||
|
p = client.get_paginator('list_role_policies')
|
||||||
|
for response in p.paginate(RoleName=name):
|
||||||
|
for policy in response['PolicyNames']:
|
||||||
|
try:
|
||||||
|
client.delete_role_policy(RoleName=name, PolicyName=policy)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def nuke_role(client, name):
|
||||||
|
# delete role policies, etc
|
||||||
|
try:
|
||||||
|
nuke_role_policies(client, name)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
client.delete_role(RoleName=name)
|
||||||
|
|
||||||
|
def nuke_roles(client, **kwargs):
|
||||||
|
p = client.get_paginator('list_roles')
|
||||||
|
for response in p.paginate(**kwargs):
|
||||||
|
for role in response['Roles']:
|
||||||
|
try:
|
||||||
|
nuke_role(client, role['RoleName'])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# fixture for iam account root user
|
# fixture for iam account root user
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def iam_root(configfile):
|
def iam_root(configfile):
|
||||||
|
@ -935,6 +961,7 @@ def iam_root(configfile):
|
||||||
|
|
||||||
yield client
|
yield client
|
||||||
nuke_users(client, PathPrefix=get_iam_path_prefix())
|
nuke_users(client, PathPrefix=get_iam_path_prefix())
|
||||||
|
nuke_roles(client, PathPrefix=get_iam_path_prefix())
|
||||||
|
|
||||||
|
|
||||||
# IAM User apis
|
# IAM User apis
|
||||||
|
@ -1512,3 +1539,182 @@ def test_account_user_policy_allow(iam_root):
|
||||||
# the policy may take a bit to start working. retry until it returns
|
# the policy may take a bit to start working. retry until it returns
|
||||||
# something other than AccessDenied
|
# something other than AccessDenied
|
||||||
retry_on('AccessDenied', 10, client.list_buckets)
|
retry_on('AccessDenied', 10, client.list_buckets)
|
||||||
|
|
||||||
|
|
||||||
|
assume_role_policy = json.dumps({
|
||||||
|
'Version': '2012-10-17',
|
||||||
|
'Statement': [{
|
||||||
|
'Effect': 'Allow',
|
||||||
|
'Action': 'sts:AssumeRole',
|
||||||
|
'Principal': {'AWS': '*'}
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
# IAM Role apis
|
||||||
|
@pytest.mark.iam_account
|
||||||
|
@pytest.mark.iam_role
|
||||||
|
def test_account_role_create(iam_root):
|
||||||
|
path = get_iam_path_prefix()
|
||||||
|
name1 = make_iam_name('R1')
|
||||||
|
desc = 'my role description'
|
||||||
|
max_duration = 43200
|
||||||
|
response = iam_root.create_role(RoleName=name1, Path=path, AssumeRolePolicyDocument=assume_role_policy, Description=desc, MaxSessionDuration=max_duration)
|
||||||
|
role = response['Role']
|
||||||
|
assert role['Path'] == path
|
||||||
|
assert role['RoleName'] == name1
|
||||||
|
assert assume_role_policy == json.dumps(role['AssumeRolePolicyDocument'])
|
||||||
|
assert len(role['RoleId'])
|
||||||
|
arn = role['Arn']
|
||||||
|
assert arn.startswith('arn:aws:iam:')
|
||||||
|
assert arn.endswith(f':role{path}{name1}')
|
||||||
|
assert role['CreateDate'] > datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc)
|
||||||
|
# AWS doesn't include these for CreateRole, only GetRole
|
||||||
|
#assert desc == role['Description']
|
||||||
|
#assert max_duration == role['MaxSessionDuration']
|
||||||
|
|
||||||
|
response = iam_root.get_role(RoleName=name1)
|
||||||
|
role = response['Role']
|
||||||
|
assert arn == role['Arn']
|
||||||
|
assert desc == role['Description']
|
||||||
|
assert max_duration == role['MaxSessionDuration']
|
||||||
|
|
||||||
|
path2 = get_iam_path_prefix() + 'foo/'
|
||||||
|
with pytest.raises(iam_root.exceptions.EntityAlreadyExistsException):
|
||||||
|
iam_root.create_role(RoleName=name1, Path=path2, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
|
||||||
|
name2 = make_iam_name('R2')
|
||||||
|
response = iam_root.create_role(RoleName=name2, Path=path2, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
role = response['Role']
|
||||||
|
assert role['Path'] == path2
|
||||||
|
assert role['RoleName'] == name2
|
||||||
|
|
||||||
|
@pytest.mark.iam_account
|
||||||
|
@pytest.mark.iam_role
|
||||||
|
def test_account_role_case_insensitive_name(iam_root):
|
||||||
|
path = get_iam_path_prefix()
|
||||||
|
name_upper = make_iam_name('R1')
|
||||||
|
name_lower = make_iam_name('r1')
|
||||||
|
response = iam_root.create_role(RoleName=name_upper, Path=path, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
rid = response['Role']['RoleId']
|
||||||
|
|
||||||
|
# name is case-insensitive, so 'r1' should also conflict
|
||||||
|
with pytest.raises(iam_root.exceptions.EntityAlreadyExistsException):
|
||||||
|
iam_root.create_role(RoleName=name_lower, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
|
||||||
|
# search for 'r1' should return the same 'R1' role
|
||||||
|
response = iam_root.get_role(RoleName=name_lower)
|
||||||
|
assert rid == response['Role']['RoleId']
|
||||||
|
|
||||||
|
# delete for 'r1' should delete the same 'R1' role
|
||||||
|
iam_root.delete_role(RoleName=name_lower)
|
||||||
|
|
||||||
|
with pytest.raises(iam_root.exceptions.NoSuchEntityException):
|
||||||
|
iam_root.get_role(RoleName=name_lower)
|
||||||
|
|
||||||
|
@pytest.mark.iam_account
|
||||||
|
@pytest.mark.iam_role
|
||||||
|
def test_account_role_delete(iam_root):
|
||||||
|
path = get_iam_path_prefix()
|
||||||
|
name = make_iam_name('U1')
|
||||||
|
with pytest.raises(iam_root.exceptions.NoSuchEntityException):
|
||||||
|
iam_root.delete_role(RoleName=name)
|
||||||
|
|
||||||
|
response = iam_root.create_role(RoleName=name, Path=path, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
uid = response['Role']['RoleId']
|
||||||
|
create_date = response['Role']['CreateDate']
|
||||||
|
|
||||||
|
iam_root.delete_role(RoleName=name)
|
||||||
|
|
||||||
|
response = iam_root.create_role(RoleName=name, Path=path, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
assert uid != response['Role']['RoleId']
|
||||||
|
assert create_date <= response['Role']['CreateDate']
|
||||||
|
|
||||||
|
def role_list_names(client, **kwargs):
|
||||||
|
p = client.get_paginator('list_roles')
|
||||||
|
rolenames = []
|
||||||
|
for response in p.paginate(**kwargs):
|
||||||
|
rolenames += [u['RoleName'] for u in response['Roles']]
|
||||||
|
return rolenames
|
||||||
|
|
||||||
|
@pytest.mark.iam_account
|
||||||
|
@pytest.mark.iam_role
|
||||||
|
def test_account_role_list(iam_root):
|
||||||
|
path = get_iam_path_prefix()
|
||||||
|
response = iam_root.list_roles(PathPrefix=path)
|
||||||
|
assert len(response['Roles']) == 0
|
||||||
|
assert response['IsTruncated'] == False
|
||||||
|
|
||||||
|
name1 = make_iam_name('aa')
|
||||||
|
name2 = make_iam_name('Ab')
|
||||||
|
name3 = make_iam_name('ac')
|
||||||
|
name4 = make_iam_name('Ad')
|
||||||
|
|
||||||
|
# sort order is independent of CreateDate, Path, and RoleName capitalization
|
||||||
|
iam_root.create_role(RoleName=name4, Path=path+'w/', AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
iam_root.create_role(RoleName=name3, Path=path+'x/', AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
iam_root.create_role(RoleName=name2, Path=path+'y/', AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
iam_root.create_role(RoleName=name1, Path=path+'z/', AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
|
||||||
|
assert [name1, name2, name3, name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path)
|
||||||
|
assert [name1, name2, name3, name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path, PaginationConfig={'PageSize': 1})
|
||||||
|
|
||||||
|
@pytest.mark.iam_account
|
||||||
|
@pytest.mark.iam_role
|
||||||
|
def test_account_role_list_path_prefix(iam_root):
|
||||||
|
path = get_iam_path_prefix()
|
||||||
|
response = iam_root.list_roles(PathPrefix=path)
|
||||||
|
assert len(response['Roles']) == 0
|
||||||
|
assert response['IsTruncated'] == False
|
||||||
|
|
||||||
|
name1 = make_iam_name('a')
|
||||||
|
name2 = make_iam_name('b')
|
||||||
|
name3 = make_iam_name('c')
|
||||||
|
name4 = make_iam_name('d')
|
||||||
|
|
||||||
|
iam_root.create_role(RoleName=name1, Path=path, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
iam_root.create_role(RoleName=name2, Path=path, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
iam_root.create_role(RoleName=name3, Path=path+'a/', AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
iam_root.create_role(RoleName=name4, Path=path+'a/x/', AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
|
||||||
|
assert [name1, name2, name3, name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path)
|
||||||
|
assert [name1, name2, name3, name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path,
|
||||||
|
PaginationConfig={'PageSize': 1})
|
||||||
|
assert [name3, name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path+'a')
|
||||||
|
assert [name3, name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path+'a',
|
||||||
|
PaginationConfig={'PageSize': 1})
|
||||||
|
assert [name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path+'a/x')
|
||||||
|
assert [name4] == \
|
||||||
|
role_list_names(iam_root, PathPrefix=path+'a/x',
|
||||||
|
PaginationConfig={'PageSize': 1})
|
||||||
|
assert [] == role_list_names(iam_root, PathPrefix=path+'a/x/d')
|
||||||
|
|
||||||
|
@pytest.mark.iam_account
|
||||||
|
@pytest.mark.iam_role
|
||||||
|
def test_account_role_update(iam_root):
|
||||||
|
path = get_iam_path_prefix()
|
||||||
|
name = make_iam_name('a')
|
||||||
|
with pytest.raises(iam_root.exceptions.NoSuchEntityException):
|
||||||
|
iam_root.update_role(RoleName=name)
|
||||||
|
|
||||||
|
iam_root.create_role(RoleName=name, Path=path, AssumeRolePolicyDocument=assume_role_policy)
|
||||||
|
|
||||||
|
response = iam_root.get_role(RoleName=name)
|
||||||
|
assert name == response['Role']['RoleName']
|
||||||
|
arn = response['Role']['Arn']
|
||||||
|
rid = response['Role']['RoleId']
|
||||||
|
|
||||||
|
desc = 'my role description'
|
||||||
|
iam_root.update_role(RoleName=name, Description=desc, MaxSessionDuration=43200)
|
||||||
|
|
||||||
|
response = iam_root.get_role(RoleName=name)
|
||||||
|
assert rid == response['Role']['RoleId']
|
||||||
|
assert arn == response['Role']['Arn']
|
||||||
|
assert desc == response['Role']['Description']
|
||||||
|
assert 43200 == response['Role']['MaxSessionDuration']
|
||||||
|
|
Loading…
Reference in a new issue