Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / cyclades / __init__.py @ 058ee9a8

History | View | Annotate | Download (16 kB)

1 24851aa5 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 a1c50326 Giorgos Verigakis
#
3 a1c50326 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 a1c50326 Giorgos Verigakis
# without modification, are permitted provided that the following
5 a1c50326 Giorgos Verigakis
# conditions are met:
6 a1c50326 Giorgos Verigakis
#
7 a1c50326 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 a1c50326 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 a1c50326 Giorgos Verigakis
#      disclaimer.
10 a1c50326 Giorgos Verigakis
#
11 a1c50326 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 a1c50326 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 a1c50326 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 a1c50326 Giorgos Verigakis
#      provided with the distribution.
15 a1c50326 Giorgos Verigakis
#
16 a1c50326 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a1c50326 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a1c50326 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a1c50326 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a1c50326 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a1c50326 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a1c50326 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a1c50326 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a1c50326 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a1c50326 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a1c50326 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a1c50326 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 a1c50326 Giorgos Verigakis
#
29 a1c50326 Giorgos Verigakis
# The views and conclusions contained in the software and
30 a1c50326 Giorgos Verigakis
# documentation are those of the authors and should not be
31 a1c50326 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 a1c50326 Giorgos Verigakis
# or implied, of GRNET S.A.
33 a1c50326 Giorgos Verigakis
34 02846a75 Stavros Sachtouris
from time import sleep
35 02846a75 Stavros Sachtouris
36 55faa0bc Stavros Sachtouris
from kamaki.clients.cyclades.rest_api import CycladesRestClient
37 6c068db6 Stavros Sachtouris
from kamaki.clients import ClientError
38 a1c50326 Giorgos Verigakis
39 3dabe5d2 Stavros Sachtouris
40 55faa0bc Stavros Sachtouris
class CycladesClient(CycladesRestClient):
41 76e7661e Stavros Sachtouris
    """Synnefo Cyclades Compute API client"""
42 2f749e6e Stavros Sachtouris
43 dbcbf446 Stavros Sachtouris
    def create_server(
44 dbcbf446 Stavros Sachtouris
            self, name, flavor_id, image_id,
45 dbcbf446 Stavros Sachtouris
            metadata=None, personality=None):
46 dbcbf446 Stavros Sachtouris
        """Submit request to create a new server
47 dbcbf446 Stavros Sachtouris

48 dbcbf446 Stavros Sachtouris
        :param name: (str)
49 dbcbf446 Stavros Sachtouris

50 dbcbf446 Stavros Sachtouris
        :param flavor_id: integer id denoting a preset hardware configuration
51 dbcbf446 Stavros Sachtouris

52 2bd23362 Stavros Sachtouris
        :param image_id: (str) id denoting the OS image to run on virt. server
53 dbcbf446 Stavros Sachtouris

54 dbcbf446 Stavros Sachtouris
        :param metadata: (dict) vm metadata updated by os/users image metadata
55 dbcbf446 Stavros Sachtouris

56 dbcbf446 Stavros Sachtouris
        :param personality: a list of (file path, file contents) tuples,
57 2bd23362 Stavros Sachtouris
            describing files to be injected into virtual server upon creation
58 dbcbf446 Stavros Sachtouris

59 2bd23362 Stavros Sachtouris
        :returns: a dict with the new virtual server details
60 dbcbf446 Stavros Sachtouris

61 dbcbf446 Stavros Sachtouris
        :raises ClientError: wraps request errors
62 dbcbf446 Stavros Sachtouris
        """
63 dbcbf446 Stavros Sachtouris
        image = self.get_image_details(image_id)
64 dbcbf446 Stavros Sachtouris
        metadata = metadata or dict()
65 dbcbf446 Stavros Sachtouris
        for key in ('os', 'users'):
66 dbcbf446 Stavros Sachtouris
            try:
67 dbcbf446 Stavros Sachtouris
                metadata[key] = image['metadata'][key]
68 dbcbf446 Stavros Sachtouris
            except KeyError:
69 dbcbf446 Stavros Sachtouris
                pass
70 dbcbf446 Stavros Sachtouris
71 65a8b1da Stavros Sachtouris
        return super(CycladesClient, self).create_server(
72 65a8b1da Stavros Sachtouris
            name, flavor_id, image_id,
73 65a8b1da Stavros Sachtouris
            metadata=metadata, personality=personality)
74 dbcbf446 Stavros Sachtouris
75 a1c50326 Giorgos Verigakis
    def start_server(self, server_id):
