compute.py 6.59 KB
Newer Older
Giorgos Verigakis's avatar
Giorgos Verigakis committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Copyright 2011 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
#   1. Redistributions of source code must retain the above
#      copyright notice, this list of conditions and the following
#      disclaimer.
#
#   2. Redistributions in binary form must reproduce the above
#      copyright notice, this list of conditions and the following
#      disclaimer in the documentation and/or other materials
#      provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.

Giorgos Verigakis's avatar
Giorgos Verigakis committed
34
from . import Client, ClientError
Giorgos Verigakis's avatar
Giorgos Verigakis committed
35
36


Giorgos Verigakis's avatar
Giorgos Verigakis committed
37
class ComputeClient(Client):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
38
39
    """OpenStack Compute API 1.1 client"""
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
40
41
42
43
44
45
46
    def raise_for_status(self, r):
        d = r.json
        key = d.keys()[0]
        val = d[key]
        message = '%s: %s' % (key, val.get('message', ''))
        details = val.get('details', '')
        raise ClientError(message, r.status_code, details)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
47
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
48
49
    def list_servers(self, detail=False):
        """List servers, returned detailed output if detailed is True"""
Giorgos Verigakis's avatar
Giorgos Verigakis committed
50
        
Giorgos Verigakis's avatar
Giorgos Verigakis committed
51
        path = '/servers/detail' if detail else '/servers'
Giorgos Verigakis's avatar
Giorgos Verigakis committed
52
53
        r = self.get(path, success=200)
        return r.json['servers']['values']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
54
55
56
    
    def get_server_details(self, server_id):
        """Return detailed output on a server specified by its id"""
Giorgos Verigakis's avatar
Giorgos Verigakis committed
57
58
59
60
        
        path = '/servers/%s' % (server_id,)
        r = self.get(path, success=200)
        return r.json['server']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
61
62
63
64
65
66
67
68
69
70
71
72
73
    
    def create_server(self, name, flavor_id, image_id, personality=None):
        """Submit request to create a new server

        The flavor_id specifies the hardware configuration to use,
        the image_id specifies the OS Image to be deployed inside the new
        server.

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

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

        This call does not modify the hostname actually used by the server
        internally.
        """
Giorgos Verigakis's avatar
Giorgos Verigakis committed
89
90
91
        path = '/servers/%s' % (server_id,)
        req = {'server': {'name': new_name}}
        self.put(path, json=req, success=204)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
92
93
94
    
    def delete_server(self, server_id):
        """Submit a deletion request for a server specified by id"""
Giorgos Verigakis's avatar
Giorgos Verigakis committed
95
96
97
        
        path = '/servers/%s' % (server_id,)
        self.delete(path, success=204)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
98
99
100
101
    
    def reboot_server(self, server_id, hard=False):
        """Submit a reboot request for a server specified by id"""
        
Giorgos Verigakis's avatar
Giorgos Verigakis committed
102
103
104
105
106
        path = '/servers/%s/action' % (server_id,)
        type = 'HARD' if hard else 'SOFT'
        req = {'reboot': {'type': type}}
        self.post(path, json=req, success=202)
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
107
    def get_server_metadata(self, server_id, key=None):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
108
        path = '/servers/%s/meta' % (server_id,)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
109
110
        if key:
            path += '/%s' % key
Giorgos Verigakis's avatar
Giorgos Verigakis committed
111
112
        r = self.get(path, success=200)
        return r.json['meta'] if key else r.json['metadata']['values']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
113
114
115
    
    def create_server_metadata(self, server_id, key, val):
        path = '/servers/%d/meta/%s' % (server_id, key)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
116
117
118
        req = {'meta': {key: val}}
        r = self.put(path, json=req, success=201)
        return r.json['meta']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
119
120
    
    def update_server_metadata(self, server_id, **metadata):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
121
122
123
124
        path = '/servers/%d/meta' % (server_id,)
        req = {'metadata': metadata}
        r = self.post(path, json=req, success=201)
        return r.json['metadata']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
125
126
127
    
    def delete_server_metadata(self, server_id, key):
        path = '/servers/%d/meta/%s' % (server_id, key)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
128
129
130
        self.delete(path, success=204)
    
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
131
132
    def list_flavors(self, detail=False):
        path = '/flavors/detail' if detail else '/flavors'
Giorgos Verigakis's avatar
Giorgos Verigakis committed
133
134
        r = self.get(path, success=200)
        return r.json['flavors']['values']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
135
136
137

    def get_flavor_details(self, flavor_id):
        path = '/flavors/%d' % flavor_id
Giorgos Verigakis's avatar
Giorgos Verigakis committed
138
139
        r = self.get(path, success=200)
        return r.json['flavor']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
140
141
142
143
    
    
    def list_images(self, detail=False):
        path = '/images/detail' if detail else '/images'
Giorgos Verigakis's avatar
Giorgos Verigakis committed
144
145
        r = self.get(path, success=200)
        return r.json['images']['values']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
146
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
147
    def get_image_details(self, image_id):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
148
149
150
        path = '/images/%s' % (image_id,)
        r = self.get(path, success=200)
        return r.json['image']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
151
    
Giorgos Verigakis's avatar
Giorgos Verigakis committed
152
    def delete_image(self, image_id):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
153
154
        path = '/images/%s' % (image_id,)
        self.delete(path, success=204)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
155
156

    def get_image_metadata(self, image_id, key=None):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
157
        path = '/images/%s/meta' % (image_id,)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
158
159
        if key:
            path += '/%s' % key
Giorgos Verigakis's avatar
Giorgos Verigakis committed
160
161
        r = self.get(path, success=200)
        return r.json['meta'] if key else r.json['metadata']['values']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
162
163
    
    def create_image_metadata(self, image_id, key, val):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
164
        path = '/images/%s/meta/%s' % (image_id, key)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
165
166
167
        req = {'meta': {key: val}}
        r = self.put(path, json=req, success=201)
        return r.json['meta']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
168
169

    def update_image_metadata(self, image_id, **metadata):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
170
171
172
173
        path = '/images/%s/meta' % (image_id,)
        req = {'metadata': metadata}
        r = self.post(path, json=req, success=201)
        return r.json['metadata']
Giorgos Verigakis's avatar
Giorgos Verigakis committed
174
175

    def delete_image_metadata(self, image_id, key):
Giorgos Verigakis's avatar
Giorgos Verigakis committed
176
        path = '/images/%s/meta/%s' % (image_id, key)
Giorgos Verigakis's avatar
Giorgos Verigakis committed
177
        self.delete(path, success=204)