from . import model
from .client import client
+from .placement import parse as parse_placement
log = logging.getLogger(__name__)
result = await app_facade.AddUnits(
application=self.name,
- placement=to,
+ placement=[parse_placement(to)],
num_units=count,
)
--- /dev/null
+#
+# This module allows us to parse a machine placement directive into a
+# Placement object suitable for passing through the websocket API.
+#
+# Once https://bugs.launchpad.net/juju/+bug/1645480 is addressed, this
+# module should be deprecated.
+#
+
+MACHINE_SCOPE = "#"
+
+from .client import client
+
+def parse(directive):
+ """
+ Given a string in the format `scope:directive`, or simply `scope`
+ or `directive`, return a Placement object suitable for passing
+ back over the websocket API.
+
+ """
+ if directive == "":
+ # Handle null case
+ return None
+
+ if type(directive) in [dict, client.Placement]:
+ # We've been handed something that we can simply hand back to
+ # the api. (Forwards compatibility)
+ return directive
+
+ if ":" in directive:
+ # Planner has given us a scope and directive in string form
+ scope, directive = directive.split(":")
+ return client.Placement(scope=scope, directive=directive)
+
+ if directive.isdigit():
+ # Planner has given us a machine id (we rely on juju core to
+ # verify its validity.)
+ return client.Placement(scope=MACHINE_SCOPE, directive=directive)
+
+ # Planner has probably given us a container type. Leave it up to
+ # juju core to verify that it is valid.
+ return client.Placement(scope=directive)
--- /dev/null
+#
+# Test our placement helper
+#
+
+import unittest
+
+from juju import placement
+from juju.client import client
+
+class TestPlacement(unittest.TestCase):
+
+ def test_parse_both_specified(self):
+ res = placement.parse("foo:bar")
+ self.assertEqual(res.scope, "foo")
+ self.assertEqual(res.directive, "bar")
+
+ def test_parse_machine(self):
+ res = placement.parse("22")
+ self.assertEqual(res.scope, "#")
+ self.assertEqual(res.directive, "22")