76 f5eac743 Stavros Sachtouris
        """Submit a startup request
77 f5eac743 Stavros Sachtouris

78 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
79 cd295a1d Stavros Sachtouris

80 cd295a1d Stavros Sachtouris
        :returns: (dict) response headers
81 f5eac743 Stavros Sachtouris
        """
82 6a0b1658 Giorgos Verigakis
        req = {'start': {}}
83 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req, success=202)
84 cd295a1d Stavros Sachtouris
        return r.headers
85 6f1ec797 Stavros Sachtouris
86 a1c50326 Giorgos Verigakis
    def shutdown_server(self, server_id):
87 f5eac743 Stavros Sachtouris
        """Submit a shutdown request
88 f5eac743 Stavros Sachtouris

89 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
90 cd295a1d Stavros Sachtouris

91 cd295a1d Stavros Sachtouris
        :returns: (dict) response headers
92 f5eac743 Stavros Sachtouris
        """
93 6a0b1658 Giorgos Verigakis
        req = {'shutdown': {}}
94 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req, success=202)
95 cd295a1d Stavros Sachtouris
        return r.headers
96 3dabe5d2 Stavros Sachtouris
97 a1c50326 Giorgos Verigakis
    def get_server_console(self, server_id):
98 f5eac743 Stavros Sachtouris
        """
99 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
100 f5eac743 Stavros Sachtouris

101 2bd23362 Stavros Sachtouris
        :returns: (dict) info to set a VNC connection to virtual server
102 f5eac743 Stavros Sachtouris
        """
103 6a0b1658 Giorgos Verigakis
        req = {'console': {'type': 'vnc'}}
104 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req, success=200)
105 6a0b1658 Giorgos Verigakis
        return r.json['console']
106 2d67ecbb Stavros Sachtouris
107 2d67ecbb Stavros Sachtouris
    def get_firewall_profile(self, server_id):
108 f5eac743 Stavros Sachtouris
        """
109 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
110 f5eac743 Stavros Sachtouris

111 f5eac743 Stavros Sachtouris
        :returns: (str) ENABLED | DISABLED | PROTECTED
112 f5eac743 Stavros Sachtouris

113 f5eac743 Stavros Sachtouris
        :raises ClientError: 520 No Firewall Profile
114 f5eac743 Stavros Sachtouris
        """
115 2d67ecbb Stavros Sachtouris
        r = self.get_server_details(server_id)
116 2d67ecbb Stavros Sachtouris
        try:
117 fab9b17f Stavros Sachtouris
            return r['attachments'][0]['firewallProfile']
118 2d67ecbb Stavros Sachtouris
        except KeyError:
119 24ff0a35 Stavros Sachtouris
            raise ClientError(
120 7d768bc6 Stavros Sachtouris
                'No Firewall Profile',
121 3dabe5d2 Stavros Sachtouris
                details='Server %s is missing a firewall profile' % server_id)
122 2d67ecbb Stavros Sachtouris
123 a1c50326 Giorgos Verigakis
    def set_firewall_profile(self, server_id, profile):
124 a1c50326 Giorgos Verigakis
        """Set the firewall profile for the public interface of a server
125 f5eac743 Stavros Sachtouris

126 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
127 f5eac743 Stavros Sachtouris

128 f5eac743 Stavros Sachtouris
        :param profile: (str) ENABLED | DISABLED | PROTECTED
129 cd295a1d Stavros Sachtouris

130 cd295a1d Stavros Sachtouris
        :returns: (dict) response headers
131 a1c50326 Giorgos Verigakis
        """
132 6a0b1658 Giorgos Verigakis
        req = {'firewallProfile': {'profile': profile}}
133 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req, success=202)
134 cd295a1d Stavros Sachtouris
        return r.headers
135 3dabe5d2 Stavros Sachtouris
136 c7083665 Stavros Sachtouris
    def list_server_nics(self, server_id):
137 f5eac743 Stavros Sachtouris
        """
138 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
139 f5eac743 Stavros Sachtouris

140 f5eac743 Stavros Sachtouris
        :returns: (dict) network interface connections
141 f5eac743 Stavros Sachtouris
        """
142 e51c7d5b Stavros Sachtouris
        r = self.servers_ips_get(server_id)
143 9a70c511 Stavros Sachtouris
        return r.json['attachments']
144 1a85b14f Stavros Sachtouris
145 a1c50326 Giorgos Verigakis
    def get_server_stats(self, server_id):
