1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2012 United States Government as represented by the
4
# Administrator of the National Aeronautics and Space Administration.
7
# Copyright 2012 Cisco Systems, Inc.
8
# Copyright 2012 NEC Corporation
10
# Licensed under the Apache License, Version 2.0 (the "License"); you may
11
# not use this file except in compliance with the License. You may obtain
12
# a copy of the License at
14
# http://www.apache.org/licenses/LICENSE-2.0
16
# Unless required by applicable law or agreed to in writing, software
17
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19
# License for the specific language governing permissions and limitations
22
from __future__ import absolute_import
26
from quantumclient.v2_0 import client as quantum_client
27
from django.utils.datastructures import SortedDict
29
from openstack_dashboard.api.base import APIDictWrapper, url_for
32
LOG = logging.getLogger(__name__)
35
class QuantumAPIDictWrapper(APIDictWrapper):
37
def set_id_as_name_if_empty(self, length=8):
39
if not self._apidict['name']:
40
id = self._apidict['id']
43
self._apidict['name'] = '(%s)' % id
48
return self._apidict.items()
51
class Network(QuantumAPIDictWrapper):
52
"""Wrapper for quantum Networks"""
53
_attrs = ['name', 'id', 'subnets', 'tenant_id', 'status',
54
'admin_state_up', 'shared']
56
def __init__(self, apiresource):
57
apiresource['admin_state'] = \
58
'UP' if apiresource['admin_state_up'] else 'DOWN'
59
super(Network, self).__init__(apiresource)
62
class Subnet(QuantumAPIDictWrapper):
63
"""Wrapper for quantum subnets"""
64
_attrs = ['name', 'id', 'cidr', 'network_id', 'tenant_id',
65
'ip_version', 'ipver_str']
67
def __init__(self, apiresource):
68
apiresource['ipver_str'] = get_ipver_str(apiresource['ip_version'])
69
super(Subnet, self).__init__(apiresource)
72
class Port(QuantumAPIDictWrapper):
73
"""Wrapper for quantum ports"""
74
_attrs = ['name', 'id', 'network_id', 'tenant_id',
75
'admin_state_up', 'status', 'mac_address',
76
'fixed_ips', 'host_routes', 'device_id']
78
def __init__(self, apiresource):
79
apiresource['admin_state'] = \
80
'UP' if apiresource['admin_state_up'] else 'DOWN'
81
super(Port, self).__init__(apiresource)
84
IP_VERSION_DICT = {4: 'IPv4', 6: 'IPv6'}
87
def get_ipver_str(ip_version):
88
"""Convert an ip version number to a human-friendly string"""
89
return IP_VERSION_DICT.get(ip_version, '')
92
def quantumclient(request):
93
LOG.debug('quantumclient connection created using token "%s" and url "%s"'
94
% (request.user.token.id, url_for(request, 'network')))
95
LOG.debug('user_id=%(user)s, tenant_id=%(tenant)s' %
96
{'user': request.user.id, 'tenant': request.user.tenant_id})
97
c = quantum_client.Client(token=request.user.token.id,
98
endpoint_url=url_for(request, 'network'))
102
def network_list(request, **params):
103
LOG.debug("network_list(): params=%s" % (params))
104
networks = quantumclient(request).list_networks(**params).get('networks')
105
# Get subnet list to expand subnet info in network list.
106
subnets = subnet_list(request)
107
subnet_dict = SortedDict([(s['id'], s) for s in subnets])
108
# Expand subnet list from subnet_id to values.
110
n['subnets'] = [subnet_dict[s] for s in n['subnets']]
111
return [Network(n) for n in networks]
114
def network_list_for_tenant(request, tenant_id, **params):
115
"""Return a network list available for the tenant.
116
The list contains networks owned by the tenant and public networks.
117
If requested_networks specified, it searches requested_networks only.
119
LOG.debug("network_list_for_tenant(): tenant_id=%s, params=%s"
120
% (tenant_id, params))
122
# If a user has admin role, network list returned by Quantum API
123
# contains networks that do not belong to that tenant.
124
# So we need to specify tenant_id when calling network_list().
125
networks = network_list(request, tenant_id=tenant_id,
126
shared=False, **params)
128
# In the current Quantum API, there is no way to retrieve
129
# both owner networks and public networks in a single API call.
130
networks += network_list(request, shared=True, **params)
135
def network_get(request, network_id, **params):
136
LOG.debug("network_get(): netid=%s, params=%s" % (network_id, params))
137
network = quantumclient(request).show_network(network_id,
138
**params).get('network')
139
# Since the number of subnets per network must be small,
140
# call subnet_get() for each subnet instead of calling
141
# subnet_list() once.
142
network['subnets'] = [subnet_get(request, sid)
143
for sid in network['subnets']]
144
return Network(network)
147
def network_create(request, **kwargs):
149
Create a subnet on a specified network.
150
:param request: request context
151
:param tenant_id: (optional) tenant id of the network created
152
:param name: (optional) name of the network created
153
:returns: Subnet object
155
LOG.debug("network_create(): kwargs = %s" % kwargs)
156
body = {'network': kwargs}
157
network = quantumclient(request).create_network(body=body).get('network')
158
return Network(network)
161
def network_modify(request, network_id, **kwargs):
162
LOG.debug("network_modify(): netid=%s, params=%s" % (network_id, kwargs))
163
body = {'network': kwargs}
164
network = quantumclient(request).update_network(network_id,
165
body=body).get('network')
166
return Network(network)
169
def network_delete(request, network_id):
170
LOG.debug("network_delete(): netid=%s" % network_id)
171
quantumclient(request).delete_network(network_id)
174
def subnet_list(request, **params):
175
LOG.debug("subnet_list(): params=%s" % (params))
176
subnets = quantumclient(request).list_subnets(**params).get('subnets')
177
return [Subnet(s) for s in subnets]
180
def subnet_get(request, subnet_id, **params):
181
LOG.debug("subnet_get(): subnetid=%s, params=%s" % (subnet_id, params))
182
subnet = quantumclient(request).show_subnet(subnet_id,
183
**params).get('subnet')
184
return Subnet(subnet)
187
def subnet_create(request, network_id, cidr, ip_version, **kwargs):
189
Create a subnet on a specified network.
190
:param request: request context
191
:param network_id: network id a subnet is created on
192
:param cidr: subnet IP address range
193
:param ip_version: IP version (4 or 6)
194
:param gateway_ip: (optional) IP address of gateway
195
:param tenant_id: (optional) tenant id of the subnet created
196
:param name: (optional) name of the subnet created
197
:returns: Subnet object
199
LOG.debug("subnet_create(): netid=%s, cidr=%s, ipver=%d, kwargs=%s"
200
% (network_id, cidr, ip_version, kwargs))
202
{'network_id': network_id,
203
'ip_version': ip_version,
205
body['subnet'].update(kwargs)
206
subnet = quantumclient(request).create_subnet(body=body).get('subnet')
207
return Subnet(subnet)
210
def subnet_modify(request, subnet_id, **kwargs):
211
LOG.debug("subnet_modify(): subnetid=%s, kwargs=%s" % (subnet_id, kwargs))
212
body = {'subnet': kwargs}
213
subnet = quantumclient(request).update_subnet(subnet_id,
214
body=body).get('subnet')
215
return Subnet(subnet)
218
def subnet_delete(request, subnet_id):
219
LOG.debug("subnet_delete(): subnetid=%s" % subnet_id)
220
quantumclient(request).delete_subnet(subnet_id)
223
def port_list(request, **params):
224
LOG.debug("port_list(): params=%s" % (params))
225
ports = quantumclient(request).list_ports(**params).get('ports')
226
return [Port(p) for p in ports]
229
def port_get(request, port_id, **params):
230
LOG.debug("port_get(): portid=%s, params=%s" % (port_id, params))
231
port = quantumclient(request).show_port(port_id, **params).get('port')
235
def port_create(request, network_id, **kwargs):
237
Create a port on a specified network.
238
:param request: request context
239
:param network_id: network id a subnet is created on
240
:param device_id: (optional) device id attached to the port
241
:param tenant_id: (optional) tenant id of the port created
242
:param name: (optional) name of the port created
243
:returns: Port object
245
LOG.debug("port_create(): netid=%s, kwargs=%s" % (network_id, kwargs))
246
body = {'port': {'network_id': network_id}}
247
body['port'].update(kwargs)
248
port = quantumclient(request).create_port(body=body).get('port')
252
def port_delete(request, port_id):
253
LOG.debug("port_delete(): portid=%s" % port_id)
254
quantumclient(request).delete_port(port_id)
257
def port_modify(request, port_id, **kwargs):
258
LOG.debug("port_modify(): portid=%s, kwargs=%s" % (port_id, kwargs))
259
body = {'port': kwargs}
260
port = quantumclient(request).update_port(port_id, body=body).get('port')