commit 81c60832c2a9f435b28f308029a46261912e9f12
Author: Stavros Sachtouris <saxtouri@admin.grnet.gr>
Date:   Thu Oct 3 18:46:52 2013 +0300

    Move cluster handling in server create/delete
    
    Refs: #4429

diff --git a/kamaki/cli/commands/cyclades.py b/kamaki/cli/commands/cyclades.py
index 729ee85..2adea2c 100644
--- a/kamaki/cli/commands/cyclades.py
+++ b/kamaki/cli/commands/cyclades.py
@@ -375,22 +375,41 @@ class server_create(_init_cyclades, _optional_json, _server_wait):
     arguments = dict(
         personality=PersonalityArgument(
             (80 * ' ').join(howto_personality), ('-p', '--personality')),
-        wait=FlagArgument('Wait server to build', ('-w', '--wait'))
+        wait=FlagArgument('Wait server to build', ('-w', '--wait')),
+        cluster_size=IntArgument(
+            'Create a cluster of servers of this size. In this case, the name'
+            'parameter is the prefix of each server in the cluster (e.g.,'
+            'srv1, srv2, etc.',
+            '--cluster-size')
     )
 
+    @errors.cyclades.cluster_size
+    def _create_cluster(self, prefix, flavor_id, image_id, size):
+        servers = [dict(
+            name='%s%s' % (prefix, i),
+            flavor_id=flavor_id,
+            image_id=image_id,
+            personality=self['personality']) for i in range(size)]
+        if size == 1:
+            return [self.client.create_server(**servers[0])]
+        return self.client.async_run(self.client.create_server, servers)
+
     @errors.generic.all
     @errors.cyclades.connection
     @errors.plankton.id
     @errors.cyclades.flavor_id
     def _run(self, name, flavor_id, image_id):
-        r = self.client.create_server(
-            name, int(flavor_id), image_id, personality=self['personality'])
-        usernames = self._uuids2usernames([r['user_id'], r['tenant_id']])
-        r['user_id'] += ' (%s)' % usernames[r['user_id']]
-        r['tenant_id'] += ' (%s)' % usernames[r['tenant_id']]
-        self._print(r, self.print_dict)
-        if self['wait']:
-            self._wait(r['id'], r['status'])
+        for r in self._create_cluster(
+                name, flavor_id, image_id, size=self['cluster_size'] or 1):
+            print 'HEY I GOT A', r
+            print 'MKEY?????????????????'
+            usernames = self._uuids2usernames([r['user_id'], r['tenant_id']])
+            r['user_id'] += ' (%s)' % usernames[r['user_id']]
+            r['tenant_id'] += ' (%s)' % usernames[r['tenant_id']]
+            self._print(r, self.print_dict)
+            if self['wait']:
+                self._wait(r['id'], r['status'])
+            self.error('')
 
     def main(self, name, flavor_id, image_id):
         super(self.__class__, self)._run()
@@ -421,27 +440,41 @@ class server_delete(_init_cyclades, _optional_output_cmd, _server_wait):
     """Delete a virtual server"""
 
     arguments = dict(
-        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait'))
+        wait=FlagArgument('Wait server to be destroyed', ('-w', '--wait')),
+        cluster=FlagArgument(
+            '(DANGEROUS) Delete all virtual servers prefixed with the cluster '
+            'prefix. In that case, the prefix replaces the server id',
+            '--cluster')
     )
 
+    def _server_ids(self, server_var):
+        if self['cluster']:
+            return [s['id'] for s in self.client.list_servers() if (
+                s['name'].startswith(server_var))]
+
+        @errors.cyclades.server_id
+        def _check_server_id(self, server_id):
+            return server_id
+
+        return [_check_server_id(self, server_id=server_var), ]
+
     @errors.generic.all
     @errors.cyclades.connection
-    @errors.cyclades.server_id
-    def _run(self, server_id):
-            status = 'DELETED'
+    def _run(self, server_var):
+        for server_id in self._server_ids(server_var):
             if self['wait']:
                 details = self.client.get_server_details(server_id)
                 status = details['status']
 
-            r = self.client.delete_server(int(server_id))
+            r = self.client.delete_server(server_id)
             self._optional_output(r)
 
             if self['wait']:
                 self._wait(server_id, status)
 
-    def main(self, server_id):
+    def main(self, server_id_or_cluster_prefix):
         super(self.__class__, self)._run()
-        self._run(server_id=server_id)
+        self._run(server_id_or_cluster_prefix)
 
 
 @command(server_cmds)
@@ -785,52 +818,6 @@ class server_wait(_init_cyclades, _server_wait):
         self._run(server_id=server_id, current_status=current_status)
 
 
-@command(server_cmds)
-class server_cluster_create(_init_cyclades):
-    """Create a cluster of virtual servers
-    All new servers will be named as <prefix><increment> e.g.,
-    mycluster1, mycluster2, etc.
-    All servers in the cluster will run the same image on the same hardware
-    flavor.
-    """
-
-    @errors.generic.all
-    @errors.cyclades.connection
-    @errors.plankton.id
-    @errors.cyclades.flavor_id
-    @errors.cyclades.cluster_size
-    def _run(self, prefix, image_id, flavor_id, size):
-        servers = [dict(
-            name='%s%s' % (prefix, i),
-            flavor_id=flavor_id,
-            image_id=image_id) for i in range(int(size))]
-        self.client.create_cluster(servers)
-
-    def main(self, prefix, image_id, flavor_id, size):
-        super(self.__class__, self)._run()
-        self._run(prefix, image_id=image_id, flavor_id=flavor_id, size=size)
-
-
-@command(server_cmds)
-class server_cluster_delete(_init_cyclades):
-    """Remove all servers that belong to a virtual cluster
-    A virtual cluster consists of the virtual servers with the same name prefix
-    ATTENTION: make sure you want to delete all servers of that prefix
-    To get a list of your servers:  /server list
-    """
-
-    @errors.generic.all
-    @errors.cyclades.connection
-    def _run(self, prefix):
-        servers = [s['id'] for s in self.client.list_servers() if (
-            s['name'].startswith(prefix))]
-        self.client.delete_cluster(servers)
-
-    def main(self, prefix):
-        super(self.__class__, self)._run()
-        self._run(prefix)
-
-
 @command(flavor_cmds)
 class flavor_list(_init_cyclades, _optional_json, _name_filter, _id_filter):
     """List available hardware flavors"""