146 f5eac743 Stavros Sachtouris
        """
147 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
148 f5eac743 Stavros Sachtouris

149 f5eac743 Stavros Sachtouris
        :returns: (dict) auto-generated graphs of statistics (urls)
150 f5eac743 Stavros Sachtouris
        """
151 e51c7d5b Stavros Sachtouris
        r = self.servers_stats_get(server_id)
152 6a0b1658 Giorgos Verigakis
        return r.json['stats']
153 3dabe5d2 Stavros Sachtouris
154 a1c50326 Giorgos Verigakis
    def list_networks(self, detail=False):
155 f5eac743 Stavros Sachtouris
        """
156 f5eac743 Stavros Sachtouris
        :param detail: (bool)
157 f5eac743 Stavros Sachtouris

158 f5eac743 Stavros Sachtouris
        :returns: (list) id,name if not detail else full info per network
159 f5eac743 Stavros Sachtouris
        """
160 6f1ec797 Stavros Sachtouris
        detail = 'detail' if detail else ''
161 6f1ec797 Stavros Sachtouris
        r = self.networks_get(command=detail)
162 fab9b17f Stavros Sachtouris
        return r.json['networks']
163 a1c50326 Giorgos Verigakis
164 a34888b4 Stavros Sachtouris
    def list_network_nics(self, network_id):
165 f5eac743 Stavros Sachtouris
        """
166 f5eac743 Stavros Sachtouris
        :param network_id: integer (str or int)
167 f5eac743 Stavros Sachtouris

168 f5eac743 Stavros Sachtouris
        :returns: (list)
169 f5eac743 Stavros Sachtouris
        """
170 a34888b4 Stavros Sachtouris
        r = self.networks_get(network_id=network_id)
171 fab9b17f Stavros Sachtouris
        return r.json['network']['attachments']
172 a34888b4 Stavros Sachtouris
173 24ff0a35 Stavros Sachtouris
    def create_network(
174 24ff0a35 Stavros Sachtouris
            self, name,
175 9d1db11e Stavros Sachtouris
            cidr=None, gateway=None, type=None, dhcp=False):
176 f5eac743 Stavros Sachtouris
        """
177 f5eac743 Stavros Sachtouris
        :param name: (str)
178 f5eac743 Stavros Sachtouris

179 f5eac743 Stavros Sachtouris
        :param cidr: (str)
180 f5eac743 Stavros Sachtouris

181 f5eac743 Stavros Sachtouris
        :param geteway: (str)
182 f5eac743 Stavros Sachtouris

183 f6f81cd3 Stavros Sachtouris
        :param type: (str) if None, will use MAC_FILTERED as default
184 f6f81cd3 Stavros Sachtouris
            Valid values: CUSTOM, IP_LESS_ROUTED, MAC_FILTERED, PHYSICAL_VLAN
185 f5eac743 Stavros Sachtouris

186 9d1db11e Stavros Sachtouris
        :param dhcp: (bool)
187 f5eac743 Stavros Sachtouris

188 f5eac743 Stavros Sachtouris
        :returns: (dict) network detailed info
189 e52840fa Stavros Sachtouris
        """
190 e52840fa Stavros Sachtouris
        net = dict(name=name)
191 e52840fa Stavros Sachtouris
        if cidr:
192 3dabe5d2 Stavros Sachtouris
            net['cidr'] = cidr
193 e52840fa Stavros Sachtouris
        if gateway:
194 3dabe5d2 Stavros Sachtouris
            net['gateway'] = gateway
195 f6f81cd3 Stavros Sachtouris
        net['type'] = type or 'MAC_FILTERED'
196 9d1db11e Stavros Sachtouris
        net['dhcp'] = True if dhcp else False
197 e52840fa Stavros Sachtouris
        req = dict(network=net)
198 6f1ec797 Stavros Sachtouris
        r = self.networks_post(json_data=req, success=202)
199 6a0b1658 Giorgos Verigakis
        return r.json['network']
200 a1c50326 Giorgos Verigakis
201 a1c50326 Giorgos Verigakis
    def get_network_details(self, network_id):
202 f5eac743 Stavros Sachtouris
        """
203 f5eac743 Stavros Sachtouris
        :param network_id: integer (str or int)
204 f5eac743 Stavros Sachtouris

205 f5eac743 Stavros Sachtouris
        :returns: (dict)
206 f5eac743 Stavros Sachtouris
        """
