Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / compute.py @ 8f5d38df

History | View | Annotate | Download (9.1 kB)

1 a1c50326 Giorgos Verigakis
# Copyright 2011 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 606fe15f Stavros Sachtouris
from kamaki.clients import ClientError
35 606fe15f Stavros Sachtouris
from kamaki.clients.compute_rest_api import ComputeClientApi
36 c270fe96 Stavros Sachtouris
from kamaki.clients.utils import path4url
37 a1c50326 Giorgos Verigakis
38 3dabe5d2 Stavros Sachtouris
39 606fe15f Stavros Sachtouris
class ComputeClient(ComputeClientApi):
40 d2cea1e2 Giorgos Verigakis
    """OpenStack Compute API 1.1 client"""
41 2f749e6e Stavros Sachtouris
42 a1c50326 Giorgos Verigakis
    def list_servers(self, detail=False):
43 a2ef112e Stavros Sachtouris
        """
44 a2ef112e Stavros Sachtouris
        :param detail: if true, append full server details to each item
45 a2ef112e Stavros Sachtouris

46 a2ef112e Stavros Sachtouris
        :returns: list of server ids and names
47 a2ef112e Stavros Sachtouris
        """
48 6666f3b3 Stavros Sachtouris
        detail = 'detail' if detail else ''
49 6666f3b3 Stavros Sachtouris
        r = self.servers_get(command=detail)
50 6a0b1658 Giorgos Verigakis
        return r.json['servers']['values']
51 3dabe5d2 Stavros Sachtouris
52 c92d159d Stavros Sachtouris
    def get_server_details(self, server_id, **kwargs):
53 a2ef112e Stavros Sachtouris
        """Return detailed info for a server
54 a2ef112e Stavros Sachtouris

55 a2ef112e Stavros Sachtouris
        :param server_id: integer (int or str)
56 a2ef112e Stavros Sachtouris

57 a2ef112e Stavros Sachtouris
        :returns: dict with server details
58 a2ef112e Stavros Sachtouris
        """
59 c92d159d Stavros Sachtouris
        r = self.servers_get(server_id, **kwargs)
60 6a0b1658 Giorgos Verigakis
        return r.json['server']
61 3dabe5d2 Stavros Sachtouris
62 a1c50326 Giorgos Verigakis
    def create_server(self, name, flavor_id, image_id, personality=None):
63 a1c50326 Giorgos Verigakis
        """Submit request to create a new server
64 a1c50326 Giorgos Verigakis

65 a2ef112e Stavros Sachtouris
        :param name: (str)
66 a2ef112e Stavros Sachtouris

67 a2ef112e Stavros Sachtouris
        :param flavor_id: integer id denoting a preset hardware configuration
68 a2ef112e Stavros Sachtouris

69 a2ef112e Stavros Sachtouris
        :param image_id: (str) id denoting the OS image to run on the VM
70 a1c50326 Giorgos Verigakis

71 a2ef112e Stavros Sachtouris
        :param personality: a list of (file path, file contents) tuples,
72 a2ef112e Stavros Sachtouris
            describing files to be injected into VM upon creation.
73 a1c50326 Giorgos Verigakis

74 a2ef112e Stavros Sachtouris
        :returns: a dict with the new VMs details
75 a2ef112e Stavros Sachtouris

76 a2ef112e Stavros Sachtouris
        :raises ClientError: wraps request errors
77 a1c50326 Giorgos Verigakis
        """
78 6a0b1658 Giorgos Verigakis
        req = {'server': {'name': name,
79 6a0b1658 Giorgos Verigakis
                          'flavorRef': flavor_id,
80 6a0b1658 Giorgos Verigakis
                          'imageRef': image_id}}
81 ae3c77f9 Stavros Sachtouris
82 ae3c77f9 Stavros Sachtouris
        image = self.get_image_details(image_id)
83 ae3c77f9 Stavros Sachtouris
        img_meta = image['metadata']['values']
84 ae3c77f9 Stavros Sachtouris
        metadata = {}
85 ae3c77f9 Stavros Sachtouris
        for key in ('os', 'users'):
86 ae3c77f9 Stavros Sachtouris
            try:
87 ae3c77f9 Stavros Sachtouris
                metadata[key] = img_meta[key]
88 ae3c77f9 Stavros Sachtouris
            except KeyError:
89 ae3c77f9 Stavros Sachtouris
                pass
90 ae3c77f9 Stavros Sachtouris
        if metadata:
91 ae3c77f9 Stavros Sachtouris
            req['server']['metadata'] = metadata
92 ae3c77f9 Stavros Sachtouris
93 a1c50326 Giorgos Verigakis
        if personality:
94 c4922a05 Giorgos Verigakis
            req['server']['personality'] = personality
