Browse Source

Add netloc and version check for version discovery

If the url netloc in the catalog and service's response
are not the same, we should choose the catalog's and
add the version info to it if needed.

Change-Id: If78d368bd505156a5416bb9cbfaf988204925c79
Closes-bug: #1733052
wangxiyuan 10 months ago
parent
commit
323f4e4bc4

+ 19
- 1
keystoneauth1/discover.py View File

@@ -417,10 +417,28 @@ def _combine_relative_url(discovery_url, version_url):
417 417
     parsed_version_url = urllib.parse.urlparse(url)
418 418
     parsed_discovery_url = urllib.parse.urlparse(discovery_url)
419 419
 
420
+    # The services can override the version_url with some config options.(for
421
+    # example, In Keystone, Cinder and Glance, the option is "public_endpoint",
422
+    # and "compute_link_prefix", "network_link_prefix" in Nova and Neutron.
423
+    # In this case, it's hard to distinguish which part in version_url is
424
+    # useful for discovery_url , so here we just get the version from
425
+    # version_url and then add it into the discovery_url if needed.
426
+    path = parsed_version_url.path
427
+    if parsed_discovery_url.netloc != parsed_version_url.netloc:
428
+        version = version_url.rstrip('/').split('/')[-1]
429
+        url_path = parsed_discovery_url.path.rstrip('/')
430
+        if not url_path.endswith(version):
431
+            path = url_path + '/' + version
432
+            if version_url.endswith('/'):
433
+                # add '/' back to keep backward compatibility.
434
+                path = path + '/'
435
+        else:
436
+            path = parsed_discovery_url.path
437
+
420 438
     return urllib.parse.ParseResult(
421 439
         parsed_discovery_url.scheme,
422 440
         parsed_discovery_url.netloc,
423
-        parsed_version_url.path,
441
+        path,
424 442
         parsed_version_url.params,
425 443
         parsed_version_url.query,
426 444
         parsed_version_url.fragment).geturl()

+ 1
- 1
keystoneauth1/tests/unit/identity/test_identity_common.py View File

@@ -329,7 +329,7 @@ class CommonIdentityTests(object):
329 329
         sb = session.Session()
330 330
         discovery_cache = {}
331 331
 
332
-        expected_url = urllib.parse.urljoin(self.TEST_COMPUTE_ADMIN, '/v2.0')
332
+        expected_url = self.TEST_COMPUTE_ADMIN + '/v2.0'
333 333
         for sess in (sa, sb):
334 334
 
335 335
             disc = discover.get_discovery(

+ 34
- 0
keystoneauth1/tests/unit/test_discovery.py View File

@@ -491,6 +491,40 @@ class VersionDataTests(utils.TestCase):
491 491
 
492 492
             self.assertTrue(mock.called_once)
493 493
 
494
+    def test_version_data_override_version_url(self):
495
+        # if the request url is versioned already, just return it.
496
+        self.requests_mock.get(
497
+            V3_URL, status_code=200,
498
+            json={'version': fixture.V3Discovery('http://override/identity/v3')
499
+                  }
500
+        )
501
+
502
+        disc = discover.Discover(self.session, V3_URL)
503
+        version_data = disc.version_data()
504
+
505
+        for v in version_data:
506
+            self.assertEqual(v['version'], (3, 0))
507
+            self.assertEqual(v['status'], discover.Status.CURRENT)
508
+            self.assertEqual(v['raw_status'], 'stable')
509
+            self.assertEqual(v['url'], V3_URL)
510
+
511
+        # if the request url is not versioned, just add version info to it.(
512
+        # do not changed the url's netloc or path)
513
+        self.requests_mock.get(
514
+            BASE_URL, status_code=200,
515
+            json={'version': fixture.V3Discovery('http://override/identity/v3')
516
+                  }
517
+        )
518
+
519
+        disc = discover.Discover(self.session, BASE_URL)
520
+        version_data = disc.version_data()
521
+
522
+        for v in version_data:
523
+            self.assertEqual(v['version'], (3, 0))
524
+            self.assertEqual(v['status'], discover.Status.CURRENT)
525
+            self.assertEqual(v['raw_status'], 'stable')
526
+            self.assertEqual(v['url'], V3_URL)
527
+
494 528
     def test_version_data_unknown(self):
495 529
         discovery_fixture = fixture.V3Discovery(V3_URL)
496 530
         discovery_fixture.status = 'hungry'

+ 7
- 0
releasenotes/notes/bug-1733052-1b4af3b3fe1b05bb.yaml View File

@@ -0,0 +1,7 @@
1
+---
2
+fixes:
3
+  - >
4
+    [`bug 1733052 <https://bugs.launchpad.net/keystoneauth/+bug/1733052>`_]
5
+    Now the version discovery mechanism only fetches the version info from
6
+    server side if the versioned url has been overrode. So that the request
7
+    url's path won't be changed completely.

Loading…
Cancel
Save