207 6f1ec797 Stavros Sachtouris
        r = self.networks_get(network_id=network_id)
208 6a0b1658 Giorgos Verigakis
        return r.json['network']
209 a1c50326 Giorgos Verigakis
210 a1c50326 Giorgos Verigakis
    def update_network_name(self, network_id, new_name):
211 f5eac743 Stavros Sachtouris
        """
212 f5eac743 Stavros Sachtouris
        :param network_id: integer (str or int)
213 f5eac743 Stavros Sachtouris

214 f5eac743 Stavros Sachtouris
        :param new_name: (str)
215 1b73b4c1 Stavros Sachtouris

216 1b73b4c1 Stavros Sachtouris
        :returns: (dict) response headers
217 f5eac743 Stavros Sachtouris
        """
218 6a0b1658 Giorgos Verigakis
        req = {'network': {'name': new_name}}
219 1b73b4c1 Stavros Sachtouris
        r = self.networks_put(network_id=network_id, json_data=req)
220 1b73b4c1 Stavros Sachtouris
        return r.headers
221 a1c50326 Giorgos Verigakis
222 a1c50326 Giorgos Verigakis
    def delete_network(self, network_id):
223 f5eac743 Stavros Sachtouris
        """
224 f5eac743 Stavros Sachtouris
        :param network_id: integer (str or int)
225 f5eac743 Stavros Sachtouris

226 1b73b4c1 Stavros Sachtouris
        :returns: (dict) response headers
227 1b73b4c1 Stavros Sachtouris

228 f5eac743 Stavros Sachtouris
        :raises ClientError: 421 Network in use
229 f5eac743 Stavros Sachtouris
        """
230 a34888b4 Stavros Sachtouris
        try:
231 1b73b4c1 Stavros Sachtouris
            r = self.networks_delete(network_id)
232 1b73b4c1 Stavros Sachtouris
            return r.headers
233 a34888b4 Stavros Sachtouris
        except ClientError as err:
234 a34888b4 Stavros Sachtouris
            if err.status == 421:
235 ec51b97c Stavros Sachtouris
                err.details = [
236 24ff0a35 Stavros Sachtouris
                    'Network may be still connected to at least one server']
237 08aad6db Stavros Sachtouris
            raise
238 a1c50326 Giorgos Verigakis
239 a1c50326 Giorgos Verigakis
    def connect_server(self, server_id, network_id):
240 f5eac743 Stavros Sachtouris
        """ Connect a server to a network
241 f5eac743 Stavros Sachtouris

242 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
243 f5eac743 Stavros Sachtouris

244 f5eac743 Stavros Sachtouris
        :param network_id: integer (str or int)
245 1b73b4c1 Stavros Sachtouris

246 1b73b4c1 Stavros Sachtouris
        :returns: (dict) response headers
247 f5eac743 Stavros Sachtouris
        """
248 6a0b1658 Giorgos Verigakis
        req = {'add': {'serverRef': server_id}}
249 1b73b4c1 Stavros Sachtouris
        r = self.networks_post(network_id, 'action', json_data=req)
250 1b73b4c1 Stavros Sachtouris
        return r.headers
251 a1c50326 Giorgos Verigakis
252 c7083665 Stavros Sachtouris
    def disconnect_server(self, server_id, nic_id):
253 f5eac743 Stavros Sachtouris
        """
254 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
255 f5eac743 Stavros Sachtouris

256 f5eac743 Stavros Sachtouris
        :param nic_id: (str)
257 b87ed277 Stavros Sachtouris

258 b87ed277 Stavros Sachtouris
        :returns: (int) the number of nics disconnected
259 f5eac743 Stavros Sachtouris
        """
260 2005b18e Stavros Sachtouris
        vm_nets = self.list_server_nics(server_id)
261 0e806947 Stavros Sachtouris
        num_of_disconnections = 0
262 24ff0a35 Stavros Sachtouris
        for (nic_id, network_id) in [(
263 2005b18e Stavros Sachtouris
                net['id'],
264 2005b18e Stavros Sachtouris
                net['network_id']) for net in vm_nets if nic_id == net['id']]:
265 a517ff50 Stavros Sachtouris
            req = {'remove': {'attachment': '%s' % nic_id}}
266 c2b5da2f Stavros Sachtouris
            self.networks_post(network_id, 'action', json_data=req)
267 0e806947 Stavros Sachtouris
            num_of_disconnections += 1
268 0e806947 Stavros Sachtouris
        return num_of_disconnections
