← Back to team overview

sts-sponsors team mailing list archive

[Merge] ~troyanov/maas:backport-fix-2009186-to-3.3 into maas:3.3

 

Anton Troyanov has proposed merging ~troyanov/maas:backport-fix-2009186-to-3.3 into maas:3.3.

Commit message:
fix(cli): use profile.url to build absolute uri

When MAAS is behind a load-balancer or proxy
(e.g. HAProxy with `mode tcp`), CLI should use MAAS URL stored in profile
to build absolute URI of a resource, instead of relying on `uri` property
returned by `/describe`.

Resolves LP:2009186

(cherry picked from commit 28c72b81ed318b283cd3f2ddcae2e199ca067228)

Requested reviews:
  MAAS Maintainers (maas-maintainers)
Related bugs:
  Bug #2009186 in MAAS: "CLI results in connection timed out when behind haproxy and 5240 is blocked"
  https://bugs.launchpad.net/maas/+bug/2009186

For more details, see:
https://code.launchpad.net/~troyanov/maas/+git/maas/+merge/438404
-- 
Your team MAAS Maintainers is requested to review the proposed merge of ~troyanov/maas:backport-fix-2009186-to-3.3 into maas:3.3.
diff --git a/src/maascli/api.py b/src/maascli/api.py
index d121309..7196977 100644
--- a/src/maascli/api.py
+++ b/src/maascli/api.py
@@ -90,7 +90,10 @@ class Action(Command):
     # Override these in subclasses; see `register_actions`.
     profile = handler = action = None
 
-    uri = property(lambda self: self.handler["uri"])
+    _maas_url = property(lambda self: urlparse(self.profile["url"]))
+    uri = property(
+        lambda self: f"{self._maas_url.scheme}://{self._maas_url.netloc}{self.handler['path']}"
+    )
     method = property(lambda self: self.action["method"])
     credentials = property(lambda self: self.profile["credentials"])
     op = property(lambda self: self.action["op"])
diff --git a/src/maascli/tests/test_api.py b/src/maascli/tests/test_api.py
index a767648..9b2f659 100644
--- a/src/maascli/tests/test_api.py
+++ b/src/maascli/tests/test_api.py
@@ -304,7 +304,8 @@ class TestAction(MAASTestCase):
             "name": factory.make_name("handler"),
             "handler_name": factory.make_name("handler"),
             "params": [],
-            "uri": "http://example.com/api/2.0/";,
+            "path": "/MAAS/api/2.0",
+            "uri": "http://example.com/MAAS/api/2.0/";,
         }
         action = {"name": "action", "op": "test", "method": "GET"}
         action_name = safe_name(action["name"])
@@ -342,6 +343,29 @@ class TestAction(MAASTestCase):
         action_parser(options)
         mock_materializer.assert_called_once()
 
+    def test_action_build_correct_uri(self):
+        handler = {
+            "name": factory.make_name("handler"),
+            "handler_name": factory.make_name("handler"),
+            "params": [],
+            "path": "/MAAS/api/2.0/resource",
+        }
+        action = {"name": "action", "op": "test", "method": "GET"}
+        action_name = safe_name(action["name"])
+        action_bases = api.get_action_class_bases(handler, action)
+        profile = make_profile()
+        profile["url"] = "http://localhost:5240/MAAS";
+
+        action_ns = {"action": action, "handler": handler, "profile": profile}
+        action_class = type(action_name, action_bases, action_ns)
+
+        parser = ArgumentParser()
+        action_parser = action_class(parser)
+
+        self.assertEqual(
+            "http://localhost:5240/MAAS/api/2.0/resource";, action_parser.uri
+        )
+
 
 class TestActionHelp(MAASTestCase):
     def make_help(self):