From 782729b6e98c1d2857c7e4f24bb69219e43c108f Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Fri, 12 Oct 2018 09:05:10 -0700 Subject: [PATCH] Fix audit target service selection The keystonemiddleware audit code would select the wrong OpenStack service endpoint for a request if the cloud is not using unique TCP ports for each service endpoint. As most services are no longer using a port per service, but instead using unique paths, this caused the audit to select the wrong target service. This leads to incorrect audit logging due to the wrong audit map being used. This patch checks the request to see if a TCP port was present in the request, and if not, fall back to using the target_endpoint_type configured in the audit map file. Change-Id: Ie2e0bf74ecca485d599a4041bb770bd6e296bc99 Closes-bug: 1797584 --- keystonemiddleware/audit/_api.py | 4 +- .../tests/unit/audit/test_audit_api.py | 38 +++++++++++++++++++ ...rvice-endpoint-ports-72b2009d631dcf19.yaml | 6 +++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml diff --git a/keystonemiddleware/audit/_api.py b/keystonemiddleware/audit/_api.py index e6921518..b84e140c 100644 --- a/keystonemiddleware/audit/_api.py +++ b/keystonemiddleware/audit/_api.py @@ -272,8 +272,8 @@ class OpenStackAuditApi(object): public_urlparse = urlparse.urlparse( endpoint_urls.get('publicURL', '')) req_url = urlparse.urlparse(req.host_url) - if (req_url.netloc == admin_urlparse.netloc - or req_url.netloc == public_urlparse.netloc): + if req_url.port and (req_url.netloc == admin_urlparse.netloc + or req_url.netloc == public_urlparse.netloc): service_info = self._get_service_info(endp) break elif (self._MAP.default_target_endpoint_type and diff --git a/keystonemiddleware/tests/unit/audit/test_audit_api.py b/keystonemiddleware/tests/unit/audit/test_audit_api.py index 1512e9dd..f63f3d51 100644 --- a/keystonemiddleware/tests/unit/audit/test_audit_api.py +++ b/keystonemiddleware/tests/unit/audit/test_audit_api.py @@ -320,6 +320,44 @@ class AuditApiLogicTest(base.BaseAuditMiddlewareTest): payload = self.get_payload('GET', url, environ=env_headers) self.assertEqual(payload['target']['name'], "unknown") + def test_endpoint_no_service_port(self): + with open(self.audit_map, "w") as f: + f.write("[DEFAULT]\n") + f.write("target_endpoint_type = load-balancer\n") + f.write("[path_keywords]\n") + f.write("loadbalancers = loadbalancer\n\n") + f.write("[service_endpoints]\n") + f.write("load-balancer = service/load-balancer") + + env_headers = {'HTTP_X_SERVICE_CATALOG': + '''[{"endpoints_links": [], + "endpoints": [{"adminURL": + "http://admin_host/compute", + "region": "RegionOne", + "publicURL": + "http://public_host/compute"}], + "type": "compute", + "name": "nova"}, + {"endpoints_links": [], + "endpoints": [{"adminURL": + "http://admin_host/load-balancer", + "region": "RegionOne", + "publicURL": + "http://public_host/load-balancer"}], + "type": "load-balancer", + "name": "octavia"}]''', + 'HTTP_X_USER_ID': 'user_id', + 'HTTP_X_USER_NAME': 'user_name', + 'HTTP_X_AUTH_TOKEN': 'token', + 'HTTP_X_PROJECT_ID': 'tenant_id', + 'HTTP_X_IDENTITY_STATUS': 'Confirmed', + 'REQUEST_METHOD': 'GET'} + + url = ('http://admin_host/load-balancer/v2/loadbalancers/' + + str(uuid.uuid4())) + payload = self.get_payload('GET', url, environ=env_headers) + self.assertEqual(payload['target']['id'], 'octavia') + def test_no_auth_token(self): # Test cases where API requests such as Swift list public containers # which does not require an auth token. In these cases, CADF event diff --git a/releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml b/releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml new file mode 100644 index 00000000..31d2a848 --- /dev/null +++ b/releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + [`bug 1797584 `_] + Fixed a bug where the audit code would select the wrong target service + if the OpenStack service endpoints were not using unique TCP ports.