269 a34888b4 Stavros Sachtouris
270 a34888b4 Stavros Sachtouris
    def disconnect_network_nics(self, netid):
271 f5eac743 Stavros Sachtouris
        """
272 f5eac743 Stavros Sachtouris
        :param netid: integer (str or int)
273 f5eac743 Stavros Sachtouris
        """
274 f5eac743 Stavros Sachtouris
        for nic in self.list_network_nics(netid):
275 a34888b4 Stavros Sachtouris
            req = dict(remove=dict(attachment=nic))
276 c2b5da2f Stavros Sachtouris
            self.networks_post(netid, 'action', json_data=req)
277 fd1f1d96 Stavros Sachtouris
278 7b2e4bf1 Stavros Sachtouris
    def _wait(
279 7b2e4bf1 Stavros Sachtouris
            self, item_id, current_status, get_status,
280 7b2e4bf1 Stavros Sachtouris
            delay=1, max_wait=100, wait_cb=None):
281 7b2e4bf1 Stavros Sachtouris
        """Wait for item while its status is current_status
282 f5eac743 Stavros Sachtouris

283 f5eac743 Stavros Sachtouris
        :param server_id: integer (str or int)
284 f5eac743 Stavros Sachtouris

285 7b2e4bf1 Stavros Sachtouris
        :param current_status: (str)
286 7b2e4bf1 Stavros Sachtouris

287 7b2e4bf1 Stavros Sachtouris
        :param get_status: (method(self, item_id)) if called, returns
288 7b2e4bf1 Stavros Sachtouris
            (status, progress %) If no way to tell progress, return None
289 f5eac743 Stavros Sachtouris

290 f5eac743 Stavros Sachtouris
        :param delay: time interval between retries
291 f5eac743 Stavros Sachtouris

292 7b2e4bf1 Stavros Sachtouris
        :param wait_cb: if set a progress bar is used to show progress
293 f5eac743 Stavros Sachtouris

294 7b2e4bf1 Stavros Sachtouris
        :returns: (str) the new mode if successful, (bool) False if timed out
295 fd1f1d96 Stavros Sachtouris
        """
296 7b2e4bf1 Stavros Sachtouris
        status, progress = get_status(self, item_id)
297 fd1f1d96 Stavros Sachtouris
298 7b2e4bf1 Stavros Sachtouris
        if wait_cb:
