Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / cyclades / __init__.py @ cedde35d

History | View | Annotate | Download (15.2 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 68fd1bda Stavros Sachtouris
from sys import stdout
35 02846a75 Stavros Sachtouris
from time import sleep
36 02846a75 Stavros Sachtouris
37 55faa0bc Stavros Sachtouris
from kamaki.clients.cyclades.rest_api import CycladesRestClient
38 29685b9b Stavros Sachtouris
from kamaki.clients import ClientError
39 a1c50326 Giorgos Verigakis
40 3dabe5d2 Stavros Sachtouris
41 55faa0bc Stavros Sachtouris
class CycladesClient(CycladesRestClient):
42 76e7661e Stavros Sachtouris
    """Synnefo Cyclades Compute API client"""
43 2f749e6e Stavros Sachtouris
44 dbcbf446 Stavros Sachtouris
    def create_server(
45 dbcbf446 Stavros Sachtouris
            self, name, flavor_id, image_id,
46 dbcbf446 Stavros Sachtouris
            metadata=None, personality=None):
47 dbcbf446 Stavros Sachtouris
        """Submit request to create a new server
48 dbcbf446 Stavros Sachtouris

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

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

53 dbcbf446 Stavros Sachtouris
        :param image_id: (str) id denoting the OS image to run on the VM
54 dbcbf446 Stavros Sachtouris

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

57 dbcbf446 Stavros Sachtouris
        :param personality: a list of (file path, file contents) tuples,
58 dbcbf446 Stavros Sachtouris
            describing files to be injected into VM upon creation.
59 dbcbf446 Stavros Sachtouris

60 dbcbf446 Stavros Sachtouris
        :returns: a dict with the new VMs details
61 dbcbf446 Stavros Sachtouris

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

336 7b2e4bf1 Stavros Sachtouris
        :param server_id: integer (str or int)
337 7b2e4bf1 Stavros Sachtouris

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

340 7b2e4bf1 Stavros Sachtouris
        :param delay: time interval between retries
341 7b2e4bf1 Stavros Sachtouris

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

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

360 7b2e4bf1 Stavros Sachtouris
        :param net_id: integer (str or int)
361 7b2e4bf1 Stavros Sachtouris

362 7b2e4bf1 Stavros Sachtouris
        :param current_status: (str) PENDING | ACTIVE | DELETED
363 7b2e4bf1 Stavros Sachtouris

364 7b2e4bf1 Stavros Sachtouris
        :param delay: time interval between retries
365 7b2e4bf1 Stavros Sachtouris

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

368 7b2e4bf1 Stavros Sachtouris
        :returns: (str) the new mode if succesfull, (bool) False if timed out
369 7b2e4bf1 Stavros Sachtouris
        """
370 7b2e4bf1 Stavros Sachtouris
371 7b2e4bf1 Stavros Sachtouris
        def get_status(self, net_id):
372 7b2e4bf1 Stavros Sachtouris
            r = self.get_network_details(net_id)
373 7b2e4bf1 Stavros Sachtouris
            return r['status'], None
374 7b2e4bf1 Stavros Sachtouris
375 7b2e4bf1 Stavros Sachtouris
        return self._wait(
376 7b2e4bf1 Stavros Sachtouris
            net_id, current_status, get_status, delay, max_wait, wait_cb)
377 03033b54 Stavros Sachtouris
378 03033b54 Stavros Sachtouris
    def get_floating_ip_pools(self):
379 03033b54 Stavros Sachtouris
        """
380 03033b54 Stavros Sachtouris
        :returns: (dict) {floating_ip_pools:[{name: ...}, ...]}
381 03033b54 Stavros Sachtouris
        """
382 03033b54 Stavros Sachtouris
        r = self.floating_ip_pools_get()
383 03033b54 Stavros Sachtouris
        return r.json
384 03033b54 Stavros Sachtouris
385 03033b54 Stavros Sachtouris
    def get_floating_ips(self):
386 03033b54 Stavros Sachtouris
        """
387 03033b54 Stavros Sachtouris
        :returns: (dict) {floating_ips:[
388 03033b54 Stavros Sachtouris
            {fixed_ip: ..., id: ..., instance_id: ..., ip: ..., pool: ...},
389 03033b54 Stavros Sachtouris
            ... ]}
390 03033b54 Stavros Sachtouris
        """
391 03033b54 Stavros Sachtouris
        r = self.floating_ips_get()
392 03033b54 Stavros Sachtouris
        return r.json
393 03033b54 Stavros Sachtouris
394 03033b54 Stavros Sachtouris
    def alloc_floating_ip(self, pool=None, address=None):
395 03033b54 Stavros Sachtouris
        """
396 03033b54 Stavros Sachtouris
        :param pool: (str) pool of ips to allocate from
397 03033b54 Stavros Sachtouris

398 03033b54 Stavros Sachtouris
        :param address: (str) ip address to request
399 03033b54 Stavros Sachtouris

400 03033b54 Stavros Sachtouris
        :returns: (dict) {
401 cedde35d Stavros Sachtouris
            fixed_ip: ..., id: ..., instance_id: ..., ip: ..., pool: ...}
402 03033b54 Stavros Sachtouris
        """
403 03033b54 Stavros Sachtouris
        json_data = dict()
404 03033b54 Stavros Sachtouris
        if pool:
405 03033b54 Stavros Sachtouris
            json_data['pool'] = pool
406 03033b54 Stavros Sachtouris
            if address:
407 03033b54 Stavros Sachtouris
                json_data['address'] = address
408 03033b54 Stavros Sachtouris
        r = self.floating_ips_post(json_data)
409 03033b54 Stavros Sachtouris
        return r.json['floating_ip']
410 03033b54 Stavros Sachtouris
411 03033b54 Stavros Sachtouris
    def get_floating_ip(self, fip_id):
412 03033b54 Stavros Sachtouris
        """
413 03033b54 Stavros Sachtouris
        :param fip_id: (str) floating ip id
414 03033b54 Stavros Sachtouris

415 03033b54 Stavros Sachtouris
        :returns: (dict)
416 03033b54 Stavros Sachtouris
            {fixed_ip: ..., id: ..., instance_id: ..., ip: ..., pool: ...},
417 03033b54 Stavros Sachtouris

418 03033b54 Stavros Sachtouris
        :raises AssertionError: if fip_id is emtpy
419 03033b54 Stavros Sachtouris
        """
420 03033b54 Stavros Sachtouris
        assert fip_id, 'floating ip id is needed for get_floating_ip'
421 03033b54 Stavros Sachtouris
        r = self.floating_ips_get(fip_id)
422 03033b54 Stavros Sachtouris
        return r.json['floating_ip']
423 03033b54 Stavros Sachtouris
424 03033b54 Stavros Sachtouris
    def delete_floating_ip(self, fip_id=None):
425 03033b54 Stavros Sachtouris
        """
426 03033b54 Stavros Sachtouris
        :param fip_id: (str) floating ip id (if None, all ips are deleted)
427 03033b54 Stavros Sachtouris

428 03033b54 Stavros Sachtouris
        :returns: (dict) request headers
429 03033b54 Stavros Sachtouris

430 03033b54 Stavros Sachtouris
        :raises AssertionError: if fip_id is emtpy
431 03033b54 Stavros Sachtouris
        """
432 03033b54 Stavros Sachtouris
        assert fip_id, 'floating ip id is needed for delete_floating_ip'
433 03033b54 Stavros Sachtouris
        r = self.floating_ips_delete(fip_id)
434 03033b54 Stavros Sachtouris
        return r.headers
435 03033b54 Stavros Sachtouris
436 9b47150e Stavros Sachtouris
    def attach_floating_ip(self, server_id, address):
437 03033b54 Stavros Sachtouris
        """Associate the address ip to server with server_id
438 03033b54 Stavros Sachtouris

439 03033b54 Stavros Sachtouris
        :param server_id: (int)
440 03033b54 Stavros Sachtouris

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

443 03033b54 Stavros Sachtouris
        :returns: (dict) request headers
444 03033b54 Stavros Sachtouris

445 03033b54 Stavros Sachtouris
        :raises ValueError: if server_id cannot be converted to int
446 03033b54 Stavros Sachtouris

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

449 03033b54 Stavros Sachtouris
        :raises AssertionError: if address is emtpy
450 03033b54 Stavros Sachtouris
        """
451 03033b54 Stavros Sachtouris
        server_id = int(server_id)
452 9b47150e Stavros Sachtouris
        assert address, 'address is needed for attach_floating_ip'
453 ef2e6c9f Stavros Sachtouris
        req = dict(addFloatingIp=dict(address=address))
454 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req)
455 03033b54 Stavros Sachtouris
        return r.headers
456 03033b54 Stavros Sachtouris
457 9b47150e Stavros Sachtouris
    def detach_floating_ip(self, server_id, address):
458 03033b54 Stavros Sachtouris
        """Disassociate an address ip from the server with server_id
459 03033b54 Stavros Sachtouris

460 03033b54 Stavros Sachtouris
        :param server_id: (int)
461 03033b54 Stavros Sachtouris

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

464 03033b54 Stavros Sachtouris
        :returns: (dict) request headers
465 03033b54 Stavros Sachtouris

466 03033b54 Stavros Sachtouris
        :raises ValueError: if server_id cannot be converted to int
467 03033b54 Stavros Sachtouris

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

470 03033b54 Stavros Sachtouris
        :raises AssertionError: if address is emtpy
471 03033b54 Stavros Sachtouris
        """
472 03033b54 Stavros Sachtouris
        server_id = int(server_id)
473 9b47150e Stavros Sachtouris
        assert address, 'address is needed for detach_floating_ip'
474 ef2e6c9f Stavros Sachtouris
        req = dict(removeFloatingIp=dict(address=address))
475 ef2e6c9f Stavros Sachtouris
        r = self.servers_action_post(server_id, json_data=req)
476 03033b54 Stavros Sachtouris
        return r.headers