Add -w/--wait to server firewall set
authorStavros Sachtouris <saxtouri@admin.grnet.gr>
Mon, 30 Sep 2013 14:13:23 +0000 (17:13 +0300)
committerStavros Sachtouris <saxtouri@admin.grnet.gr>
Mon, 30 Sep 2013 14:13:23 +0000 (17:13 +0300)
Refs: #4298

kamaki/cli/commands/cyclades.py
kamaki/clients/cyclades/__init__.py

index bb922cb..3cf7644 100644 (file)
@@ -39,7 +39,8 @@ from pydoc import pager
 from kamaki.cli import command
 from kamaki.cli.command_tree import CommandTree
 from kamaki.cli.utils import remove_from_items, filter_dicts_by_dict
-from kamaki.cli.errors import raiseCLIError, CLISyntaxError, CLIBaseUrlError
+from kamaki.cli.errors import (
+    raiseCLIError, CLISyntaxError, CLIBaseUrlError, CLIInvalidArgument)
 from kamaki.clients.cyclades import CycladesClient, ClientError
 from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
 from kamaki.cli.argument import ProgressBarArgument, DateArgument, IntArgument
@@ -116,6 +117,15 @@ class _network_wait(_service_wait):
             timeout=timeout)
 
 
+class _firewall_wait(_service_wait):
+
+    def _wait(self, server_id, current_status, timeout=60):
+        super(_firewall_wait, self)._wait(
+            'Firewall of server',
+            server_id, self.client.wait_firewall, current_status,
+            timeout=timeout)
+
+
 class _init_cyclades(_command_init):
     @errors.generic.all
     @addLogSettings
@@ -552,7 +562,8 @@ class server_firewall(_init_cyclades):
 
 
 @command(server_cmds)
-class server_firewall_set(_init_cyclades, _optional_output_cmd):
+class server_firewall_set(
+        _init_cyclades, _optional_output_cmd, _firewall_wait):
     """Set the firewall profile on virtual server public network
     Values for profile:
     - DISABLED: Shutdown firewall
@@ -560,13 +571,30 @@ class server_firewall_set(_init_cyclades, _optional_output_cmd):
     - PROTECTED: Firewall in secure mode
     """
 
+    arguments = dict(
+        wait=FlagArgument('Wait server firewall to build', ('-w', '--wait')),
+        timeout=IntArgument(
+            'Set wait timeout in seconds (default: 60)', '--timeout',
+            default=60)
+    )
+
     @errors.generic.all
     @errors.cyclades.connection
     @errors.cyclades.server_id
     @errors.cyclades.firewall
     def _run(self, server_id, profile):
-        self._optional_output(self.client.set_firewall_profile(
-            server_id=int(server_id), profile=('%s' % profile).upper()))
+        if self['timeout'] and not self['wait']:
+            raise CLIInvalidArgument('Invalid use of --timeout', details=[
+                'Timeout is used only along with -w/--wait'])
+        old_profile = self.client.get_firewall_profile(server_id)
+        if old_profile.lower() == profile.lower():
+            self.error('Firewall of server %s: allready in status %s' % (
+                server_id, old_profile))
+        else:
+            self._optional_output(self.client.set_firewall_profile(
+                server_id=int(server_id), profile=('%s' % profile).upper()))
+            if self['wait']:
+                self._wait(server_id, old_profile, timeout=self['timeout'])
 
     def main(self, server_id, profile):
         super(self.__class__, self)._run()
index 760ca2f..b86a5a5 100644 (file)
@@ -342,6 +342,8 @@ class CycladesClient(CycladesRestClient):
 
         :param delay: time interval between retries
 
+        :max_wait: (int) timeout in secconds
+
         :param wait_cb: if set a progressbar is used to show progress
 
         :returns: (str) the new mode if succesfull, (bool) False if timed out
@@ -366,6 +368,8 @@ class CycladesClient(CycladesRestClient):
 
         :param delay: time interval between retries
 
+        :max_wait: (int) timeout in secconds
+
         :param wait_cb: if set a progressbar is used to show progress
 
         :returns: (str) the new mode if succesfull, (bool) False if timed out
@@ -378,6 +382,30 @@ class CycladesClient(CycladesRestClient):
         return self._wait(
             net_id, current_status, get_status, delay, max_wait, wait_cb)
 
+    def wait_firewall(
+            self, server_id,
+            current_status='DISABLED', delay=1, max_wait=100, wait_cb=None):
+        """Wait while the public network firewall status is current_status
+
+        :param server_id: integer (str or int)
+
+        :param current_status: (str) DISABLED | ENABLED | PROTECTED
+
+        :param delay: time interval between retries
+
+        :max_wait: (int) timeout in secconds
+
+        :param wait_cb: if set a progressbar is used to show progress
+
+        :returns: (str) the new mode if succesfull, (bool) False if timed out
+        """
+
+        def get_status(self, server_id):
+            return self.get_firewall_profile(server_id), None
+
+        return self._wait(
+            server_id, current_status, get_status, delay, max_wait, wait_cb)
+
     def get_floating_ip_pools(self):
         """
         :returns: (dict) {floating_ip_pools:[{name: ...}, ...]}