299 e9c73313 Stavros Sachtouris
            wait_gen = wait_cb(max_wait // delay)
300 c59aef27 Stavros Sachtouris
            wait_gen.next()
301 fd1f1d96 Stavros Sachtouris
302 e9c73313 Stavros Sachtouris
        if status != current_status:
303 e9c73313 Stavros Sachtouris
            if wait_cb:
304 e9c73313 Stavros Sachtouris
                try:
305 e9c73313 Stavros Sachtouris
                    wait_gen.next()
306 e9c73313 Stavros Sachtouris
                except Exception:
307 e9c73313 Stavros Sachtouris
                    pass
308 e9c73313 Stavros Sachtouris
            return status
309 e9c73313 Stavros Sachtouris
        old_wait = total_wait = 0
310 e9c73313 Stavros Sachtouris
311 7b2e4bf1 Stavros Sachtouris
        while status == current_status and total_wait <= max_wait:
312 7b2e4bf1 Stavros Sachtouris
            if wait_cb:
313 7b2e4bf1 Stavros Sachtouris
                try:
314 7b2e4bf1 Stavros Sachtouris
                    for i in range(total_wait - old_wait):
315 fd1f1d96 Stavros Sachtouris
                        wait_gen.next()
316 7b2e4bf1 Stavros Sachtouris
                except Exception:
317 7b2e4bf1 Stavros Sachtouris
                    break
318 7b2e4bf1 Stavros Sachtouris
            old_wait = total_wait
319 e9c73313 Stavros Sachtouris
            total_wait = progress or total_wait + 1
320 fd1f1d96 Stavros Sachtouris
            sleep(delay)
321 7b2e4bf1 Stavros Sachtouris
            status, progress = get_status(self, item_id)
322 fd1f1d96 Stavros Sachtouris
323 7b2e4bf1 Stavros Sachtouris
        if total_wait < max_wait:
324 c59aef27 Stavros Sachtouris
            if wait_cb:
325 c59aef27 Stavros Sachtouris
                try:
326 7b2e4bf1 Stavros Sachtouris
                    for i in range(max_wait):
327 c59aef27 Stavros Sachtouris
                        wait_gen.next()
328 c59aef27 Stavros Sachtouris
                except:
329 c59aef27 Stavros Sachtouris
                    pass
330 7b2e4bf1 Stavros Sachtouris
        return status if status != current_status else False
331 7b2e4bf1 Stavros Sachtouris
332 7b2e4bf1 Stavros Sachtouris
    def wait_server(
333 7b2e4bf1 Stavros Sachtouris
            self, server_id,
334 7b2e4bf1 Stavros Sachtouris
            current_status='BUILD',
335 7b2e4bf1 Stavros Sachtouris
            delay=1, max_wait=100, wait_cb=None):
336 7b2e4bf1 Stavros Sachtouris
        """Wait for server while its status is current_status
337 7b2e4bf1 Stavros Sachtouris

338 7b2e4bf1 Stavros Sachtouris
        :param server_id: integer (str or int)
339 7b2e4bf1 Stavros Sachtouris

340 7b2e4bf1 Stavros Sachtouris
        :param current_status: (str) BUILD|ACTIVE|STOPPED|DELETED|REBOOT
341 7b2e4bf1 Stavros Sachtouris

342 7b2e4bf1 Stavros Sachtouris
        :param delay: time interval between retries
343 7b2e4bf1 Stavros Sachtouris

344 c788a761 Stavros Sachtouris
        :max_wait: (int) timeout in secconds
345 c788a761 Stavros Sachtouris

346 7b2e4bf1 Stavros Sachtouris
        :param wait_cb: if set a progressbar is used to show progress
347 7b2e4bf1 Stavros Sachtouris

348 7b2e4bf1 Stavros Sachtouris
        :returns: (str) the new mode if succesfull, (bool) False if timed out
349 7b2e4bf1 Stavros Sachtouris
        """
350 7b2e4bf1 Stavros Sachtouris
351 7b2e4bf1 Stavros Sachtouris
        def get_status(self, server_id):
352 7b2e4bf1 Stavros Sachtouris
            r = self.get_server_details(server_id)
353 7b2e4bf1 Stavros Sachtouris
            return r['status'], (r.get('progress', None) if (
354 7b2e4bf1 Stavros Sachtouris
                            current_status in ('BUILD', )) else None)
355 7b2e4bf1 Stavros Sachtouris
356 7b2e4bf1 Stavros Sachtouris
        return self._wait(
357 7b2e4bf1 Stavros Sachtouris
            server_id, current_status, get_status, delay, max_wait, wait_cb)
358 7b2e4bf1 Stavros Sachtouris
359 7b2e4bf1 Stavros Sachtouris
    def wait_network(
360 7b2e4bf1 Stavros Sachtouris
            self, net_id,
361 f6822a26 Stavros Sachtouris
            current_status='PENDING', delay=1, max_wait=100, wait_cb=None):
362 7b2e4bf1 Stavros Sachtouris
        """Wait for network while its status is current_status
363 7b2e4bf1 Stavros Sachtouris

364 7b2e4bf1 Stavros Sachtouris
        :param net_id: integer (str or int)
365 7b2e4bf1 Stavros Sachtouris

366 7b2e4bf1 Stavros Sachtouris
        :param current_status: (str) PENDING | ACTIVE | DELETED
367 7b2e4bf1 Stavros Sachtouris

368 7b2e4bf1 Stavros Sachtouris
        :param delay: time interval between retries
369 7b2e4bf1 Stavros Sachtouris

370 c788a761 Stavros Sachtouris
        :max_wait: (int) timeout in secconds
371 c788a761 Stavros Sachtouris

372 7b2e4bf1 Stavros Sachtouris
        :param wait_cb: if set a progressbar is used to show progress
373 7b2e4bf1 Stavros Sachtouris

374 7b2e4bf1 Stavros Sachtouris
        :returns: (str) the new mode if succesfull, (bool) False if timed out
375 7b2e4bf1 Stavros Sachtouris
        """
376 7b2e4bf1 Stavros Sachtouris
377 7b2e4bf1 Stavros Sachtouris
        def get_status(self, net_id):
378 7b2e4bf1 Stavros Sachtouris
            r = self.get_network_details(net_id)
379 7b2e4bf1 Stavros Sachtouris
            return r['status'], None
380 7b2e4bf1 Stavros Sachtouris
381 7b2e4bf1 Stavros Sachtouris
        return self._wait(
382 7b2e4bf1 Stavros Sachtouris
            net_id, current_status, get_status, delay, max_wait, wait_cb)
383 03033b54 Stavros Sachtouris
384 c788a761 Stavros Sachtouris
    def wait_firewall(
385 c788a761 Stavros Sachtouris
            self, server_id,
386 c788a761 Stavros Sachtouris
            current_status='DISABLED', delay=1, max_wait=100, wait_cb=None):
387 c788a761 Stavros Sachtouris
        """Wait while the public network firewall status is current_status
388 c788a761 Stavros Sachtouris

389 c788a761 Stavros Sachtouris
        :param server_id: integer (str or int)
390 c788a761 Stavros Sachtouris

391 c788a761 Stavros Sachtouris
        :param current_status: (str) DISABLED | ENABLED | PROTECTED
392 c788a761 Stavros Sachtouris

393 c788a761 Stavros Sachtouris
        :param delay: time interval between retries
394 c788a761 Stavros Sachtouris

395 c788a761 Stavros Sachtouris
        :max_wait: (int) timeout in secconds
396 c788a761 Stavros Sachtouris

397 c788a761 Stavros Sachtouris
        :param wait_cb: if set a progressbar is used to show progress
398 c788a761 Stavros Sachtouris

399 c788a761 Stavros Sachtouris
        :returns: (str) the new mode if succesfull, (bool) False if timed out
400 c788a761 Stavros Sachtouris
        """
401 c788a761 Stavros Sachtouris
402 c788a761 Stavros Sachtouris
        def get_status(self, server_id):
403 c788a761 Stavros Sachtouris
            return self.get_firewall_profile(server_id), None
404 c788a761 Stavros Sachtouris
405 c788a761 Stavros Sachtouris
        return self._wait(
406 c788a761 Stavros Sachtouris
            server_id, current_status, get_status, delay, max_wait, wait_cb)
407 c788a761 Stavros Sachtouris
408 03033b54 Stavros Sachtouris
    def get_floating_ip_pools(self):
409 03033b54 Stavros Sachtouris
        """
410 03033b54 Stavros Sachtouris
        :returns: (dict) {floating_ip_pools:[{name: ...}, ...]}
411 03033b54 Stavros Sachtouris
        """
412 03033b54 Stavros Sachtouris
        r = self.floating_ip_pools_get()
413 03033b54 Stavros Sachtouris
        return r.json
414 03033b54 Stavros Sachtouris
415 03033b54 Stavros Sachtouris
    def get_floating_ips(self):
416 03033b54 Stavros Sachtouris
        """
417 97086fcd Stavros Sachtouris
        :returns: (dict) {floating_ips: [fixed_ip: , id: , ip: , pool: ]}
418 03033b54 Stavros Sachtouris
        """
419 03033b54 Stavros Sachtouris
        r = self.floating_ips_get()
420 03033b54 Stavros Sachtouris
        return r.json
421 03033b54 Stavros Sachtouris
422 03033b54 Stavros Sachtouris
    def alloc_floating_ip(self, pool=None, address=None):
423 03033b54 Stavros Sachtouris
        """
424 03033b54 Stavros Sachtouris
        :param pool: (str) pool of ips to allocate from
425 03033b54 Stavros Sachtouris

426 03033b54 Stavros Sachtouris
        :param address: (str) ip address to request
427 03033b54 Stavros Sachtouris

428 03033b54 Stavros Sachtouris
        :returns: (dict) {
429 cedde35d Stavros Sachtouris
            fixed_ip: ..., id: ..., instance_id: ..., ip: ..., pool: ...}
430 03033b54 Stavros Sachtouris
        """
431 03033b54 Stavros Sachtouris
        json_data = dict()
432 03033b54 Stavros Sachtouris
        if pool:
433 03033b54 Stavros Sachtouris
            json_data['pool'] = pool
434 2e6e03da Stavros Sachtouris
        if address:
435 2e6e03da Stavros Sachtouris
            json_data['address'] = address
436 03033b54 Stavros Sachtouris
        r = self.floating_ips_post(json_data)
437 03033b54 Stavros Sachtouris
        return r.json['floating_ip']
438 03033b54 Stavros Sachtouris
439 03033b54 Stavros Sachtouris
    def get_floating_ip(self, fip_id):
440 03033b54 Stavros Sachtouris
        """
441 03033b54 Stavros Sachtouris
        :param fip_id: (str) floating ip id
442 03033b54 Stavros Sachtouris

443 03033b54 Stavros Sachtouris
        :returns: (dict)
444 03033b54 Stavros Sachtouris
            {fixed_ip: ..., id: ..., instance_id: ..., ip: ..., pool: ...},
445 03033b54 Stavros Sachtouris

446 03033b54 Stavros Sachtouris
        :raises AssertionError: if fip_id is emtpy
447 03033b54 Stavros Sachtouris
        """
448 03033b54 Stavros Sachtouris
        assert fip_id, 'floating ip id is needed for get_floating_ip'
449 03033b54 Stavros Sachtouris
        r = self.floating_ips_get(fip_id)
450 03033b54 Stavros Sachtouris
        return r.json['floating_ip']
451 03033b54 Stavros Sachtouris
452 03033b54 Stavros Sachtouris
    def delete_floating_ip(self, fip_id=None):
453 03033b54 Stavros Sachtouris
        """
454 03033b54 Stavros Sachtouris
        :param fip_id: (str) floating ip id (if None, all ips are deleted)
455 03033b54 Stavros Sachtouris

456 03033b54 Stavros Sachtouris
        :returns: (dict) request headers
457 03033b54 Stavros Sachtouris

458 03033b54 Stavros Sachtouris
        :raises AssertionError: if fip_id is emtpy
459 03033b54 Stavros Sachtouris
        """
460 03033b54 Stavros Sachtouris
        assert fip_id, 'floating ip id is needed for delete_floating_ip'
461 03033b54 Stavros Sachtouris
        r = self.floating_ips_delete(fip_id)
462 03033b54 Stavros Sachtouris
        return r.headers
463 03033b54 Stavros Sachtouris
464 9b47150e Stavros Sachtouris
    def attach_floating_ip(self, server_id, address):
465 03033b54 Stavros Sachtouris
        """Associate the address ip to server with server_id
466 03033b54 Stavros Sachtouris

467 03033b54 Stavros Sachtouris
        :param server_id: (int)
468 03033b54 Stavros Sachtouris

469 03033b54 Stavros Sachtouris
        :param address: (str) the ip address to assign to server (vm)
470 03033b54 Stavros Sachtouris

471 03033b54 Stavros Sachtouris
        :returns: (dict) request headers
472 03033b54 Stavros Sachtouris

473 03033b54 Stavros Sachtouris
        :raises ValueError: if server_id cannot be converted to int
474 03033b54 Stavros Sachtouris

475 03033b54 Stavros Sachtouris
        :raises ValueError: if server_id is not of a int-convertable type
476 03033b54 Stavros Sachtouris

477 03033b54 Stavros Sachtouris
        :raises AssertionError: if address is emtpy
478 03033b54 Stavros Sachtouris
        """
479 03033b54 Stavros Sachtouris
        server_id = int(server_id)
480 9b47150e Stavros Sachtouris
        assert address, 'address is needed for attach_floating_ip'
481 ef2e6c9f Stavros Sachtouris
        req = dict(addFloatingIp=dict(address=address))
482 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req)
483 03033b54 Stavros Sachtouris
        return r.headers
