Merge commit '19031b24b523c872c1ac367821dc60c950a09755' as 'modules/libjuju'
[osm/N2VC.git] / modules / libjuju / juju / placement.py
diff --git a/modules/libjuju/juju/placement.py b/modules/libjuju/juju/placement.py
new file mode 100644 (file)
index 0000000..d0d42f7
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# 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.
+#
+
+from .client import client
+
+MACHINE_SCOPE = "#"
+
+
+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 not directive:
+        # Handle null case
+        return None
+
+    if isinstance(directive, (list, tuple)):
+        results = []
+        for d in directive:
+            results.extend(parse(d))
+        return results
+
+    if isinstance(directive, (dict, client.Placement)):
+        # We've been handed something that we can simply hand back to
+        # the api. (Forwards compatibility)
+        return [directive]
+
+    # Juju 2.0 can't handle lxc containers.
+    directive = directive.replace('lxc', 'lxd')
+
+    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)]
+
+    if "/" in directive:
+        # e.g. "0/lxd/0"
+        # https://github.com/juju/juju/blob/master/instance/placement_test.go#L29
+        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)]