]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/orchestrator: add ability to parse placementspec from strings 33441/head
authorDaniel-Pivonka <dpivonka@redhat.com>
Thu, 20 Feb 2020 15:22:35 +0000 (10:22 -0500)
committerDaniel-Pivonka <dpivonka@redhat.com>
Thu, 20 Feb 2020 19:46:24 +0000 (14:46 -0500)
Signed-off-by: Daniel-Pivonka <dpivonka@redhat.com>
src/pybind/mgr/orchestrator/_interface.py

index 2f04de54e0004a6f288a41a2f46b976a94576413..ac079579b2c0b55c6fc5480d8aa8285ec4ab8435 100644 (file)
@@ -1164,6 +1164,47 @@ class PlacementSpec(object):
         if self.count is not None and self.count <= 0:
             raise Exception("num/count must be > 1")
 
+    @classmethod
+    def from_strings(cls, strings):
+        # type: (Optional[List[str]]) -> PlacementSpec
+        """
+        A single integer is parsed as a count:
+        >>> PlacementSpec.from_strings('3'.split())
+        PlacementSpec(count=3)
+        A list of names is parsed as host specifications:
+        >>> PlacementSpec.from_strings('host1 host2'.split())
+        PlacementSpec(label=[HostSpec(hostname='host1', network='', name=''), HostSpec(hostname='host2', network='', name='')])
+        You can also prefix the hosts with a count as follows:
+        >>> PlacementSpec.from_strings('2 host1 host2'.split())
+        PlacementSpec(label=[HostSpec(hostname='host1', network='', name=''), HostSpec(hostname='host2', network='', name='')], count=2)
+        You can spefify labels using `label:<label>`
+        >>> PlacementSpec.from_strings('label:mon'.split())
+        PlacementSpec(label='label:mon')
+        Labels als support a count:
+        >>> PlacementSpec.from_strings('3 label:mon'.split())
+        PlacementSpec(label='label:mon', count=3)
+        >>> PlacementSpec.from_strings(None)
+        PlacementSpec()
+        """
+        strings = strings or []
+
+        count = None
+        if strings:
+            try:
+                count = int(strings[0])
+                strings = strings[1:]
+            except ValueError:
+                pass
+
+        hosts = [x for x in strings if 'label:' not in x]
+        labels = [x for x in strings if 'label:' in x]
+        if len(labels) > 1:
+            raise OrchestratorValidationError('more than one label provided: {}'.format(labels))
+
+        ps = PlacementSpec(count=count, hosts=hosts, label=labels[0] if labels else None)
+        ps.validate()
+        return ps
+
 
 def handle_type_error(method):
     @wraps(method)