2
# Copyright 2014, Rackspace, US, Inc.
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
"""API over the nova service.
18
from django.utils import http as utils_http
19
from django.views import generic
21
from openstack_dashboard import api
22
from openstack_dashboard.api.rest import urls
23
from openstack_dashboard.api.rest import utils as rest_utils
27
class Keypairs(generic.View):
28
"""API for nova keypairs.
30
url_regex = r'nova/keypairs/$'
33
def get(self, request):
34
"""Get a list of keypairs associated with the current logged-in
37
The listing result is an object with property "items".
39
result = api.nova.keypair_list(request)
40
return {'items': [u.to_dict() for u in result]}
42
@rest_utils.ajax(data_required=True)
43
def post(self, request):
46
Create a keypair using the parameters supplied in the POST
47
application/json object. The parameters are:
49
:param name: the name to give the keypair
50
:param public_key: (optional) a key to import
52
This returns the new keypair object on success.
54
if 'public_key' in request.DATA:
55
new = api.nova.keypair_import(request, request.DATA['name'],
56
request.DATA['public_key'])
58
new = api.nova.keypair_create(request, request.DATA['name'])
59
return rest_utils.CreatedResponse(
60
'/api/nova/keypairs/%s' % utils_http.urlquote(new.name),
66
class AvailabilityZones(generic.View):
67
"""API for nova availability zones.
69
url_regex = r'nova/availzones/$'
72
def get(self, request):
73
"""Get a list of availability zones.
75
The following get parameters may be passed in the GET
78
:param detailed: If this equals "true" then the result will
81
The listing result is an object with property "items".
83
detailed = request.GET.get('detailed') == 'true'
84
result = api.nova.availability_zone_list(request, detailed)
85
return {'items': [u.to_dict() for u in result]}
89
class Limits(generic.View):
90
"""API for nova limits.
92
url_regex = r'nova/limits/$'
95
def get(self, request):
96
"""Get an object describing the current project limits.
98
Note: the Horizon API doesn't support any other project (tenant) but
99
the underlying client does...
101
The following get parameters may be passed in the GET
104
:param reserved: This may be set to "true" but it's not
105
clear what the result of that is.
107
The result is an object with limits as properties.
109
reserved = request.GET.get('reserved') == 'true'
110
result = api.nova.tenant_absolute_limits(request, reserved)
115
class Servers(generic.View):
116
"""API over all servers.
118
url_regex = r'nova/servers/$'
121
'block_device_mapping', 'block_device_mapping_v2', 'nics', 'meta',
122
'availability_zone', 'instance_count', 'admin_pass', 'disk_config',
126
@rest_utils.ajax(data_required=True)
127
def post(self, request):
130
Create a server using the parameters supplied in the POST
131
application/json object. The required parameters as specified by
132
the underlying novaclient are:
134
:param name: The new server name.
135
:param source_id: The ID of the image to use.
136
:param flavor_id: The ID of the flavor to use.
137
:param key_name: (optional extension) name of previously created
138
keypair to inject into the instance.
139
:param user_data: user data to pass to be exposed by the metadata
140
server this can be a file type object as well or a
142
:param security_groups: An array of one or more objects with a "name"
145
Other parameters are accepted as per the underlying novaclient:
146
"block_device_mapping", "block_device_mapping_v2", "nics", "meta",
147
"availability_zone", "instance_count", "admin_pass", "disk_config",
150
This returns the new server object on success.
155
request.DATA['name'],
156
request.DATA['source_id'],
157
request.DATA['flavor_id'],
158
request.DATA['key_name'],
159
request.DATA['user_data'],
160
request.DATA['security_groups'],
162
except KeyError as e:
163
raise rest_utils.AjaxError(400, 'missing required parameter '
166
for name in self._optional_create:
167
if name in request.DATA:
168
kw[name] = request.DATA[name]
170
new = api.nova.server_create(*args, **kw)
171
return rest_utils.CreatedResponse(
172
'/api/nova/servers/%s' % utils_http.urlquote(new.id),
178
class Server(generic.View):
179
"""API for retrieving a single server
181
url_regex = r'nova/servers/(?P<server_id>.+|default)$'
184
def get(self, request, server_id):
185
"""Get a specific server
187
http://localhost/api/nova/servers/1
189
return api.nova.server_get(request, server_id).to_dict()
193
class Extensions(generic.View):
194
"""API for nova extensions.
196
url_regex = r'nova/extensions/$'
199
def get(self, request):
200
"""Get a list of extensions.
202
The listing result is an object with property "items". Each item is
206
http://localhost/api/nova/extensions
208
result = api.nova.list_extensions(request)
209
return {'items': [e.to_dict() for e in result]}
213
class Flavors(generic.View):
214
"""API for nova flavors.
216
url_regex = r'nova/flavors/$'
219
def get(self, request):
220
"""Get a list of flavors.
222
The listing result is an object with property "items". Each item is
223
an flavor. By default this will return the flavors for the user's
224
current project. If the user is admin, public flavors will also be
227
:param is_public: For a regular user, set to True to see all public
228
flavors. For an admin user, set to False to not see public flavors.
229
:param get_extras: Also retrieve the extra specs.
232
http://localhost/api/nova/flavors?is_public=true
234
is_public = request.GET.get('is_public')
235
is_public = (is_public and is_public.lower() == 'true')
236
get_extras = request.GET.get('get_extras')
237
get_extras = bool(get_extras and get_extras.lower() == 'true')
238
flavors = api.nova.flavor_list(request, is_public=is_public,
239
get_extras=get_extras)
240
result = {'items': []}
241
for flavor in flavors:
244
d['extras'] = flavor.extras
245
result['items'].append(d)
250
class Flavor(generic.View):
251
"""API for retrieving a single flavor
253
url_regex = r'nova/flavors/(?P<flavor_id>.+)/$'
256
def get(self, request, flavor_id):
257
"""Get a specific flavor
259
:param get_extras: Also retrieve the extra specs.
262
http://localhost/api/nova/flavors/1
264
get_extras = request.GET.get('get_extras')
265
get_extras = bool(get_extras and get_extras.lower() == 'true')
266
flavor = api.nova.flavor_get(request, flavor_id, get_extras=get_extras)
267
result = flavor.to_dict()
269
result['extras'] = flavor.extras
274
class FlavorExtraSpecs(generic.View):
275
"""API for managing flavor extra specs
277
url_regex = r'nova/flavors/(?P<flavor_id>.+)/extra-specs$'
280
def get(self, request, flavor_id):
281
"""Get a specific flavor's extra specs
284
http://localhost/api/nova/flavors/1/extra-specs
286
return api.nova.flavor_get_extras(request, flavor_id, raw=True)