Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / compute.py @ ab13eafe

History | View | Annotate | Download (6.7 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 df79206f Giorgos Verigakis
from . import Client, ClientError
35 a1c50326 Giorgos Verigakis
36 a1c50326 Giorgos Verigakis
37 df79206f Giorgos Verigakis
class ComputeClient(Client):
38 d2cea1e2 Giorgos Verigakis
    """OpenStack Compute API 1.1 client"""
39 d2cea1e2 Giorgos Verigakis
    
40 df79206f Giorgos Verigakis
    def raise_for_status(self, r):
41 df79206f Giorgos Verigakis
        d = r.json
42 ab13eafe Giorgos Verigakis
        if not d:
43 ab13eafe Giorgos Verigakis
            return super(ComputeClient, self).raise_for_status(r)
44 df79206f Giorgos Verigakis
        key = d.keys()[0]
45 df79206f Giorgos Verigakis
        val = d[key]
46 df79206f Giorgos Verigakis
        message = '%s: %s' % (key, val.get('message', ''))
47 df79206f Giorgos Verigakis
        details = val.get('details', '')
48 df79206f Giorgos Verigakis
        raise ClientError(message, r.status_code, details)
49 d2cea1e2 Giorgos Verigakis
    
50 a1c50326 Giorgos Verigakis
    def list_servers(self, detail=False):
51 a1c50326 Giorgos Verigakis
        """List servers, returned detailed output if detailed is True"""
52 df79206f Giorgos Verigakis
        
53 a1c50326 Giorgos Verigakis
        path = '/servers/detail' if detail else '/servers'
54 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
55 df79206f Giorgos Verigakis
        return r.json['servers']['values']
56 a1c50326 Giorgos Verigakis
    
57 a1c50326 Giorgos Verigakis
    def get_server_details(self, server_id):
58 a1c50326 Giorgos Verigakis
        """Return detailed output on a server specified by its id"""
59 df79206f Giorgos Verigakis
        
60 df79206f Giorgos Verigakis
        path = '/servers/%s' % (server_id,)
61 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
62 df79206f Giorgos Verigakis
        return r.json['server']
63 a1c50326 Giorgos Verigakis
    
64 a1c50326 Giorgos Verigakis
    def create_server(self, name, flavor_id, image_id, personality=None):
65 a1c50326 Giorgos Verigakis
        """Submit request to create a new server
66 a1c50326 Giorgos Verigakis

67 a1c50326 Giorgos Verigakis
        The flavor_id specifies the hardware configuration to use,
68 a1c50326 Giorgos Verigakis
        the image_id specifies the OS Image to be deployed inside the new
69 a1c50326 Giorgos Verigakis
        server.
70 a1c50326 Giorgos Verigakis

71 a1c50326 Giorgos Verigakis
        The personality argument is a list of (file path, file contents)
72 a1c50326 Giorgos Verigakis
        tuples, describing files to be injected into the server upon creation.
73 a1c50326 Giorgos Verigakis

74 a1c50326 Giorgos Verigakis
        The call returns a dictionary describing the newly created server.
75 a1c50326 Giorgos Verigakis
        """
76 df79206f Giorgos Verigakis
        req = {'server': {'name': name,
77 df79206f Giorgos Verigakis
                          'flavorRef': flavor_id,
78 df79206f Giorgos Verigakis
                          'imageRef': image_id}}
79 a1c50326 Giorgos Verigakis
        if personality:
80 2394d9e1 Giorgos Verigakis
            req['server']['personality'] = personality
81 a1c50326 Giorgos Verigakis
        
82 df79206f Giorgos Verigakis
        r = self.post('/servers', json=req, success=202)
83 df79206f Giorgos Verigakis
        return r.json['server']
84 a1c50326 Giorgos Verigakis
    
85 a1c50326 Giorgos Verigakis
    def update_server_name(self, server_id, new_name):
86 a1c50326 Giorgos Verigakis
        """Update the name of the server as reported by the API.
87 a1c50326 Giorgos Verigakis

88 a1c50326 Giorgos Verigakis
        This call does not modify the hostname actually used by the server
89 a1c50326 Giorgos Verigakis
        internally.
90 a1c50326 Giorgos Verigakis
        """
91 df79206f Giorgos Verigakis
        path = '/servers/%s' % (server_id,)
92 df79206f Giorgos Verigakis
        req = {'server': {'name': new_name}}
93 df79206f Giorgos Verigakis
        self.put(path, json=req, success=204)
94 a1c50326 Giorgos Verigakis
    
95 a1c50326 Giorgos Verigakis
    def delete_server(self, server_id):
96 a1c50326 Giorgos Verigakis
        """Submit a deletion request for a server specified by id"""
97 df79206f Giorgos Verigakis
        
98 df79206f Giorgos Verigakis
        path = '/servers/%s' % (server_id,)
99 df79206f Giorgos Verigakis
        self.delete(path, success=204)
100 a1c50326 Giorgos Verigakis
    
101 a1c50326 Giorgos Verigakis
    def reboot_server(self, server_id, hard=False):
102 a1c50326 Giorgos Verigakis
        """Submit a reboot request for a server specified by id"""
103 a1c50326 Giorgos Verigakis
        
104 df79206f Giorgos Verigakis
        path = '/servers/%s/action' % (server_id,)
105 df79206f Giorgos Verigakis
        type = 'HARD' if hard else 'SOFT'
106 df79206f Giorgos Verigakis
        req = {'reboot': {'type': type}}
107 df79206f Giorgos Verigakis
        self.post(path, json=req, success=202)
108 df79206f Giorgos Verigakis
    
109 a1c50326 Giorgos Verigakis
    def get_server_metadata(self, server_id, key=None):
110 df79206f Giorgos Verigakis
        path = '/servers/%s/meta' % (server_id,)
111 a1c50326 Giorgos Verigakis
        if key:
112 a1c50326 Giorgos Verigakis
            path += '/%s' % key
113 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
114 df79206f Giorgos Verigakis
        return r.json['meta'] if key else r.json['metadata']['values']
115 a1c50326 Giorgos Verigakis
    
116 a1c50326 Giorgos Verigakis
    def create_server_metadata(self, server_id, key, val):
117 a1c50326 Giorgos Verigakis
        path = '/servers/%d/meta/%s' % (server_id, key)
118 df79206f Giorgos Verigakis
        req = {'meta': {key: val}}
119 df79206f Giorgos Verigakis
        r = self.put(path, json=req, success=201)
120 df79206f Giorgos Verigakis
        return r.json['meta']
121 a1c50326 Giorgos Verigakis
    
122 a1c50326 Giorgos Verigakis
    def update_server_metadata(self, server_id, **metadata):
123 df79206f Giorgos Verigakis
        path = '/servers/%d/meta' % (server_id,)
124 df79206f Giorgos Verigakis
        req = {'metadata': metadata}
125 df79206f Giorgos Verigakis
        r = self.post(path, json=req, success=201)
126 df79206f Giorgos Verigakis
        return r.json['metadata']
127 a1c50326 Giorgos Verigakis
    
128 a1c50326 Giorgos Verigakis
    def delete_server_metadata(self, server_id, key):
129 a1c50326 Giorgos Verigakis
        path = '/servers/%d/meta/%s' % (server_id, key)
130 df79206f Giorgos Verigakis
        self.delete(path, success=204)
131 df79206f Giorgos Verigakis
    
132 df79206f Giorgos Verigakis
    
133 a1c50326 Giorgos Verigakis
    def list_flavors(self, detail=False):
134 a1c50326 Giorgos Verigakis
        path = '/flavors/detail' if detail else '/flavors'
135 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
136 df79206f Giorgos Verigakis
        return r.json['flavors']['values']
137 a1c50326 Giorgos Verigakis
138 a1c50326 Giorgos Verigakis
    def get_flavor_details(self, flavor_id):
139 a1c50326 Giorgos Verigakis
        path = '/flavors/%d' % flavor_id
140 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
141 df79206f Giorgos Verigakis
        return r.json['flavor']
142 a1c50326 Giorgos Verigakis
    
143 a1c50326 Giorgos Verigakis
    
144 a1c50326 Giorgos Verigakis
    def list_images(self, detail=False):
145 a1c50326 Giorgos Verigakis
        path = '/images/detail' if detail else '/images'
146 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
147 df79206f Giorgos Verigakis
        return r.json['images']['values']
148 b3b32add Giorgos Verigakis
    
149 a1c50326 Giorgos Verigakis
    def get_image_details(self, image_id):
150 df79206f Giorgos Verigakis
        path = '/images/%s' % (image_id,)
151 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
152 df79206f Giorgos Verigakis
        return r.json['image']
153 b3b32add Giorgos Verigakis
    
154 a1c50326 Giorgos Verigakis
    def delete_image(self, image_id):
155 df79206f Giorgos Verigakis
        path = '/images/%s' % (image_id,)
156 df79206f Giorgos Verigakis
        self.delete(path, success=204)
157 a1c50326 Giorgos Verigakis
158 a1c50326 Giorgos Verigakis
    def get_image_metadata(self, image_id, key=None):
159 df79206f Giorgos Verigakis
        path = '/images/%s/meta' % (image_id,)
160 a1c50326 Giorgos Verigakis
        if key:
161 a1c50326 Giorgos Verigakis
            path += '/%s' % key
162 df79206f Giorgos Verigakis
        r = self.get(path, success=200)
163 df79206f Giorgos Verigakis
        return r.json['meta'] if key else r.json['metadata']['values']
164 a1c50326 Giorgos Verigakis
    
165 a1c50326 Giorgos Verigakis
    def create_image_metadata(self, image_id, key, val):
166 b3b32add Giorgos Verigakis
        path = '/images/%s/meta/%s' % (image_id, key)
167 df79206f Giorgos Verigakis
        req = {'meta': {key: val}}
168 df79206f Giorgos Verigakis
        r = self.put(path, json=req, success=201)
169 df79206f Giorgos Verigakis
        return r.json['meta']
170 a1c50326 Giorgos Verigakis
171 a1c50326 Giorgos Verigakis
    def update_image_metadata(self, image_id, **metadata):
172 df79206f Giorgos Verigakis
        path = '/images/%s/meta' % (image_id,)
173 df79206f Giorgos Verigakis
        req = {'metadata': metadata}
174 df79206f Giorgos Verigakis
        r = self.post(path, json=req, success=201)
175 df79206f Giorgos Verigakis
        return r.json['metadata']
176 a1c50326 Giorgos Verigakis
177 a1c50326 Giorgos Verigakis
    def delete_image_metadata(self, image_id, key):
178 b3b32add Giorgos Verigakis
        path = '/images/%s/meta/%s' % (image_id, key)
179 df79206f Giorgos Verigakis
        self.delete(path, success=204)