Implement BP untie-nova-network-models

Fixes LP853979
Remove the FK references for network data.
Remove unused db functions that used the FK's
Update db functions to not joinload
Update notification to optionally take network_info if compute has it
Update EC2 Api to use the network cache, falling back to rpc.call
Remove test_instance_get_project_vpn_joins which tests calls not used

Change-Id: I1a01ccc5ebcf7efeafe014af62be893325bb0825
This commit is contained in:
Jason Kölker 2012-01-04 11:10:10 -06:00
parent 1a8f27ef2a
commit 0c90acfb15
3 changed files with 57 additions and 135 deletions
nova

@ -290,11 +290,6 @@ def floating_ip_fixed_ip_associate(context, floating_address,
host)
def floating_ip_get_all(context):
"""Get all floating ips."""
return IMPL.floating_ip_get_all(context)
def floating_ip_get_all_by_host(context, host):
"""Get all floating ips by host."""
return IMPL.floating_ip_get_all_by_host(context, host)
@ -315,6 +310,11 @@ def floating_ip_get_by_fixed_address(context, fixed_address):
return IMPL.floating_ip_get_by_fixed_address(context, fixed_address)
def floating_ip_get_by_fixed_ip_id(context, fixed_ip_id):
"""Get a floating ips by fixed address"""
return IMPL.floating_ip_get_by_fixed_ip_id(context, fixed_ip_id)
def floating_ip_update(context, address, values):
"""Update a floating ip by address or raise if it doesn't exist."""
return IMPL.floating_ip_update(context, address, values)
@ -407,11 +407,6 @@ def fixed_ip_get_all(context):
return IMPL.fixed_ip_get_all(context)
def fixed_ip_get_all_by_instance_host(context, host):
"""Get all allocated fixed ips filtered by instance host."""
return IMPL.fixed_ip_get_all_by_instance_host(context, host)
def fixed_ip_get_by_address(context, address):
"""Get a fixed ip by address or raise if it does not exist."""
return IMPL.fixed_ip_get_by_address(context, address)
@ -581,15 +576,6 @@ def instance_get_all_by_reservation(context, reservation_id):
return IMPL.instance_get_all_by_reservation(context, reservation_id)
def instance_get_fixed_addresses(context, instance_id):
"""Get the fixed ip address of an instance."""
return IMPL.instance_get_fixed_addresses(context, instance_id)
def instance_get_fixed_addresses_v6(context, instance_id):
return IMPL.instance_get_fixed_addresses_v6(context, instance_id)
def instance_get_floating_address(context, instance_id):
"""Get the first floating ip address of an instance."""
return IMPL.instance_get_floating_address(context, instance_id)

