Update CMS for cross domain role assignment

When a user with a domain different than
the domain of the user authorizing heat
to create the resources that ranger defines
is added to a customer template, heat returns
stack validation as the user cannot be found
in the domain of the authorizing user.
Updated to check if use match auth user and
if not, use ranger conf domain as previous

Change-Id: I1406b61c695a5d9a3d94e732b95c2b683c94852b
This commit is contained in:
jh629g 2020-08-19 09:41:33 -05:00 committed by Jeremy Houser
parent c72a3759b6
commit 94170b688e
6 changed files with 49 additions and 34 deletions

View File

@ -183,16 +183,17 @@ class CreateNewResource(rest.RestController):
uuid = resource.service_template.tracking.tracking_id
resource_type = resource.service_template.resource.resource_type
base_url = pecan.request.application_url
user_domain = None
user_data = {}
if resource_type == 'customer':
user_domain = pecan.request.headers['User-Domain']
user_data['user_domain'] = pecan.request.headers['User-Domain']
user_data['user_id'] = pecan.request.headers['X-RANGER-Client']
jsondata = ast.literal_eval(jsondata)
try:
resource_id = ResourceService.main(jsondata,
uuid,
resource_type,
'create',
user_domain)
user_data)
site_link = "%s/v1/rds/%s/%s" % (base_url,
resource_type,
resource_id)
@ -228,16 +229,17 @@ class CreateNewResource(rest.RestController):
resource_type = resource.service_template.resource.resource_type
base_url = pecan.request.application_url
jsondata = ast.literal_eval(jsondata)
user_domain = None
user_data = {}
if resource_type == 'customer':
user_domain = pecan.request.headers['User-Domain']
user_data['user_domain'] = pecan.request.headers['User-Domain']
user_data['user_id'] = pecan.request.headers['X-RANGER-Client']
try:
resource_id = ResourceService.main(jsondata,
uuid,
resource_type,
'modify',
user_domain)
user_data)
my_logger.debug("data sent")
site_link = "%s/v1/rds/%s/%s" % (base_url,
resource_type,
@ -273,9 +275,10 @@ class CreateNewResource(rest.RestController):
jsondata = ast.literal_eval(jsondata)
resource_uuid = resource.service_template.tracking.tracking_id
resource_type = resource.service_template.resource.resource_type
user_domain = None
user_data = {}
if resource_type == 'customer':
user_domain = pecan.request.headers['User-Domain']
user_data['user_domain'] = pecan.request.headers['User-Domain']
user_data['user_id'] = pecan.request.headers['X-RANGER-Client']
if resource_type not in resources_operation_list or operation not in \
resources_operation_list[resource_type]:
raise NotAllowedError("delete Not allowed for this"
@ -285,7 +288,7 @@ class CreateNewResource(rest.RestController):
resource_uuid,
resource_type,
operation,
user_domain)
user_data)
return resource_id
except ConflictValue as e:
my_logger.error("the request blocked need to wait"

View File

@ -127,7 +127,7 @@ def _create_template_data(input_data):
yamldata = "delete"
elif input_data.resource_type == "customer":
yamldata = yaml_customer_builder.yamlbuilder(jsondata, target,
input_data.user_domain)
input_data.user_data)
elif input_data.resource_type == "group":
yamldata = yaml_group_builder.yamlbuilder(jsondata, target)
elif input_data.resource_type == "flavor":
@ -264,7 +264,7 @@ def _generate_resource_data(input_data):
# User domain is only used in the case that a customer template is being generated,
# as certain builds of heat require user_domain in order to validate roles
def main(jsondata, external_transaction_id, resource_type, operation, user_domain=None):
def main(jsondata, external_transaction_id, resource_type, operation, user_data=None):
"""main function handle resource operation."""
my_logger.info("got %s for %s resource" % (operation, resource_type))
try:
@ -277,7 +277,7 @@ def main(jsondata, external_transaction_id, resource_type, operation, user_domai
my_logger.debug("iterate through the regions see if none in submitted")
_check_resource_status(input_data)
my_logger.debug("get uuid from uuid generator")
input_data.user_domain = user_domain
input_data.user_data = user_data
input_data.transaction_id = uuid_utils.get_random_uuid()
my_logger.debug("uuid ={}".format(input_data.transaction_id))
# add regions status from rms (to check if it down)

View File

@ -26,7 +26,7 @@ def _metadata_to_tags(metadata):
str(k) + '=' + str(v) for i in metadata for k, v in i.items()) + ']'
def yamlbuilder(alldata, region, user_domain):
def yamlbuilder(alldata, region, user_data):
logger.info("building customer yaml")
logger.debug("start building flavor yaml for region %s" % region['name'])
"""build cstomer yaml.
@ -105,10 +105,16 @@ def yamlbuilder(alldata, region, user_domain):
'groups': user_group,
'roles': user_roles}}
else:
resources['resources'][user['id']] = \
{'type': 'OS::Keystone::UserRoleAssignment\n',
'properties': {'user': (user['id'] + "{%s}" % user_domain),
'roles': user_roles}}
if user['id'] == user_data['user_id']:
resources['resources'][user['id']] = \
{'type': 'OS::Keystone::UserRoleAssignment\n',
'properties': {'user': (user['id'] + "{%s}" % user_data['user_domain']),
'roles': user_roles}}
else:
resources['resources'][user['id']] = \
{'type': 'OS::Keystone::UserRoleAssignment\n',
'properties': {'user': (user['id'] + "{%s}" % domain),
'roles': user_roles}}
# create the output for users
outputs['outputs']["%s_id" % user['id']] = \

View File

@ -10,7 +10,7 @@ class TestCreateResource(FunctionalTest):
@patch.object(root.ResourceService, 'main', return_value="12345")
def test_create_resource_success(self, input):
"""test create resource as it succeed."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
response = self.app.post_json('/v1/rds/resources', good_data, headers=headers)
assert response.json['customer']['id'] == '12345'
assert response.status_int == 201
@ -33,7 +33,7 @@ class TestCreateResource(FunctionalTest):
side_effect=Exception("general exception"))
def test_create_resource_gen_except(self, input):
"""test creatte resource to catch general exception."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
response = self.app.post_json('/v1/rds/resources', good_data,
headers=headers, expect_errors=True)
assert response.status_int == 400
@ -42,7 +42,7 @@ class TestCreateResource(FunctionalTest):
side_effect=root.ConflictValue("region"))
def test_create_resource_conflict_except(self, input):
"""test creatte resource to catch ConflictValue exception."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
response = self.app.post_json('/v1/rds/resources', good_data,
headers=headers, expect_errors=True)
assert response.status_int == 409
@ -50,7 +50,7 @@ class TestCreateResource(FunctionalTest):
@patch.object(root.ResourceService, 'main', return_value="12345")
def test_delete_resource_flavor(self, input):
"""test delete flavor."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
response = self.app.delete_json('/v1/rds/resources', flavor_data,
headers=headers)
assert response.status_int == 200
@ -60,7 +60,7 @@ class TestCreateResource(FunctionalTest):
"""test delete resource not flavor."""
flavor_data["service_template"]["resource"]['resource_type'] = \
"customer"
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
response = self.app.delete_json('/v1/rds/resources', flavor_data,
headers=headers, expect_errors=True)
assert response.status_int == 405
@ -70,7 +70,7 @@ class TestCreateResource(FunctionalTest):
side_effect=root.ConflictValue("region"))
def test_delete_resource_flavor_con(self, input):
"""test delete flavor while previous process still in progress."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
try:
response = self.app.delete_json('/v1/rds/resources', flavor_data,
headers=headers)
@ -82,7 +82,7 @@ class TestCreateResource(FunctionalTest):
side_effect=Exception("unknown error"))
def test_delete_resource_flavor_exce(self, input):
"""test delete flavor with general; exception."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
try:
response = self.app.delete_json('/v1/rds/resources',
flavor_data, headers=headers)
@ -94,7 +94,7 @@ class TestCreateResource(FunctionalTest):
def test_update_resource_success(self, input):
updated = False
"""test update resource as it succeed."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
response = self.app.put_json('/v1/rds/resources', good_data,
headers=headers)
if 'updated' in response.json['customer']:
@ -107,7 +107,7 @@ class TestCreateResource(FunctionalTest):
side_effect=Exception("unknown error"))
def test_put_resource_gen_exce(self, input):
"""test customer put with general; exception."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
try:
response = self.app.put_json('/v1/rds/resources', good_data,
headers=headers)
@ -119,7 +119,7 @@ class TestCreateResource(FunctionalTest):
side_effect=root.ConflictValue("region"))
def test_modify_resource_conflict_except(self, input):
"""test modify resource to catch ConflictValue exception."""
headers = {'User-Domain': 'default'}
headers = {'User-Domain': 'default', 'X-Ranger-Client': 'user1'}
response = self.app.put_json('/v1/rds/resources', good_data,
headers=headers, expect_errors=True)
assert response.status_int == 409

View File

@ -83,7 +83,7 @@ class CreateResource(unittest.TestCase):
operation='create',
targets=targets
)
input_data.user_domain = 'default'
input_data.user_data = {'user_domain': 'default', 'user_id': 'user1'}
status_model = StatusModel(status=[result])
status_model.regions = None
result.return_value = status_model

View File

@ -287,7 +287,8 @@ class CreateResource(unittest.TestCase):
ver = mock_conf.yaml_configs.customer_yaml.yaml_version = '2015-1-1'
domain = mock_conf.yaml_configs.customer_yaml.customer_domain = 'default'
mock_conf.yaml_configs.customer_yaml.yaml_options.quotas = False
yamlfile = CustomerBuild.yamlbuilder(alldata, region_quotas, user_domain='default')
user_data = {'user_domain': 'default', 'user_id': 'user1'}
yamlfile = CustomerBuild.yamlbuilder(alldata, region_quotas, user_data)
yamlfile_as_json = yaml.safe_load(yamlfile)
self.assertEqual(yamlfile_as_json['heat_template_version'], ver)
self.assertEqual(yaml.safe_load(yamlfile), yaml.safe_load(fullyaml_no_users_quotasoff))
@ -298,7 +299,8 @@ class CreateResource(unittest.TestCase):
ver = mock_conf.yaml_configs.customer_yaml.yaml_version = '2015-1-2'
domain = mock_conf.yaml_configs.customer_yaml.customer_domain = 'default'
mock_conf.yaml_configs.customer_yaml.yaml_options.quotas = False
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_domain='default')
user_data = {'user_domain': 'default', 'user_id': 'user1'}
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_data)
yamlfile_as_json = yaml.safe_load(yamlfile)
self.assertEqual(yamlfile_as_json['heat_template_version'], ver)
self.assertEqual(yaml.safe_load(yamlfile), yaml.safe_load(fullyaml_with_users_quotasoff))
@ -309,7 +311,8 @@ class CreateResource(unittest.TestCase):
ver = mock_conf.yaml_configs.customer_yaml.yaml_version = '2015-1-1'
domain = mock_conf.yaml_configs.customer_yaml.customer_domain = 'default'
mock_conf.yaml_configs.customer_yaml.yaml_options.quotas = True
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_domain='default')
user_data = {'user_domain': 'default', 'user_id': 'user1'}
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_data)
yamlfile_as_json = yaml.safe_load(yamlfile)
self.assertEqual(yamlfile_as_json['heat_template_version'], ver)
self.assertEqual(yaml.safe_load(yamlfile), yaml.safe_load(full_yaml_default_quotas))
@ -320,7 +323,8 @@ class CreateResource(unittest.TestCase):
ver = mock_conf.yaml_configs.customer_yaml.yaml_version = '2015-1-1'
domain = mock_conf.yaml_configs.customer_yaml.customer_domain = 'default'
mock_conf.yaml_configs.customer_yaml.yaml_options.quotas = True
yamlfile = CustomerBuild.yamlbuilder(alldata, region_quotas, user_domain='default')
user_data = {'user_domain': 'default', 'user_id': 'user1'}
yamlfile = CustomerBuild.yamlbuilder(alldata, region_quotas, user_data)
yamlfile_as_json = yaml.safe_load(yamlfile)
self.assertEqual(yamlfile_as_json['heat_template_version'], ver)
self.assertEqual(yaml.safe_load(yamlfile), yaml.safe_load(full_yaml_quotas))
@ -334,7 +338,8 @@ class CreateResource(unittest.TestCase):
mock_conf.authentication.user_domain_name = 'default'
mock_conf.yaml_configs.customer_yaml.yaml_options.quotas = False
mock_conf.yaml_configs.customer_yaml.yaml_options.type = "ldap"
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_domain='default')
user_data = {'user_domain': 'default', 'user_id': 'user1'}
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_data)
yamlfile_as_json = yaml.safe_load(yamlfile)
self.assertEqual(yamlfile_as_json['heat_template_version'], ver)
@ -345,7 +350,8 @@ class CreateResource(unittest.TestCase):
ver = mock_conf.yaml_configs.customer_yaml.yaml_version = '2015-1-2'
domain = mock_conf.yaml_configs.customer_yaml.customer_domain = 'default'
mock_conf.yaml_configs.customer_yaml.yaml_options.quotas = True
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users_v4, user_domain='default')
user_data = {'user_domain': 'default', 'user_id': 'user1'}
yamlfile = CustomerBuild.yamlbuilder(alldata, region_users_v4, user_data)
yamlfile_as_json = yaml.safe_load(yamlfile)
self.assertEqual(yamlfile_as_json['heat_template_version'], ver)
self.assertEqual(yaml.safe_load(yamlfile), yaml.safe_load(fullyaml_aic4))