Browse Source

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
Michael Johnson 6 months ago
parent
commit
782729b6e9

+ 2
- 2
keystonemiddleware/audit/_api.py View File

@@ -272,8 +272,8 @@ class OpenStackAuditApi(object):
272 272
             public_urlparse = urlparse.urlparse(
273 273
                 endpoint_urls.get('publicURL', ''))
274 274
             req_url = urlparse.urlparse(req.host_url)
275
-            if (req_url.netloc == admin_urlparse.netloc
276
-                    or req_url.netloc == public_urlparse.netloc):
275
+            if req_url.port and (req_url.netloc == admin_urlparse.netloc
276
+                                 or req_url.netloc == public_urlparse.netloc):
277 277
                 service_info = self._get_service_info(endp)
278 278
                 break
279 279
             elif (self._MAP.default_target_endpoint_type and

+ 38
- 0
keystonemiddleware/tests/unit/audit/test_audit_api.py View File

@@ -320,6 +320,44 @@ class AuditApiLogicTest(base.BaseAuditMiddlewareTest):
320 320
         payload = self.get_payload('GET', url, environ=env_headers)
321 321
         self.assertEqual(payload['target']['name'], "unknown")
322 322
 
323
+    def test_endpoint_no_service_port(self):
324
+        with open(self.audit_map, "w") as f:
325
+            f.write("[DEFAULT]\n")
326
+            f.write("target_endpoint_type = load-balancer\n")
327
+            f.write("[path_keywords]\n")
328
+            f.write("loadbalancers = loadbalancer\n\n")
329
+            f.write("[service_endpoints]\n")
330
+            f.write("load-balancer = service/load-balancer")
331
+
332
+        env_headers = {'HTTP_X_SERVICE_CATALOG':
333
+                       '''[{"endpoints_links": [],
334
+                            "endpoints": [{"adminURL":
335
+                                           "http://admin_host/compute",
336
+                                           "region": "RegionOne",
337
+                                           "publicURL":
338
+                                           "http://public_host/compute"}],
339
+                             "type": "compute",
340
+                             "name": "nova"},
341
+                           {"endpoints_links": [],
342
+                            "endpoints": [{"adminURL":
343
+                                           "http://admin_host/load-balancer",
344
+                                           "region": "RegionOne",
345
+                                           "publicURL":
346
+                                           "http://public_host/load-balancer"}],
347
+                             "type": "load-balancer",
348
+                             "name": "octavia"}]''',
349
+                       'HTTP_X_USER_ID': 'user_id',
350
+                       'HTTP_X_USER_NAME': 'user_name',
351
+                       'HTTP_X_AUTH_TOKEN': 'token',
352
+                       'HTTP_X_PROJECT_ID': 'tenant_id',
353
+                       'HTTP_X_IDENTITY_STATUS': 'Confirmed',
354
+                       'REQUEST_METHOD': 'GET'}
355
+
356
+        url = ('http://admin_host/load-balancer/v2/loadbalancers/' +
357
+               str(uuid.uuid4()))
358
+        payload = self.get_payload('GET', url, environ=env_headers)
359
+        self.assertEqual(payload['target']['id'], 'octavia')
360
+
323 361
     def test_no_auth_token(self):
324 362
         # Test cases where API requests such as Swift list public containers
325 363
         # which does not require an auth token. In these cases, CADF event

+ 6
- 0
releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml View File

@@ -0,0 +1,6 @@
1
+---
2
+fixes:
3
+  - |
4
+    [`bug 1797584 <https://bugs.launchpad.net/keystonemiddleware/+bug/1797584>`_]
5
+    Fixed a bug where the audit code would select the wrong target service
6
+    if the OpenStack service endpoints were not using unique TCP ports.

Loading…
Cancel
Save