22
22
It is provided just in case a third party manager is in use.
25
from nova.compute import instance_types
28
26
from nova.db import base
29
27
from nova import exception
28
from nova.network import api as shiny_api
30
29
from nova.network import model as network_model
31
30
from nova.network import rpcapi as network_rpcapi
32
31
from nova.openstack.common import log as logging
33
from nova import policy
35
33
LOG = logging.getLogger(__name__)
40
Decorator to update the instance_info_cache
42
Requires context and instance as function args
44
argspec = inspect.getargspec(f)
47
def wrapper(self, context, *args, **kwargs):
48
res = f(self, context, *args, **kwargs)
51
# get the instance from arguments (or raise ValueError)
52
instance = kwargs.get('instance')
54
instance = args[argspec.args.index('instance') - 2]
56
msg = _('instance is a required argument to use @refresh_cache')
59
update_instance_cache_with_nw_info(self, context, instance,
62
# return the original function's return value
67
def update_instance_cache_with_nw_info(api, context, instance,
71
if not isinstance(nw_info, network_model.NetworkInfo):
74
nw_info = api._get_instance_nw_info(context, instance)
76
cache = {'network_info': nw_info.json()}
77
api.db.instance_info_cache_update(context, instance['uuid'], cache)
79
LOG.exception(_('Failed storing info cache'), instance=instance)
82
def wrap_check_policy(func):
83
"""Check policy corresponding to the wrapped methods prior to execution."""
85
@functools.wraps(func)
86
def wrapped(self, context, *args, **kwargs):
87
action = func.__name__
88
check_policy(context, action)
89
return func(self, context, *args, **kwargs)
94
def check_policy(context, action):
96
'project_id': context.project_id,
97
'user_id': context.user_id,
99
_action = 'network:%s' % action
100
policy.enforce(context, _action, target)
36
refresh_cache = shiny_api.refresh_cache
37
_update_instance_cache = shiny_api.update_instance_cache_with_nw_info
38
update_instance_cache_with_nw_info = _update_instance_cache
39
wrap_check_policy = shiny_api.wrap_check_policy
103
42
class API(base.Base):
160
99
@wrap_check_policy
161
100
def get_floating_ips_by_fixed_address(self, context, fixed_address):
162
return self.network_rpcapi.get_floating_ips_by_fixed_address(context,
101
args = (context, fixed_address)
102
return self.network_rpcapi.get_floating_ips_by_fixed_address(*args)
165
104
@wrap_check_policy
166
105
def get_backdoor_port(self, context, host):
170
109
def get_instance_id_by_floating_address(self, context, address):
171
110
# NOTE(tr3buchet): i hate this
172
111
return self.network_rpcapi.get_instance_id_by_floating_address(context,
175
114
@wrap_check_policy
176
115
def get_vifs_by_instance(self, context, instance):
177
116
return self.network_rpcapi.get_vifs_by_instance(context,
180
119
@wrap_check_policy
181
120
def get_vif_by_mac_address(self, context, mac_address):
189
128
# will probably need to move into a network supervisor
191
130
return self.network_rpcapi.allocate_floating_ip(context,
192
context.project_id, pool, False)
194
135
@wrap_check_policy
195
136
def release_floating_ip(self, context, address,
196
137
affect_auto_assigned=False):
197
138
"""Removes (deallocates) a floating ip with address from a project."""
198
return self.network_rpcapi.deallocate_floating_ip(context, address,
199
affect_auto_assigned)
139
args = (context, address, affect_auto_assigned)
140
return self.network_rpcapi.deallocate_floating_ip(*args)
201
142
@wrap_check_policy
208
149
ensures floating ip is allocated to the project in context
210
orig_instance_uuid = self.network_rpcapi.associate_floating_ip(context,
211
floating_address, fixed_address, affect_auto_assigned)
151
args = (context, floating_address, fixed_address, affect_auto_assigned)
152
orig_instance_uuid = self.network_rpcapi.associate_floating_ip(*args)
213
154
if orig_instance_uuid:
214
155
msg_dict = dict(address=floating_address,
227
168
affect_auto_assigned=False):
228
169
"""Disassociates a floating ip from fixed ip it is associated with."""
229
170
self.network_rpcapi.disassociate_floating_ip(context, address,
230
affect_auto_assigned)
171
affect_auto_assigned)
232
173
@wrap_check_policy
234
175
def allocate_for_instance(self, context, instance, vpn,
235
requested_networks, macs=None):
176
requested_networks, macs=None,
177
conductor_api=None, security_groups=None,
236
179
"""Allocates all network structures for an instance.
238
181
TODO(someone): document the rest of these parameters.
243
186
NB: macs is ignored by nova-network.
244
187
:returns: network info as from get_instance_nw_info() below
189
instance_type = instance_types.extract_instance_type(instance)
247
191
args['vpn'] = vpn
248
192
args['requested_networks'] = requested_networks
249
args['instance_id'] = instance['id']
250
args['instance_uuid'] = instance['uuid']
193
args['instance_id'] = instance['uuid']
251
194
args['project_id'] = instance['project_id']
252
195
args['host'] = instance['host']
253
args['rxtx_factor'] = instance['instance_type']['rxtx_factor']
196
args['rxtx_factor'] = instance_type['rxtx_factor']
254
197
nw_info = self.network_rpcapi.allocate_for_instance(context, **args)
256
199
return network_model.NetworkInfo.hydrate(nw_info)
258
201
@wrap_check_policy
259
def deallocate_for_instance(self, context, instance):
202
def deallocate_for_instance(self, context, instance, **kwargs):
260
203
"""Deallocates all network structures related to instance."""
268
211
@wrap_check_policy
270
def add_fixed_ip_to_instance(self, context, instance, network_id):
213
def add_fixed_ip_to_instance(self, context, instance, network_id,
214
conductor_api=None, **kwargs):
271
215
"""Adds a fixed ip to instance from specified network."""
272
216
args = {'instance_id': instance['uuid'],
273
217
'host': instance['host'],
274
'network_id': network_id}
218
'network_id': network_id,
275
220
self.network_rpcapi.add_fixed_ip_to_instance(context, **args)
277
222
@wrap_check_policy
279
def remove_fixed_ip_from_instance(self, context, instance, address):
224
def remove_fixed_ip_from_instance(self, context, instance, address,
225
conductor=None, **kwargs):
280
226
"""Removes a fixed ip from instance from specified network."""
282
228
args = {'instance_id': instance['uuid'],
283
229
'host': instance['host'],
285
232
self.network_rpcapi.remove_fixed_ip_from_instance(context, **args)
287
234
@wrap_check_policy
288
235
def add_network_to_project(self, context, project_id, network_uuid=None):
289
236
"""Force adds another network to a project."""
290
237
self.network_rpcapi.add_network_to_project(context, project_id,
293
240
@wrap_check_policy
294
241
def associate(self, context, network_uuid, host=_sentinel,
302
249
self.network_rpcapi.associate(context, network_uuid, associations)
304
251
@wrap_check_policy
305
def get_instance_nw_info(self, context, instance, update_cache=True):
252
def get_instance_nw_info(self, context, instance, conductor_api=None,
306
254
"""Returns all network info related to an instance."""
307
255
result = self._get_instance_nw_info(context, instance)
309
update_instance_cache_with_nw_info(self, context, instance,
256
update_instance_cache_with_nw_info(self, context, instance,
257
result, conductor_api)
313
260
def _get_instance_nw_info(self, context, instance):
314
261
"""Returns all network info related to an instance."""
315
args = {'instance_id': instance['id'],
316
'instance_uuid': instance['uuid'],
317
'rxtx_factor': instance['instance_type']['rxtx_factor'],
262
instance_type = instance_types.extract_instance_type(instance)
263
args = {'instance_id': instance['uuid'],
264
'rxtx_factor': instance_type['rxtx_factor'],
318
265
'host': instance['host'],
319
266
'project_id': instance['project_id']}
320
267
nw_info = self.network_rpcapi.get_instance_nw_info(context, **args)
422
369
return network['multi_host']
424
371
def _get_floating_ip_addresses(self, context, instance):
425
floating_ips = self.db.instance_floating_address_get_all(context,
372
args = (context, instance['uuid'])
373
floating_ips = self.db.instance_floating_address_get_all(*args)
427
374
return [floating_ip['address'] for floating_ip in floating_ips]
429
376
@wrap_check_policy
430
377
def migrate_instance_start(self, context, instance, migration):
431
378
"""Start to migrate the network of an instance."""
379
instance_type = instance_types.extract_instance_type(instance)
433
381
instance_uuid=instance['uuid'],
434
rxtx_factor=instance['instance_type']['rxtx_factor'],
382
rxtx_factor=instance_type['rxtx_factor'],
435
383
project_id=instance['project_id'],
436
384
source_compute=migration['source_compute'],
437
385
dest_compute=migration['dest_compute'],
448
396
@wrap_check_policy
449
397
def migrate_instance_finish(self, context, instance, migration):
450
398
"""Finish migrating the network of an instance."""
399
instance_type = instance_types.extract_instance_type(instance)
452
401
instance_uuid=instance['uuid'],
453
rxtx_factor=instance['instance_type']['rxtx_factor'],
402
rxtx_factor=instance_type['rxtx_factor'],
454
403
project_id=instance['project_id'],
455
404
source_compute=migration['source_compute'],
456
405
dest_compute=migration['dest_compute'],
463
412
args['host'] = migration['dest_compute']
465
414
self.network_rpcapi.migrate_instance_finish(context, **args)
416
# NOTE(jkoelker) These functions where added to the api after
417
# deprecation. Stubs provided for support documentation
418
def allocate_port_for_instance(self, context, instance, port_id,
419
network_id=None, requested_ip=None,
421
raise NotImplementedError()
423
def deallocate_port_for_instance(self, context, instance, port_id,
425
raise NotImplementedError()
427
def list_ports(self, *args, **kwargs):
428
raise NotImplementedError()
430
def show_port(self, *args, **kwargs):
431
raise NotImplementedError()