Skip to content

Commit 855db87

Browse files
rgw/qa: added test case to assume a role after role creation
syncs, and then creating a bucket on both primary and secondary. The test name is test_assume_role_after_sync. Signed-off-by: Pritha Srivastava <[email protected]>
1 parent 63bc738 commit 855db87

File tree

7 files changed

+103
-5
lines changed

7 files changed

+103
-5
lines changed

qa/suites/rgw/multisite/overrides.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ overrides:
2020
rgw sync obj etag verify: true
2121
rgw sync meta inject err probability: 0
2222
rgw sync data inject err probability: 0
23+
rgw s3 auth use sts: true
24+
rgw sts key: abcdefghijklmnoq
2325
rgw:
2426
compression type: random

src/test/rgw/rgw_multi/conn.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import boto
22
import boto.s3.connection
33
import boto.iam.connection
4+
import boto.sts.connection
45
import boto3
6+
from boto.regioninfo import RegionInfo
57

68
def get_gateway_connection(gateway, credentials):
79
""" connect to the given gateway """
@@ -45,6 +47,20 @@ def get_gateway_iam_connection(gateway, credentials, region):
4547
use_ssl = False)
4648
return gateway.iam_connection
4749

50+
def get_gateway_sts_connection(gateway, credentials, region):
51+
""" connect to sts api of the given gateway """
52+
if gateway.sts_connection is None:
53+
endpoint = f'http://{gateway.host}:{gateway.port}'
54+
print(endpoint)
55+
gateway.sts_connection = boto3.client(
56+
service_name = 'sts',
57+
aws_access_key_id = credentials.access_key,
58+
aws_secret_access_key = credentials.secret,
59+
endpoint_url = endpoint,
60+
region_name=region,
61+
use_ssl = False)
62+
return gateway.sts_connection
63+
4864

4965
def get_gateway_s3_client(gateway, credentials, region):
5066
""" connect to boto3 s3 client api of the given gateway """
@@ -68,3 +84,13 @@ def get_gateway_sns_client(gateway, credentials, region):
6884
aws_secret_access_key=credentials.secret,
6985
region_name=region)
7086
return gateway.sns_client
87+
88+
def get_gateway_temp_s3_client(gateway, credentials, session_token, region):
89+
""" connect to boto3 s3 client api using temporary credntials """
90+
gateway.temp_s3_client = boto3.client('s3',
91+
endpoint_url='http://' + gateway.host + ':' + str(gateway.port),
92+
aws_access_key_id=credentials.access_key,
93+
aws_secret_access_key=credentials.secret,
94+
aws_session_token = session_token,
95+
region_name=region)
96+
return gateway.temp_s3_client

src/test/rgw/rgw_multi/multisite.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import json
55

6-
from .conn import get_gateway_connection, get_gateway_iam_connection, get_gateway_secure_connection, get_gateway_s3_client, get_gateway_sns_client
6+
from .conn import get_gateway_connection, get_gateway_iam_connection, get_gateway_secure_connection, get_gateway_s3_client, get_gateway_sns_client, get_gateway_sts_connection, get_gateway_temp_s3_client
77