@ -27,7 +27,6 @@ from nova import block_device
from nova import db
from nova import exception
from nova import flags
from nova import ipv6
from nova import utils
from nova import log as logging
from nova.compute import vm_states
@ -478,8 +477,6 @@ def certificate_update(context, certificate_id, values):
@require_context
def floating_ip_get(context, id):
result = model_query(context, models.FloatingIp, project_only=True).\
options(joinedload('fixed_ip')).\
options(joinedload_all('fixed_ip.instance')).\
filter_by(id=id).\
first()
@ -548,7 +545,7 @@ def floating_ip_fixed_ip_associate(context, floating_address,
fixed_ip_ref = fixed_ip_get_by_address(context,
fixed_address,
session=session)
floating_ip_ref.fixed_ip = fixed_ip_ref
floating_ip_ref.fixed_ip_id = fixed_ip_ref["id"]
floating_ip_ref.host = host
floating_ip_ref.save(session=session)
@ -583,12 +580,13 @@ def floating_ip_disassociate(context, address):
floating_ip_ref = floating_ip_get_by_address(context,
address,
session=session)
fixed_ip_ref = floating_ip_ref.fixed_ip
fixed_ip_ref = fixed_ip_get(context,
floating_ip_ref['fixed_ip_id'])
if fixed_ip_ref:
fixed_ip_address = fixed_ip_ref['address']
else:
fixed_ip_address = None
floating_ip_ref.fixed_ip = None
floating_ip_ref.fixed_ip_id = None
floating_ip_ref.host = None
floating_ip_ref.save(session=session)
return fixed_ip_address
@ -606,16 +604,7 @@ def floating_ip_set_auto_assigned(context, address):
def _floating_ip_get_all(context):
return model_query(context, models.FloatingIp, read_deleted="no").\
options(joinedload_all('fixed_ip.instance'))
@require_admin_context
def floating_ip_get_all(context):
floating_ip_refs = _floating_ip_get_all(context).all()
if not floating_ip_refs:
raise exception.NoFloatingIpsDefined()
return floating_ip_refs
return model_query(context, models.FloatingIp, read_deleted="no")
@require_admin_context
@ -641,7 +630,6 @@ def floating_ip_get_all_by_project(context, project_id):
@require_context
def floating_ip_get_by_address(context, address, session=None):
result = model_query(context, models.FloatingIp, session=session).\
options(joinedload_all('fixed_ip.network')).\
filter_by(address=address).\
first()
@ -665,13 +653,22 @@ def floating_ip_get_by_fixed_address(context, fixed_address, session=None):
fixed_ip_id = fixed_ip['id']
return model_query(context, models.FloatingIp, session=session).\
options(joinedload_all('fixed_ip.network')).\
filter_by(fixed_ip_id=fixed_ip_id).\
all()
# NOTE(tr3buchet) please don't invent an exception here, empty list is fine
@require_context
def floating_ip_get_by_fixed_ip_id(context, fixed_ip_id, session=None):
if not session:
session = get_session()
return model_query(context, models.FloatingIp, session=session).\
filter_by(fixed_ip_id=fixed_ip_id).\
all()
@require_context
def floating_ip_update(context, address, values):
session = get_session()
@ -732,7 +729,7 @@ def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None):
read_deleted="no").\
filter(network_or_none).\
filter_by(reserved=False).\
filter_by(instance=None).\
filter_by(instance_id=None).\
filter_by(host=None).\
with_lockmode('update').\
first()
@ -740,16 +737,15 @@ def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None):
# then this has concurrency issues
if not fixed_ip_ref:
raise exception.NoMoreFixedIps()
if not fixed_ip_ref.network:
fixed_ip_ref.network = network_get(context,
network_id,
session=session)
if fixed_ip_ref['network_id'] is None:
fixed_ip_ref['network'] = network_id
if instance_id:
fixed_ip_ref.instance = instance_get(context,
instance_id,
session=session)
fixed_ip_ref['instance_id'] = instance_id
if host:
fixed_ip_ref.host = host
fixed_ip_ref['host'] = host
session.add(fixed_ip_ref)
return fixed_ip_ref['address']
@ -798,8 +794,6 @@ def fixed_ip_disassociate_all_by_timeout(context, host, time):
filter(models.FixedIp.updated_at < time).\
filter(models.FixedIp.instance_id != None).\
filter(models.FixedIp.allocated == False).\
join(models.FixedIp.instance).\
join(models.FixedIp.network).\
filter(host_filter).\
all()
result = model_query(context, models.FixedIp, session=session,
@ -816,16 +810,15 @@ def fixed_ip_disassociate_all_by_timeout(context, host, time):
def fixed_ip_get(context, id, session=None):
result = model_query(context, models.FixedIp, session=session).\
filter_by(id=id).\
options(joinedload('floating_ips')).\
options(joinedload('network')).\
first()
if not result:
raise exception.FixedIpNotFound(id=id)
# FIXME(sirp): shouldn't we just use project_only here to restrict the
# results?
if is_user_context(context):
authorize_project_context(context, result.instance.project_id)
if is_user_context(context) and result['instance_id'] is not None:
instance = instance_get(context, result['instance_id'], session)
authorize_project_context(context, instance.project_id)
return result
@ -834,7 +827,6 @@ def fixed_ip_get(context, id, session=None):
def fixed_ip_get_all(context, session=None):
result = model_query(context, models.FixedIp, session=session,
read_deleted="yes").\
options(joinedload('floating_ips')).\
all()
if not result:
raise exception.NoFixedIpsDefined()
@ -842,36 +834,20 @@ def fixed_ip_get_all(context, session=None):
return result
@require_admin_context
def fixed_ip_get_all_by_instance_host(context, host=None):
result = model_query(context, models.FixedIp, read_deleted="yes").\
options(joinedload('floating_ips')).\
join(models.FixedIp.instance).\
filter_by(host=host).\
all()
if not result:
raise exception.FixedIpNotFoundForHost(host=host)
return result
@require_context
def fixed_ip_get_by_address(context, address, session=None):
result = model_query(context, models.FixedIp, session=session,
read_deleted="yes").\
filter_by(address=address).\
options(joinedload('floating_ips')).\
options(joinedload('network')).\
options(joinedload('instance')).\
first()
if not result:
raise exception.FixedIpNotFoundForAddress(address=address)
# NOTE(sirp): shouldn't we just use project_only here to restrict the
# results?
if is_user_context(context):
authorize_project_context(context, result.instance.project_id)
if is_user_context(context) and result['instance_id'] is not None:
instance = instance_get(context, result['instance_id'], session)
authorize_project_context(context, instance.project_id)
return result
@ -879,7 +855,6 @@ def fixed_ip_get_by_address(context, address, session=None):
@require_context
def fixed_ip_get_by_instance(context, instance_id):
result = model_query(context, models.FixedIp, read_deleted="no").\
options(joinedload('floating_ips')).\
filter_by(instance_id=instance_id).\
all()
@ -905,7 +880,6 @@ def fixed_ip_get_by_network_host(context, network_id, host):
@require_context
def fixed_ips_by_virtual_interface(context, vif_id):
result = model_query(context, models.FixedIp, read_deleted="no").\
options(joinedload('floating_ips')).\
filter_by(virtual_interface_id=vif_id).\
all()
@ -966,8 +940,7 @@ def virtual_interface_update(context, vif_id, values):
@require_context
def _virtual_interface_query(context, session=None):
return model_query(context, models.VirtualInterface, session=session,
read_deleted="yes").\
options(joinedload_all('fixed_ips.floating_ips'))
read_deleted="yes")
@require_context
@ -1202,9 +1175,6 @@ def instance_get(context, instance_id, session=None):
def _build_instance_get(context, session=None):
return model_query(context, models.Instance, session=session,
project_only=True).\
options(joinedload_all('fixed_ips.floating_ips')).\
options(joinedload_all('fixed_ips.network')).\
options(joinedload_all('fixed_ips.virtual_interface')).\
options(joinedload_all('security_groups.rules')).\
options(joinedload('info_cache')).\
options(joinedload('volumes')).\
@ -1215,10 +1185,8 @@ def _build_instance_get(context, session=None):
@require_admin_context
def instance_get_all(context):
return model_query(context, models.Instance).\
options(joinedload_all('fixed_ips.floating_ips')).\
options(joinedload('info_cache')).\
options(joinedload('security_groups')).\
options(joinedload_all('fixed_ips.network')).\
options(joinedload('metadata')).\
options(joinedload('instance_type')).\
all()
@ -1266,9 +1234,6 @@ def instance_get_all_by_filters(context, filters):
session = get_session()
query_prefix = session.query(models.Instance).\
options(joinedload_all('fixed_ips.floating_ips')).\
options(joinedload_all('fixed_ips.network')).\
options(joinedload_all('fixed_ips.virtual_interface')).\
options(joinedload('info_cache')).\
options(joinedload('security_groups')).\
options(joinedload('metadata')).\
@ -1366,9 +1331,7 @@ def instance_get_active_by_window_joined(context, begin, end=None,
"""Return instances and joins that were continuously active over window."""
session = get_session()
query = session.query(models.Instance).\
options(joinedload_all('fixed_ips.floating_ips')).\
options(joinedload('security_groups')).\
options(joinedload_all('fixed_ips.network')).\
options(joinedload('instance_type')).\
filter(models.Instance.launched_at < begin)
if end:
@ -1384,10 +1347,8 @@ def instance_get_active_by_window_joined(context, begin, end=None,
@require_admin_context
def _instance_get_all_query(context, project_only=False):
return model_query(context, models.Instance, project_only=project_only).\
options(joinedload_all('fixed_ips.floating_ips')).\
options(joinedload('info_cache')).\
options(joinedload('security_groups')).\
options(joinedload_all('fixed_ips.network')).\
options(joinedload('metadata')).\
options(joinedload('instance_type'))
@ -1425,53 +1386,24 @@ def instance_get_project_vpn(context, project_id):
first()
@require_context
def instance_get_fixed_addresses(context, instance_id):
session = get_session()
with session.begin():
try:
fixed_ips = fixed_ip_get_by_instance(context, instance_id)
except exception.NotFound:
return []
return [fixed_ip.address for fixed_ip in fixed_ips]
@require_context
def instance_get_fixed_addresses_v6(context, instance_id):
session = get_session()
with session.begin():
# get instance
instance_ref = instance_get(context, instance_id, session=session)
# assume instance has 1 mac for each network associated with it
# get networks associated with instance
network_refs = network_get_all_by_instance(context, instance_id)
# compile a list of cidr_v6 prefixes sorted by network id
prefixes = [ref.cidr_v6 for ref in
sorted(network_refs, key=lambda ref: ref.id)]
# get vifs associated with instance
vif_refs = virtual_interface_get_by_instance(context, instance_ref.id)
# compile list of the mac_addresses for vifs sorted by network id
macs = [vif_ref['address'] for vif_ref in
sorted(vif_refs, key=lambda vif_ref: vif_ref['network_id'])]
# get project id from instance
project_id = instance_ref.project_id
# combine prefixes, macs, and project_id into (prefix,mac,p_id) tuples
prefix_mac_tuples = zip(prefixes, macs, [project_id for m in macs])
# return list containing ipv6 address for each tuple
return [ipv6.to_global(*t) for t in prefix_mac_tuples]
# NOTE(jkoelker) This is only being left here for compat with floating
# ips. Currently the network_api doesn't return floaters
# in network_info. Once it starts return the model. This
# function and it's call in compute/manager.py on 1829 can
# go away
@require_context
def instance_get_floating_address(context, instance_id):
fixed_ip_refs = fixed_ip_get_by_instance(context, instance_id)
if not fixed_ip_refs:
fixed_ips = fixed_ip_get_by_instance(context, instance_id)
if not fixed_ips:
return None
# NOTE(tr3buchet): this only gets the first fixed_ip
# won't find floating ips associated with other fixed_ips
if not fixed_ip_refs[0].floating_ips:
floating_ips = floating_ip_get_by_fixed_address(context,
fixed_ips[0]['address'])
if not floating_ips:
return None
# NOTE(vish): this just returns the first floating ip
return fixed_ip_refs[0].floating_ips[0]['address']
return floating_ips[0]['address']
@require_admin_context
@ -1878,7 +1810,6 @@ def network_get_associated_fixed_ips(context, network_id):
# FIXME(sirp): since this returns fixed_ips, this would be better named
# fixed_ip_get_all_by_network.
return model_query(context, models.FixedIp, read_deleted="no").\
options(joinedload_all('instance')).\
filter_by(network_id=network_id).\
filter(models.FixedIp.instance_id != None).\
filter(models.FixedIp.virtual_interface_id != None).\
@ -1929,7 +1860,6 @@ def network_get_by_instance(context, instance_id):
# note this uses fixed IP to get to instance
# only works for networks the instance has an IP from
result = _network_get_query(context).\
join(models.Network.fixed_ips).\
filter_by(instance_id=instance_id).\
first()
@ -1942,7 +1872,6 @@ def network_get_by_instance(context, instance_id):
@require_admin_context
def network_get_all_by_instance(context, instance_id):
result = _network_get_query(context).\
join(models.Network.fixed_ips).\
filter_by(instance_id=instance_id).\
all()
@ -1959,7 +1888,6 @@ def network_get_all_by_host(context, host):
host_filter = or_(models.Network.host == host,
models.FixedIp.host == host)
return _network_get_query(context).\
join(models.Network.fixed_ips).\
filter(host_filter).\
all()

@ -398,7 +398,7 @@ def current_audit_period(unit=None):
return (begin, end)
def usage_from_instance(instance_ref, **kw):
def usage_from_instance(instance_ref, network_info=None, **kw):
image_ref_url = "%s/images/%s" % (generate_glance_url(),
instance_ref['image_ref'])
@ -415,8 +415,16 @@ def usage_from_instance(instance_ref, **kw):
image_ref_url=image_ref_url,
state=instance_ref['vm_state'],
state_description=instance_ref['task_state'] \
if instance_ref['task_state'] else '',
fixed_ips=[a.address for a in instance_ref['fixed_ips']])
if instance_ref['task_state'] else '')
# NOTE(jkoelker) This nastyness can go away once compute uses the
# network model
if network_info is not None:
fixed_ips = []
for network, info in network_info:
fixed_ips.extend([ip['ip'] for ip in info['ips']])
usage_info['fixed_ips'] = fixed_ips
usage_info.update(kw)
return usage_info