95 3dabe5d2 Stavros Sachtouris
96 486e55f4 Stavros Sachtouris
        try:
97 486e55f4 Stavros Sachtouris
            r = self.servers_post(json_data=req)
98 486e55f4 Stavros Sachtouris
        except ClientError as err:
99 486e55f4 Stavros Sachtouris
            try:
100 de73876b Stavros Sachtouris
                if isinstance(err.details, list):
101 de73876b Stavros Sachtouris
                    tmp_err = err.details
102 de73876b Stavros Sachtouris
                else:
103 a517ff50 Stavros Sachtouris
                    errd = '%s' % err.details
104 a517ff50 Stavros Sachtouris
                    tmp_err = errd.split(',')
105 3dabe5d2 Stavros Sachtouris
                tmp_err = tmp_err[0].split(':')
106 3dabe5d2 Stavros Sachtouris
                tmp_err = tmp_err[2].split('"')
107 3dabe5d2 Stavros Sachtouris
                err.message = tmp_err[1]
108 486e55f4 Stavros Sachtouris
            finally:
109 486e55f4 Stavros Sachtouris
                raise err
110 6a0b1658 Giorgos Verigakis
        return r.json['server']
111 3dabe5d2 Stavros Sachtouris
112 a1c50326 Giorgos Verigakis
    def update_server_name(self, server_id, new_name):
113 a2ef112e Stavros Sachtouris
        """Update the name of the server as reported by the API (does not
114 a2ef112e Stavros Sachtouris
            modify the hostname used inside the VM)
115 a2ef112e Stavros Sachtouris

116 a2ef112e Stavros Sachtouris
        :param server_id: integer (str or int)
117 a1c50326 Giorgos Verigakis

118 8194b51b Stavros Sachtouris
        :param new_name: (str)
119 a1c50326 Giorgos Verigakis
        """
120 6a0b1658 Giorgos Verigakis
        req = {'server': {'name': new_name}}
121 6ce9fc72 Stavros Sachtouris
        r = self.servers_put(server_id, json_data=req)
122 6ce9fc72 Stavros Sachtouris
        r.release()
123 3dabe5d2 Stavros Sachtouris
124 a1c50326 Giorgos Verigakis
    def delete_server(self, server_id):
125 a2ef112e Stavros Sachtouris
        """Submit a deletion request for a server specified by id
126 a2ef112e Stavros Sachtouris

127 a2ef112e Stavros Sachtouris
        :param server_id: integer (str or int)
128 a2ef112e Stavros Sachtouris
        """
129 6ce9fc72 Stavros Sachtouris
        r = self.servers_delete(server_id)
130 6ce9fc72 Stavros Sachtouris
        r.release()
131 6ce9fc72 Stavros Sachtouris
132 a1c50326 Giorgos Verigakis
    def reboot_server(self, server_id, hard=False):
133 a2ef112e Stavros Sachtouris
        """
134 a2ef112e Stavros Sachtouris
        :param server_id: integer (str or int)
135 a2ef112e Stavros Sachtouris

136 a2ef112e Stavros Sachtouris
        :param hard: perform a hard reboot if true, soft reboot otherwise
137 a2ef112e Stavros Sachtouris
        """
138 e711efe2 Stavros Sachtouris
        boot_type = 'HARD' if hard else 'SOFT'
139 e711efe2 Stavros Sachtouris
        req = {'reboot': {'type': boot_type}}
140 6ce9fc72 Stavros Sachtouris
        r = self.servers_post(server_id, 'action', json_data=req)
141 6ce9fc72 Stavros Sachtouris
        r.release()
142 3dabe5d2 Stavros Sachtouris
143 6666f3b3 Stavros Sachtouris
    def get_server_metadata(self, server_id, key=''):
144 a2ef112e Stavros Sachtouris
        """
145 a2ef112e Stavros Sachtouris
        :param server_id: integer (str or int)
146 a2ef112e Stavros Sachtouris

147 a2ef112e Stavros Sachtouris
        :param key: (str) the metadatum key (all metadata if not given)
148 a2ef112e Stavros Sachtouris

149 a2ef112e Stavros Sachtouris
        :returns: a key:val dict of requests metadata
150 a2ef112e Stavros Sachtouris
        """
151 6666f3b3 Stavros Sachtouris
        command = path4url('meta', key)
152 6666f3b3 Stavros Sachtouris
        r = self.servers_get(server_id, command)
153 8f5d38df Stavros Sachtouris
        return r.json['meta'] if key else r.json['metadata']['values']
154 3dabe5d2 Stavros Sachtouris
155 a1c50326 Giorgos Verigakis
    def create_server_metadata(self, server_id, key, val):
