From 96db1d7ee018a847bb9c5360036d3e8081db159f Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Fri, 18 Oct 2019 12:18:53 -0400 Subject: [PATCH] Distributed Cloud enhancements for Horizon - Adding endpoints for the subcloud's platform services to the central keystone. This was done so horizon can reach all subclouds - Allowing version requests to bypass the authtoken validator in the dcorch proxy. version requests do not require authentication and they are required by horizon to work in the SystemController region Change-Id: I508e0168e77d1f46b8f5720fd16047177b4920c2 Partial-Bug: 1846239 Signed-off-by: Tyler Smith --- dcmanager/manager/subcloud_manager.py | 59 +++++++++++-------- .../unit/manager/test_subcloud_manager.py | 6 +- dcorch/api/proxy/apps/acceptor.py | 13 +++- dcorch/api/proxy/apps/controller.py | 21 ++++++- dcorch/api/proxy/common/constants.py | 4 +- dcorch/common/consts.py | 4 +- 6 files changed, 78 insertions(+), 29 deletions(-) diff --git a/dcmanager/manager/subcloud_manager.py b/dcmanager/manager/subcloud_manager.py index 29f27309b..9be557e41 100644 --- a/dcmanager/manager/subcloud_manager.py +++ b/dcmanager/manager/subcloud_manager.py @@ -152,39 +152,50 @@ class SubcloudManager(manager.Manager): payload['systemcontroller_gateway_address'], 1) - # Create identity endpoints to this subcloud on the + # Create endpoints to this subcloud on the # management-start-ip of the subcloud which will be allocated # as the floating Management IP of the Subcloud if the - # Address Pool is not shared. Incase the endpoint entry - # is incorrect, or the management IP of the subcloud is changed + # Address Pool is not shared. Incase the endpoint entries + # are incorrect, or the management IP of the subcloud is changed # in the future, it will not go managed or will show up as # out of sync. To fix this use Openstack endpoint commands - # on the SystemController to change the subcloud endpoint - ks_service_id = None + # on the SystemController to change the subcloud endpoints. + # The non-identity endpoints are added to facilitate horizon access + # from the System Controller to the subcloud. + endpoint_config = [] + endpoint_ip = payload['management_start_address'] + if netaddr.IPAddress(endpoint_ip).version == 6: + endpoint_ip = '[' + endpoint_ip + ']' + for service in m_ks_client.services_list: + if service.type == dcorch_consts.ENDPOINT_TYPE_PLATFORM: + endpoint_url = "http://{}:6385/v1".format(endpoint_ip) + endpoint_config.append((service.id, endpoint_url)) if service.type == dcorch_consts.ENDPOINT_TYPE_IDENTITY: - ks_service_id = service.id - break - else: + endpoint_url = "http://{}:5000/v3".format(endpoint_ip) + endpoint_config.append((service.id, endpoint_url)) + if service.type == dcorch_consts.ENDPOINT_TYPE_PATCHING: + endpoint_url = "http://{}:5491".format(endpoint_ip) + endpoint_config.append((service.id, endpoint_url)) + if service.type == dcorch_consts.ENDPOINT_TYPE_FM: + endpoint_url = "http://{}:18002".format(endpoint_ip) + endpoint_config.append((service.id, endpoint_url)) + if service.type == dcorch_consts.ENDPOINT_TYPE_NFV: + endpoint_url = "http://{}:4545".format(endpoint_ip) + endpoint_config.append((service.id, endpoint_url)) + + if len(endpoint_config) < 5: raise exceptions.BadRequest( resource='subcloud', - msg='No Identity service found on SystemController') + msg='Missing service in SystemController') - identity_endpoint_ip = payload['management_start_address'] - - if netaddr.IPAddress(identity_endpoint_ip).version == 6: - identity_endpoint_url = \ - "http://[{}]:5000/v3".format(identity_endpoint_ip) - else: - identity_endpoint_url = \ - "http://{}:5000/v3".format(identity_endpoint_ip) - - for iface in ['internal', 'admin']: - m_ks_client.keystone_client.endpoints.create( - ks_service_id, - identity_endpoint_url, - interface=iface, - region=subcloud.name) + for endpoint in endpoint_config: + for iface in ['internal', 'admin']: + m_ks_client.keystone_client.endpoints.create( + endpoint[0], + endpoint[1], + interface=iface, + region=subcloud.name) # Inform orchestrator that subcloud has been added self.dcorch_rpc_client.add_subcloud( diff --git a/dcmanager/tests/unit/manager/test_subcloud_manager.py b/dcmanager/tests/unit/manager/test_subcloud_manager.py index cb91af06f..f6c4e1c1c 100644 --- a/dcmanager/tests/unit/manager/test_subcloud_manager.py +++ b/dcmanager/tests/unit/manager/test_subcloud_manager.py @@ -130,7 +130,11 @@ class TestSubcloudManager(base.DCManagerTestCase): mock_dcorch_rpc_client): value = utils.create_subcloud_dict(value) controllers = [Controller('controller-0'), Controller('controller-1')] - services = [Service('identity', '1234')] + services = [Service('identity', '1234'), + Service('faultmanagement', '1234'), + Service('patching', '1234'), + Service('platform', '1234'), + Service('nfv', '1234')] mock_context.get_admin_context.return_value = self.ctxt mock_db_api.subcloud_get_by_name.side_effect = \ exceptions.SubcloudNameNotFound() diff --git a/dcorch/api/proxy/apps/acceptor.py b/dcorch/api/proxy/apps/acceptor.py index b9dbcf061..df485b2b3 100644 --- a/dcorch/api/proxy/apps/acceptor.py +++ b/dcorch/api/proxy/apps/acceptor.py @@ -1,4 +1,4 @@ -# Copyright 2017 Wind River +# Copyright 2017-2019 Wind River # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ from dcorch.api.proxy.apps.controller import IdentityAPIController from dcorch.api.proxy.apps.controller import NeutronAPIController from dcorch.api.proxy.apps.controller import OrchAPIController from dcorch.api.proxy.apps.controller import SysinvAPIController +from dcorch.api.proxy.apps.controller import VersionController from dcorch.api.proxy.apps.dispatcher import APIDispatcher from dcorch.api.proxy.apps.patch import PatchAPIController from dcorch.api.proxy.apps.router import Router @@ -121,3 +122,13 @@ class Acceptor(Router): for key, value in proxy_consts.IDENTITY_PATH_MAP.items(): self._add_resource(mapper, api_controller, value, key, CONF.type) + + +class VersionAcceptor(Router): + def __init__(self, app, conf): + self._conf = conf + mapper = routes.Mapper() + api_controller = VersionController(app, conf) + mapper.connect(proxy_consts.VERSION_ROOT, controller=api_controller, + conditions=dict(method=['GET'])) + super(VersionAcceptor, self).__init__(app, conf, mapper, None) diff --git a/dcorch/api/proxy/apps/controller.py b/dcorch/api/proxy/apps/controller.py index aa0f1f2ca..83501660c 100644 --- a/dcorch/api/proxy/apps/controller.py +++ b/dcorch/api/proxy/apps/controller.py @@ -1,4 +1,4 @@ -# Copyright 2017 Wind River +# Copyright 2017-2019 Wind River # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,8 +18,10 @@ import webob.dec import webob.exc from dcorch.api.proxy.apps.dispatcher import APIDispatcher +from dcorch.api.proxy.apps.proxy import Proxy from dcorch.api.proxy.common import constants as proxy_consts from dcorch.api.proxy.common.service import Middleware +from dcorch.api.proxy.common.service import Request as ProxyRequest from dcorch.api.proxy.common import utils as proxy_utils from dcorch.common import consts import dcorch.common.context as k_context @@ -689,3 +691,20 @@ class OrchAPIController(APIController): if self.get_status_code(response) in self.OK_STATUS_CODE: response = self._update_response(environ, request_body, response) return response + + +class VersionController(Middleware): + def __init__(self, app, conf): + self._default_dispatcher = Proxy() + self._remote_host, self._remote_port = \ + proxy_utils.get_remote_host_port_options(CONF) + super(VersionController, self).__init__(app) + + @webob.dec.wsgify(RequestClass=ProxyRequest) + def __call__(self, req): + LOG.debug("VersionController forward the version request to remote " + "host: (%s), port: (%d)" % (self._remote_host, + self._remote_port)) + proxy_utils.set_request_forward_environ(req, self._remote_host, + self._remote_port) + return self._default_dispatcher diff --git a/dcorch/api/proxy/common/constants.py b/dcorch/api/proxy/common/constants.py index 1db9da8bb..d5074fad2 100755 --- a/dcorch/api/proxy/common/constants.py +++ b/dcorch/api/proxy/common/constants.py @@ -1,4 +1,4 @@ -# Copyright 2017 Wind River +# Copyright 2017-2019 Wind River # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ from dcorch.common import consts +VERSION_ROOT = '/{version:.*?}' + # Compute FLAVOR_RESOURCE_TAG = 'flavors' FLAVOR_ACCESS_RESOURCE_TAG = 'action' diff --git a/dcorch/common/consts.py b/dcorch/common/consts.py index cf749312e..61f5c4edd 100644 --- a/dcorch/common/consts.py +++ b/dcorch/common/consts.py @@ -12,7 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. # -# Copyright (c) 2017-2018 Wind River Systems, Inc. +# Copyright (c) 2017-2019 Wind River Systems, Inc. # # The right to copy, distribute, modify, or otherwise make use # of this software may be licensed only pursuant to the terms @@ -135,6 +135,8 @@ ENDPOINT_TYPE_COMPUTE = "compute" ENDPOINT_TYPE_NETWORK = "network" ENDPOINT_TYPE_PATCHING = "patching" ENDPOINT_TYPE_IDENTITY = "identity" +ENDPOINT_TYPE_FM = "faultmanagement" +ENDPOINT_TYPE_NFV = "nfv" ENDPOINT_TYPES_LIST = [ENDPOINT_TYPE_PLATFORM, ENDPOINT_TYPE_PATCHING,