484 03033b54 Stavros Sachtouris
485 9b47150e Stavros Sachtouris
    def detach_floating_ip(self, server_id, address):
486 03033b54 Stavros Sachtouris
        """Disassociate an address ip from the server with server_id
487 03033b54 Stavros Sachtouris

488 03033b54 Stavros Sachtouris
        :param server_id: (int)
489 03033b54 Stavros Sachtouris

490 03033b54 Stavros Sachtouris
        :param address: (str) the ip address to assign to server (vm)
491 03033b54 Stavros Sachtouris

492 03033b54 Stavros Sachtouris
        :returns: (dict) request headers
493 03033b54 Stavros Sachtouris

494 03033b54 Stavros Sachtouris
        :raises ValueError: if server_id cannot be converted to int
495 03033b54 Stavros Sachtouris

496 03033b54 Stavros Sachtouris
        :raises ValueError: if server_id is not of a int-convertable type
497 03033b54 Stavros Sachtouris

498 03033b54 Stavros Sachtouris
        :raises AssertionError: if address is emtpy
499 03033b54 Stavros Sachtouris
        """
500 03033b54 Stavros Sachtouris
        server_id = int(server_id)
501 9b47150e Stavros Sachtouris
        assert address, 'address is needed for detach_floating_ip'
502 ef2e6c9f Stavros Sachtouris
        req = dict(removeFloatingIp=dict(address=address))
503 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req)
504 03033b54 Stavros Sachtouris
        return r.headers