156 a2ef112e Stavros Sachtouris
        """
157 a2ef112e Stavros Sachtouris
        :param server_id: integer (str or int)
158 a2ef112e Stavros Sachtouris

159 a2ef112e Stavros Sachtouris
        :param key: (str)
160 a2ef112e Stavros Sachtouris

161 a2ef112e Stavros Sachtouris
        :param val: (str)
162 a2ef112e Stavros Sachtouris

163 a2ef112e Stavros Sachtouris
        :returns: dict of updated key:val metadata
164 a2ef112e Stavros Sachtouris
        """
165 6a0b1658 Giorgos Verigakis
        req = {'meta': {key: val}}
166 de73876b Stavros Sachtouris
        r = self.servers_put(
167 de73876b Stavros Sachtouris
            server_id,
168 3dabe5d2 Stavros Sachtouris
            'meta/' + key,
169 3dabe5d2 Stavros Sachtouris
            json_data=req,
170 3dabe5d2 Stavros Sachtouris
            success=201)
171 6a0b1658 Giorgos Verigakis
        return r.json['meta']
172 3dabe5d2 Stavros Sachtouris
173 a1c50326 Giorgos Verigakis
    def update_server_metadata(self, server_id, **metadata):
174 a2ef112e Stavros Sachtouris
        """
175 a2ef112e Stavros Sachtouris
        :param server_id: integer (str or int)
176 a2ef112e Stavros Sachtouris

177 a2ef112e Stavros Sachtouris
        :param metadata: dict of key:val metadata
178 a2ef112e Stavros Sachtouris

179 a2ef112e Stavros Sachtouris
        :returns: dict of updated key:val metadata
180 a2ef112e Stavros Sachtouris
        """
181 6a0b1658 Giorgos Verigakis
        req = {'metadata': metadata}
182 6666f3b3 Stavros Sachtouris
        r = self.servers_post(server_id, 'meta', json_data=req, success=201)
183 6a0b1658 Giorgos Verigakis
        return r.json['metadata']
184 3dabe5d2 Stavros Sachtouris
185 a1c50326 Giorgos Verigakis
    def delete_server_metadata(self, server_id, key):
186 a2ef112e Stavros Sachtouris
        """
187 a2ef112e Stavros Sachtouris
        :param server_id: integer (str or int)
188 a2ef112e Stavros Sachtouris

189 a2ef112e Stavros Sachtouris
        :param key: (str) the meta key
190 a2ef112e Stavros Sachtouris
        """
191 3dabe5d2 Stavros Sachtouris
        r = self.servers_delete(server_id, 'meta/' + key)
192 6ce9fc72 Stavros Sachtouris
        r.release()
193 6666f3b3 Stavros Sachtouris
194 a2ef112e Stavros Sachtouris
    def list_flavors(self, detail=False):
195 6666f3b3 Stavros Sachtouris
        """
196 a2ef112e Stavros Sachtouris
        :param detail: (bool) detailed flavor info if set, short if not
197 6666f3b3 Stavros Sachtouris

198 a2ef112e Stavros Sachtouris
        :returns: (dict) flavor info
199 a2ef112e Stavros Sachtouris
        """
200 8f5d38df Stavros Sachtouris
        r = self.flavors_get(command='detail' if detail else '')
201 6a0b1658 Giorgos Verigakis
        return r.json['flavors']['values']
202 a1c50326 Giorgos Verigakis
203 a1c50326 Giorgos Verigakis
    def get_flavor_details(self, flavor_id):
204 a2ef112e Stavros Sachtouris
        """
205 a2ef112e Stavros Sachtouris
        :param flavor_id: integer (str or int)
206 a2ef112e Stavros Sachtouris

207 a2ef112e Stavros Sachtouris
        :returns: dict
208 a2ef112e Stavros Sachtouris
        """
209 6666f3b3 Stavros Sachtouris
        r = self.flavors_get(flavor_id)
210 6a0b1658 Giorgos Verigakis
        return r.json['flavor']
211 6666f3b3 Stavros Sachtouris
212 a1c50326 Giorgos Verigakis
    def list_images(self, detail=False):
213 a2ef112e Stavros Sachtouris
        """
214 a2ef112e Stavros Sachtouris
        :param detail: (bool) detailed info if set, short if not
215 a2ef112e Stavros Sachtouris

216 a2ef112e Stavros Sachtouris
        :returns: dict id,name + full info if detail
217 a2ef112e Stavros Sachtouris
        """
218 14af08c0 Stavros Sachtouris
        detail = 'detail' if detail else ''
219 6666f3b3 Stavros Sachtouris
        r = self.images_get(command=detail)
220 6a0b1658 Giorgos Verigakis
        return r.json['images']['values']
221 3dabe5d2 Stavros Sachtouris
222 71286858 Stavros Sachtouris
    def get_image_details(self, image_id, **kwargs):