88
class Cluster:
99
""" interface to run commands against a distinct ceph cluster """
@@ -29,6 +29,7 @@ def __init__(self, host = None, port = None, cluster = None, zone = None, ssl_po
2929
self.iam_connection = None
3030
self.s3_client = None
3131
self.sns_client = None
32+
self.sts_connection = None
3233

3334
@abstractmethod
3435
def start(self, args = []):
@@ -195,7 +196,7 @@ def __init__(self, zone, credentials):
195196
self.iam_conn = get_gateway_iam_connection(self.zone.gateways[0], self.credentials, region)
196197
self.s3_client = get_gateway_s3_client(self.zone.gateways[0], self.credentials, region)
197198
self.sns_client = get_gateway_sns_client(self.zone.gateways[0], self.credentials, region)
198-
199+
self.temp_s3_client = None
199200
# create connections for the rest of the gateways (if exist)
200201
for gw in list(self.zone.gateways):
201202
get_gateway_connection(gw, self.credentials)
@@ -209,6 +210,11 @@ def get_connection(self):
209210
def get_iam_connection(self):
210211
return self.iam_conn
211212

213+
def get_temp_s3_connection(self, credentials, session_token):
214+
region = "" if self.zone.zonegroup is None else self.zone.zonegroup.name
215+
self.temp_s3_client = get_gateway_temp_s3_client(self.zone.gateways[0], credentials, session_token, region)
216+
return self.temp_s3_client
217+
212218
def get_bucket(self, bucket_name, credentials):
213219
raise NotImplementedError
214220

src/test/rgw/rgw_multi/tests.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,6 +2258,40 @@ def test_object_acl():
22582258
after_set_acl = bucket2.get_acl(k)
22592259
assert(len(after_set_acl.acl.grants) == 2) # read grant added on AllUsers
22602260

2261+
def test_assume_role_after_sync():
2262+
zonegroup = realm.master_zonegroup()
2263+
zonegroup_conns = ZonegroupConns(zonegroup)
2264+
access_key = 'abcd'
2265+
secret_key = 'efgh'
2266+
tenant = 'testx'
2267+
uid = 'test'
2268+
cmd = ['user', 'create', '--tenant', tenant, '--uid', uid, '--access-key', access_key, '--secret-key', secret_key, '--display-name', 'tenanted-user']
2269+
zonegroup_conns.master_zone.zone.cluster.admin(cmd)
2270+
credentials = Credentials(access_key, secret_key)
2271+
2272+
role_name = gen_role_name()
2273+
log.info('create role zone=%s name=%s', zonegroup_conns.master_zone.name, role_name)
2274+
policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam::testx:user/test\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
2275+
role = zonegroup_conns.master_zone.create_role("/", role_name, policy_document, "")
2276+
policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Resource\":\"*\",\"Action\":\"s3:*\"}]}"
2277+
zonegroup_conns.master_zone.put_role_policy(role_name, "Policy1", policy_document)
2278+
2279+
zonegroup_meta_checkpoint(zonegroup)
2280+
2281+
for zone in zonegroup_conns.zones:
2282+
log.info(f'checking if zone: {zone.name} has role: {role_name}')
2283+
assert(zone.has_role(role_name))
2284+
log.info(f'success, zone: {zone.name} has role: {role_name}')
2285+
2286+
for zone in zonegroup_conns.zones:
2287+
if zone == zonegroup_conns.master_zone:
2288+
log.info(f'creating bucket in primary zone')
2289+
bucket = "bucket1"
2290+
zone.assume_role_create_bucket(bucket, role['Role']['Arn'], "primary", credentials)
2291+
if zone != zonegroup_conns.master_zone:
2292+
log.info(f'creating bucket in secondary zone')
2293+
bucket = "bucket2"
2294+
zone.assume_role_create_bucket(bucket, role['Role']['Arn'], "secondary", credentials)
22612295

22622296
@attr('fails_with_rgw')
22632297
@attr('data_sync_init')

src/test/rgw/rgw_multi/zone_cloud.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ def delete_role(self, role_name):
310310
def has_role(self, role_name):
311311
assert False
312312

313+
def put_role_policy(self, rolename, policyname, policy_document):
314+
assert False
315+
313316
def create_topic(self, topicname, attributes):
314317
assert False
315318

@@ -331,6 +334,9 @@ def delete_notifications(self, bucket_name):
331334
def list_notifications(self, bucket_name):
332335
assert False
333336

337+
def assume_role(self, role_arn, session_name, policy, duration_seconds):
338+
assert False
339+
334340
def get_conn(self, credentials):
335341
return self.Conn(self, credentials)
336342

src/test/rgw/rgw_multi/zone_es.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ def delete_role(self, role_name):
252252
def has_role(self, role_name):
253253
assert False
254254

255+
def put_role_policy(self, rolename, policyname, policy_document):
256+
assert False
257+
255258
def create_topic(self, topicname, attributes):
256259
assert False
257260

@@ -273,6 +276,9 @@ def delete_notification(self, bucket_name):
273276
def list_notifications(self, bucket_name):
274277
assert False
275278

279+
def assume_role(self, role_arn, session_name, policy, duration_seconds):
280+
assert False
281+
276282
def get_conn(self, credentials):
277283
return self.Conn(self, credentials)
278284

src/test/rgw/rgw_multi/zone_rados.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
from .multisite import *
1010

11+
from .conn import get_gateway_sts_connection
12+
1113
log = logging.getLogger(__name__)
1214

1315
def check_object_eq(k1, k2, check_extra = True):
@@ -106,7 +108,7 @@ def check_bucket_eq(self, zone_conn, bucket_name):
106108
return True
107109

108110
def get_role(self, role_name):
109-
return self.iam_conn.get_role(role_name)
111+
return self.iam_conn.get_role(RoleName=role_name)
110112

111113
def check_role_eq(self, zone_conn, role_name):
112114
log.info('comparing role=%s zones={%s, %s}', role_name, self.name, zone_conn.name)
@@ -130,10 +132,10 @@ def check_role_eq(self, zone_conn, role_name):
130132
def create_role(self, path, rolename, policy_document, tag_list):
131133
if policy_document is None:
132134
policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam:::user/testuser\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
133-
return self.iam_conn.create_role(rolename, policy_document, path)
135+
return self.iam_conn.create_role(RoleName=rolename, AssumeRolePolicyDocument=policy_document, Path=path)
134136

135137
def delete_role(self, role_name):
136-
return self.iam_conn.delete_role(role_name)
138+
return self.iam_conn.delete_role(RoleName=role_name)
137139

138140
def has_role(self, role_name):
139141
try:
@@ -142,6 +144,11 @@ def has_role(self, role_name):
142144
return False
143145
return True
144146

147+
def put_role_policy(self, rolename, policyname, policy_document):
148+
if policy_document is None:
149+
policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Resource\":\"*\",\"Action\":\"s3:*\"}]}"
150+
return self.iam_conn.put_role_policy(RoleName=rolename, PolicyName=policyname, PolicyDocument=policy_document)
151+
145152
def create_topic(self, topicname, attributes):
146153
result = self.sns_client.create_topic(Name=topicname, Attributes=attributes)
147154
self.topic_arn = result['TopicArn']
@@ -173,6 +180,17 @@ def list_notifications(self, bucket_name):
173180
def head_object(self, bucket_name, obj_name):
174181
return self.s3_client.head_object(Bucket=bucket_name, Key=obj_name)
175182

183+
def assume_role_create_bucket(self, bucket, role_arn, session_name, alt_user_creds):
184+
region = "" if self.zone.zonegroup is None else self.zone.zonegroup.name
185+
sts_conn = None
186+
if self.zone.gateways is not None:
187+
sts_conn = get_gateway_sts_connection(self.zone.gateways[0], alt_user_creds, region)
188+
assumed_role_object = sts_conn.assume_role(RoleArn=role_arn, RoleSessionName=session_name)
189+
assumed_role_credentials = assumed_role_object['Credentials']
190+
credentials = Credentials(assumed_role_credentials['AccessKeyId'], assumed_role_credentials['SecretAccessKey'])
191+
self.get_temp_s3_connection(credentials, assumed_role_credentials['SessionToken'])
192+
self.temp_s3_client.create_bucket(Bucket=bucket)
193+
176194
def get_conn(self, credentials):
177195
return self.Conn(self, credentials)
178196

0 commit comments

Comments
 (0)