diff --git a/orm/common/orm_common/policy/policy.py b/orm/common/orm_common/policy/policy.py index c06ce11c..dddb6ee2 100755 --- a/orm/common/orm_common/policy/policy.py +++ b/orm/common/orm_common/policy/policy.py @@ -134,7 +134,6 @@ def authorize(action, request, app_conf, keystone_ep=None): keystone_ep = keystone_ep if keystone_ep else ( request.headers.get('Keystone-Endpoint')) - try: if _is_authorization_enabled(app_conf): try: @@ -145,6 +144,7 @@ def authorize(action, request, app_conf, keystone_ep=None): request.headers['X-RANGER-Client'] = user.user['name'] request.headers['X-RANGER-Owner'] = user.tenant['id'] request.headers['Keystone-Endpoint'] = user.auth_url + request.headers['User-Domain'] = user.domain keystone_ep = user.auth_url except Exception as ex: user = None diff --git a/orm/services/customer_manager/cms_rest/rds_proxy.py b/orm/services/customer_manager/cms_rest/rds_proxy.py index c43c6b63..eb0b1d24 100755 --- a/orm/services/customer_manager/cms_rest/rds_proxy.py +++ b/orm/services/customer_manager/cms_rest/rds_proxy.py @@ -89,6 +89,9 @@ class RdsProxy(object): headers['X-Auth-Token'] = request.headers[ 'X-Auth-Token'] if 'X-Auth-Token' in \ request.headers else '' + headers['User-Domain'] = request.headers[ + 'User-Domain'] if 'User-Domain' in \ + request.headers else '' LOG.debug("Wrapper JSON before sending action: {0} to Rds " "Proxy\n{1}".format(method, pretty_text)) diff --git a/orm/services/resource_distributor/rds/controllers/v1/resources/root.py b/orm/services/resource_distributor/rds/controllers/v1/resources/root.py index c5b9762f..cbddbfd8 100755 --- a/orm/services/resource_distributor/rds/controllers/v1/resources/root.py +++ b/orm/services/resource_distributor/rds/controllers/v1/resources/root.py @@ -170,7 +170,7 @@ class CreateNewResource(rest.RestController): """Handle HTTP POST request. :param Customer (json in request body): - :return: result (json format ... {'Cusetomer':{'id':'', + :return: result (json format ... {'Customer':{'id':'', 'links':{'own':'how host url'},'created':'1234567890'}} the response will be 201 created if success :return 409 for conflict @@ -179,17 +179,20 @@ class CreateNewResource(rest.RestController): """ my_logger.info("create resource") jsondata = resource.service_template.model - my_logger.debug("parse json & get yaml file!!! {}".format(jsondata)) + my_logger.debug("parse json & retrieve yaml file {}".format(jsondata)) uuid = resource.service_template.tracking.tracking_id resource_type = resource.service_template.resource.resource_type base_url = pecan.request.application_url + user_domain = None + if resource_type == 'customer': + user_domain = pecan.request.headers['User-Domain'] jsondata = ast.literal_eval(jsondata) - try: resource_id = ResourceService.main(jsondata, uuid, resource_type, - 'create') + 'create', + user_domain) site_link = "%s/v1/rds/%s/%s" % (base_url, resource_type, resource_id) @@ -208,7 +211,7 @@ class CreateNewResource(rest.RestController): @wsexpose(Result, body=Resource, status_code=201, rest_content_types='json') def put(self, resource): - """Handle HTTP POST request. + """Handle HTTP PUT request. :param Customer (json in request body): :return: result (json format ... {'Cusetomer':{'id':'', @@ -225,13 +228,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 + if resource_type == 'customer': + user_domain = pecan.request.headers['User-Domain'] try: resource_id = ResourceService.main(jsondata, uuid, resource_type, - 'modify') - my_logger.debug("data sent!.") + 'modify', + user_domain) + my_logger.debug("data sent") site_link = "%s/v1/rds/%s/%s" % (base_url, resource_type, resource_id) @@ -266,6 +273,9 @@ 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 + if resource_type == 'customer': + user_domain = pecan.request.headers['User-Domain'] if resource_type not in resources_operation_list or operation not in \ resources_operation_list[resource_type]: raise NotAllowedError("delete Not allowed for this" @@ -274,7 +284,8 @@ class CreateNewResource(rest.RestController): resource_id = ResourceService.main(jsondata, resource_uuid, resource_type, - operation) + operation, + user_domain) return resource_id except ConflictValue as e: my_logger.error("the request blocked need to wait" diff --git a/orm/services/resource_distributor/rds/services/resource.py b/orm/services/resource_distributor/rds/services/resource.py index dd6f6e2a..8a540a5b 100755 --- a/orm/services/resource_distributor/rds/services/resource.py +++ b/orm/services/resource_distributor/rds/services/resource.py @@ -126,7 +126,8 @@ def _create_template_data(input_data): if target['action'] == "delete": yamldata = "delete" elif input_data.resource_type == "customer": - yamldata = yaml_customer_builder.yamlbuilder(jsondata, target) + yamldata = yaml_customer_builder.yamlbuilder(jsondata, target, + input_data.user_domain) elif input_data.resource_type == "group": yamldata = yaml_group_builder.yamlbuilder(jsondata, target) elif input_data.resource_type == "flavor": @@ -256,11 +257,14 @@ def _generate_resource_data(input_data): input_data.resource_id)) targetslist = _create_template_data(input_data) my_logger.debug("submit yaml to ranger-agent...") - _submit_template_data(input_data.resource_id, input_data.transaction_id, + _submit_template_data(input_data.resource_id, + input_data.transaction_id, targetslist) -def main(jsondata, external_transaction_id, resource_type, operation): +# 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): """main function handle resource operation.""" my_logger.info("got %s for %s resource" % (operation, resource_type)) try: @@ -273,6 +277,7 @@ def main(jsondata, external_transaction_id, resource_type, operation): 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.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) diff --git a/orm/services/resource_distributor/rds/services/yaml_customer_builder.py b/orm/services/resource_distributor/rds/services/yaml_customer_builder.py index 3a19a4f1..dbb93eae 100755 --- a/orm/services/resource_distributor/rds/services/yaml_customer_builder.py +++ b/orm/services/resource_distributor/rds/services/yaml_customer_builder.py @@ -2,6 +2,7 @@ import logging from orm.services.resource_distributor.rds.services.helpers import create_final_yaml + from pecan import conf logger = logging.getLogger(__name__) @@ -25,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): +def yamlbuilder(alldata, region, user_domain): logger.info("building customer yaml") logger.debug("start building flavor yaml for region %s" % region['name']) """build cstomer yaml. @@ -79,7 +80,6 @@ def yamlbuilder(alldata, region): # create the output for roles # outputs['outputs']["%s_id" % role] =\ # {"value": {"get_resource": "%s" % role}} - # no support for group when type is ldap if yaml_type != 'ldap': # create one group for user @@ -107,7 +107,7 @@ def yamlbuilder(alldata, region): else: resources['resources'][user['id']] = \ {'type': 'OS::Keystone::UserRoleAssignment\n', - 'properties': {'user': (user['id'] + "{%s}" % domain), + 'properties': {'user': (user['id'] + "{%s}" % user_domain), 'roles': user_roles}} # create the output for users diff --git a/orm/tests/unit/rds/controllers/v1/resources/test_create_resource.py b/orm/tests/unit/rds/controllers/v1/resources/test_create_resource.py index 08f94c4b..64f580b1 100755 --- a/orm/tests/unit/rds/controllers/v1/resources/test_create_resource.py +++ b/orm/tests/unit/rds/controllers/v1/resources/test_create_resource.py @@ -10,7 +10,8 @@ class TestCreateResource(FunctionalTest): @patch.object(root.ResourceService, 'main', return_value="12345") def test_create_resource_success(self, input): """test create resource as it succeed.""" - response = self.app.post_json('/v1/rds/resources', good_data) + headers = {'User-Domain': 'default'} + response = self.app.post_json('/v1/rds/resources', good_data, headers=headers) assert response.json['customer']['id'] == '12345' assert response.status_int == 201 @@ -32,22 +33,26 @@ class TestCreateResource(FunctionalTest): side_effect=Exception("general exception")) def test_create_resource_gen_except(self, input): """test creatte resource to catch general exception.""" - response = self.app.post_json('/v1/rds/resources', - good_data, expect_errors=True) + headers = {'User-Domain': 'default'} + response = self.app.post_json('/v1/rds/resources', good_data, + headers=headers, expect_errors=True) assert response.status_int == 400 @patch.object(root.ResourceService, 'main', side_effect=root.ConflictValue("region")) def test_create_resource_conflict_except(self, input): """test creatte resource to catch ConflictValue exception.""" - response = self.app.post_json('/v1/rds/resources', - good_data, expect_errors=True) + headers = {'User-Domain': 'default'} + response = self.app.post_json('/v1/rds/resources', good_data, + headers=headers, expect_errors=True) assert response.status_int == 409 @patch.object(root.ResourceService, 'main', return_value="12345") def test_delete_resource_flavor(self, input): """test delete flavor.""" - response = self.app.delete_json('/v1/rds/resources', flavor_data) + headers = {'User-Domain': 'default'} + response = self.app.delete_json('/v1/rds/resources', flavor_data, + headers=headers) assert response.status_int == 200 @patch.object(root.ResourceService, 'main', return_value="12345") @@ -55,8 +60,9 @@ class TestCreateResource(FunctionalTest): """test delete resource not flavor.""" flavor_data["service_template"]["resource"]['resource_type'] = \ "customer" + headers = {'User-Domain': 'default'} response = self.app.delete_json('/v1/rds/resources', flavor_data, - expect_errors=True) + headers=headers, expect_errors=True) assert response.status_int == 405 flavor_data["service_template"]["resource"]['resource_type'] = "flavor" @@ -64,8 +70,10 @@ 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'} try: - response = self.app.delete_json('/v1/rds/resources', flavor_data) + response = self.app.delete_json('/v1/rds/resources', flavor_data, + headers=headers) except Exception as e: if '409 Conflict' not in str(e): self.fail('error') @@ -74,8 +82,10 @@ 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'} try: - response = self.app.delete_json('/v1/rds/resources', flavor_data) + response = self.app.delete_json('/v1/rds/resources', + flavor_data, headers=headers) except Exception as e: if 'unknown error' not in str(e): self.fail('error') @@ -84,7 +94,9 @@ class TestCreateResource(FunctionalTest): def test_update_resource_success(self, input): updated = False """test update resource as it succeed.""" - response = self.app.put_json('/v1/rds/resources', good_data) + headers = {'User-Domain': 'default'} + response = self.app.put_json('/v1/rds/resources', good_data, + headers=headers) if 'updated' in response.json['customer']: updated = True assert response.json['customer']['id'] == '12345' @@ -95,8 +107,10 @@ 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'} try: - response = self.app.put_json('/v1/rds/resources', good_data) + response = self.app.put_json('/v1/rds/resources', good_data, + headers=headers) except Exception as e: if 'unknown error' not in str(e): self.fail('error') @@ -105,8 +119,9 @@ class TestCreateResource(FunctionalTest): side_effect=root.ConflictValue("region")) def test_modify_resource_conflict_except(self, input): """test modify resource to catch ConflictValue exception.""" - response = self.app.put_json('/v1/rds/resources', - good_data, expect_errors=True) + headers = {'User-Domain': 'default'} + response = self.app.put_json('/v1/rds/resources', good_data, + headers=headers, expect_errors=True) assert response.status_int == 409 good_data = { diff --git a/orm/tests/unit/rds/services/test_create_resource.py b/orm/tests/unit/rds/services/test_create_resource.py index 26cb1cd3..f34246da 100755 --- a/orm/tests/unit/rds/services/test_create_resource.py +++ b/orm/tests/unit/rds/services/test_create_resource.py @@ -83,6 +83,7 @@ class CreateResource(unittest.TestCase): operation='create', targets=targets ) + input_data.user_domain = 'default' status_model = StatusModel(status=[result]) status_model.regions = None result.return_value = status_model diff --git a/orm/tests/unit/rds/services/test_customer_yaml.py b/orm/tests/unit/rds/services/test_customer_yaml.py index 2dd2c7d1..b00061c0 100755 --- a/orm/tests/unit/rds/services/test_customer_yaml.py +++ b/orm/tests/unit/rds/services/test_customer_yaml.py @@ -287,7 +287,7 @@ 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) + yamlfile = CustomerBuild.yamlbuilder(alldata, region_quotas, user_domain='default') 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 +298,7 @@ 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) + yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_domain='default') 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 +309,7 @@ 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) + yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_domain='default') 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 +320,7 @@ 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) + yamlfile = CustomerBuild.yamlbuilder(alldata, region_quotas, user_domain='default') 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 +334,7 @@ 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) + yamlfile = CustomerBuild.yamlbuilder(alldata, region_users, user_domain='default') yamlfile_as_json = yaml.safe_load(yamlfile) self.assertEqual(yamlfile_as_json['heat_template_version'], ver) @@ -345,7 +345,7 @@ 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) + yamlfile = CustomerBuild.yamlbuilder(alldata, region_users_v4, user_domain='default') 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)) diff --git a/requirements.txt b/requirements.txt index 21624085..7878c26b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,3 +16,4 @@ keystonemiddleware>=4.17.0 # Apache-2.0 python-keystoneclient>=3.8.0 # Apache-2.0 mysqlclient>=1.4.0 psutil>=3.2.2 # BSD +setuptools>=40.0.0