223 a2ef112e Stavros Sachtouris
        """
224 a2ef112e Stavros Sachtouris
        :param image_id: integer (str or int)
225 a2ef112e Stavros Sachtouris

226 a2ef112e Stavros Sachtouris
        :returns: dict
227 a2ef112e Stavros Sachtouris

228 a2ef112e Stavros Sachtouris
        :raises ClientError: 404 if image not available
229 a2ef112e Stavros Sachtouris
        """
230 71286858 Stavros Sachtouris
        r = self.images_get(image_id, **kwargs)
231 71286858 Stavros Sachtouris
        try:
232 71286858 Stavros Sachtouris
            return r.json['image']
233 71286858 Stavros Sachtouris
        except KeyError:
234 de73876b Stavros Sachtouris
            raise ClientError('Image not available', 404, details=[
235 de73876b Stavros Sachtouris
                'Image %d not found or not accessible'])
236 3dabe5d2 Stavros Sachtouris
237 a1c50326 Giorgos Verigakis
    def delete_image(self, image_id):
238 a2ef112e Stavros Sachtouris
        """
239 a2ef112e Stavros Sachtouris
        :param image_id: (str)
240 a2ef112e Stavros Sachtouris
        """
241 6ce9fc72 Stavros Sachtouris
        r = self.images_delete(image_id)
242 6ce9fc72 Stavros Sachtouris
        r.release()
243 6666f3b3 Stavros Sachtouris
244 6666f3b3 Stavros Sachtouris
    def get_image_metadata(self, image_id, key=''):
245 a2ef112e Stavros Sachtouris
        """
246 a2ef112e Stavros Sachtouris
        :param image_id: (str)
247 a2ef112e Stavros Sachtouris

248 a2ef112e Stavros Sachtouris
        :param key: (str) the metadatum key
249 a2ef112e Stavros Sachtouris

250 a2ef112e Stavros Sachtouris
        :returns (dict) metadata if key not set, specific metadatum otherwise
251 a2ef112e Stavros Sachtouris
        """
252 6666f3b3 Stavros Sachtouris
        command = path4url('meta', key)
253 6666f3b3 Stavros Sachtouris
        r = self.images_get(image_id, command)
254 a2ef112e Stavros Sachtouris
        return r.json['meta'] if key else r.json['metadata']['values']
255 3dabe5d2 Stavros Sachtouris
256 a1c50326 Giorgos Verigakis
    def create_image_metadata(self, image_id, key, val):
257 a2ef112e Stavros Sachtouris
        """
258 a2ef112e Stavros Sachtouris
        :param image_id: integer (str or int)
259 a2ef112e Stavros Sachtouris

260 a2ef112e Stavros Sachtouris
        :param key: (str) metadatum key
261 a2ef112e Stavros Sachtouris

262 a2ef112e Stavros Sachtouris
        :param val: (str) metadatum value
263 a2ef112e Stavros Sachtouris

264 a2ef112e Stavros Sachtouris
        :returns: (dict) updated metadata
265 a2ef112e Stavros Sachtouris
        """
266 6a0b1658 Giorgos Verigakis
        req = {'meta': {key: val}}
267 3dabe5d2 Stavros Sachtouris
        r = self.images_put(image_id, 'meta/' + key, json_data=req)
268 6a0b1658 Giorgos Verigakis
        return r.json['meta']
269 a1c50326 Giorgos Verigakis
270 a1c50326 Giorgos Verigakis
    def update_image_metadata(self, image_id, **metadata):
271 a2ef112e Stavros Sachtouris
        """
272 a2ef112e Stavros Sachtouris
        :param image_id: (str)
273 a2ef112e Stavros Sachtouris

274 a2ef112e Stavros Sachtouris
        :param metadata: dict
275 a2ef112e Stavros Sachtouris

276 a2ef112e Stavros Sachtouris
        :returns: updated metadata
277 a2ef112e Stavros Sachtouris
        """
278 6a0b1658 Giorgos Verigakis
        req = {'metadata': metadata}
279 3dabe5d2 Stavros Sachtouris
        r = self.images_post(image_id, 'meta', json_data=req)
280 6a0b1658 Giorgos Verigakis
        return r.json['metadata']
281 a1c50326 Giorgos Verigakis
282 a1c50326 Giorgos Verigakis
    def delete_image_metadata(self, image_id, key):
283 a2ef112e Stavros Sachtouris
        """
284 a2ef112e Stavros Sachtouris
        :param image_id: (str)
285 a2ef112e Stavros Sachtouris

286 a2ef112e Stavros Sachtouris
        :param key: (str) metadatum key
287 a2ef112e Stavros Sachtouris
        """
288 6666f3b3 Stavros Sachtouris
        command = path4url('meta', key)
289 6ce9fc72 Stavros Sachtouris
        r = self.images_delete(image_id, command)
290 6ce9fc72 Stavros Sachtouris
        r.release()