summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/nova/rootwrap.d/api-metadata.filters13
-rw-r--r--etc/nova/rootwrap.d/network.filters91
-rw-r--r--lower-constraints.txt1
-rw-r--r--nova/conf/__init__.py2
-rw-r--r--nova/conf/netconf.py18
-rw-r--r--nova/conf/network.py1336
-rw-r--r--nova/conf/upgrade_levels.py18
-rw-r--r--nova/db/api.py25
-rw-r--r--nova/db/sqlalchemy/api.py53
-rw-r--r--nova/db/sqlalchemy/models.py1
-rw-r--r--nova/ipv6/__init__.py15
-rw-r--r--nova/ipv6/account_identifier.py55
-rw-r--r--nova/ipv6/api.py37
-rw-r--r--nova/ipv6/rfc2462.py44
-rw-r--r--nova/network/__init__.py24
-rw-r--r--nova/network/api.py511
-rw-r--r--nova/network/base_api.py54
-rw-r--r--nova/network/dns_driver.py44
-rw-r--r--nova/network/driver.py37
-rw-r--r--nova/network/floating_ips.py659
-rw-r--r--nova/network/l3.py179
-rw-r--r--nova/network/ldapdns.py337
-rw-r--r--nova/network/linux_net.py1632
-rw-r--r--nova/network/manager.py2165
-rw-r--r--nova/network/minidns.py206
-rw-r--r--nova/network/neutronv2/api.py71
-rw-r--r--nova/network/noop_dns_driver.py47
-rw-r--r--nova/network/rpcapi.py369
-rw-r--r--nova/objects/__init__.py1
-rw-r--r--nova/objects/dns_domain.py72
-rw-r--r--nova/objects/network.py4
-rw-r--r--nova/objects/network_request.py18
-rw-r--r--nova/privsep/linux_net.py282
-rw-r--r--nova/privsep/utils.py7
-rw-r--r--nova/test.py69
-rw-r--r--nova/tests/fixtures.py23
-rw-r--r--nova/tests/unit/README.rst95
-rw-r--r--nova/tests/unit/api/openstack/compute/test_floating_ips.py92
-rw-r--r--nova/tests/unit/conf_fixture.py15
-rw-r--r--nova/tests/unit/db/test_db_api.py66
-rw-r--r--nova/tests/unit/fake_network.py294
-rw-r--r--nova/tests/unit/network/test_api.py570
-rw-r--r--nova/tests/unit/network/test_l3.py26
-rw-r--r--nova/tests/unit/network/test_linux_net.py1417
-rw-r--r--nova/tests/unit/network/test_manager.py3823
-rw-r--r--nova/tests/unit/network/test_rpcapi.py417
-rw-r--r--nova/tests/unit/objects/test_dns_domain.py85
-rw-r--r--nova/tests/unit/objects/test_objects.py2
-rw-r--r--nova/tests/unit/privsep/test_linux_net.py114
-rw-r--r--nova/tests/unit/privsep/test_utils.py12
-rw-r--r--nova/tests/unit/test_fixtures.py42
-rw-r--r--nova/tests/unit/test_iptables_network.py276
-rw-r--r--nova/tests/unit/test_ipv6.py82
-rw-r--r--nova/tests/unit/test_profiler.py5
-rw-r--r--nova/tests/unit/utils.py24
-rw-r--r--nova/utils.py13
-rw-r--r--releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml72
-rw-r--r--setup.cfg11
-rw-r--r--test-requirements.txt1
59 files changed, 108 insertions, 15966 deletions
diff --git a/etc/nova/rootwrap.d/api-metadata.filters b/etc/nova/rootwrap.d/api-metadata.filters
deleted file mode 100644
index 1aa6f83e68..0000000000
--- a/etc/nova/rootwrap.d/api-metadata.filters
+++ /dev/null
@@ -1,13 +0,0 @@
-# nova-rootwrap command filters for api-metadata nodes
-# This is needed on nova-api hosts running with "metadata" in enabled_apis
-# or when running nova-api-metadata
-# This file should be owned by (and only-writeable by) the root user
-
-[Filters]
-# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ...
-iptables-save: CommandFilter, iptables-save, root
-ip6tables-save: CommandFilter, ip6tables-save, root
-
-# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
-iptables-restore: CommandFilter, iptables-restore, root
-ip6tables-restore: CommandFilter, ip6tables-restore, root
diff --git a/etc/nova/rootwrap.d/network.filters b/etc/nova/rootwrap.d/network.filters
deleted file mode 100644
index 52b7130ea8..0000000000
--- a/etc/nova/rootwrap.d/network.filters
+++ /dev/null
@@ -1,91 +0,0 @@
-# nova-rootwrap command filters for network nodes
-# This file should be owned by (and only-writeable by) the root user
-
-[Filters]
-# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap'
-# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up'
-# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev
-# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i..
-# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'..
-# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',..
-# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',..
-# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev)
-# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1]
-# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge
-# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', ..
-# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',..
-# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ...
-# nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,..
-# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up'
-# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up'
-# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, ..
-# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, ..
-# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up'
-# nova/network/linux_net.py: 'ip', 'route', 'add', ..
-# nova/network/linux_net.py: 'ip', 'route', 'del', .
-# nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev
-ip: CommandFilter, ip, root
-
-# nova/virt/libvirt/vif.py: 'ovs-vsctl', ...
-# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ...
-# nova/network/linux_net.py: 'ovs-vsctl', ....
-ovs-vsctl: CommandFilter, ovs-vsctl, root
-
-# nova/network/linux_net.py: 'ovs-ofctl', ....
-ovs-ofctl: CommandFilter, ovs-ofctl, root
-
-# nova/virt/libvirt/vif.py: 'ivs-ctl', ...
-# nova/virt/libvirt/vif.py: 'ivs-ctl', 'del-port', ...
-# nova/network/linux_net.py: 'ivs-ctl', ....
-ivs-ctl: CommandFilter, ivs-ctl, root
-
-# nova/virt/libvirt/vif.py: 'ifc_ctl', ...
-ifc_ctl: CommandFilter, /opt/pg/bin/ifc_ctl, root
-
-# nova/network/linux_net.py: 'ebtables', '-D' ...
-# nova/network/linux_net.py: 'ebtables', '-I' ...
-ebtables: CommandFilter, ebtables, root
-ebtables_usr: CommandFilter, ebtables, root
-
-# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ...
-iptables-save: CommandFilter, iptables-save, root
-ip6tables-save: CommandFilter, ip6tables-save, root
-
-# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,)
-iptables-restore: CommandFilter, iptables-restore, root
-ip6tables-restore: CommandFilter, ip6tables-restore, root
-
-# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ...
-# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],..
-arping: CommandFilter, arping, root
-
-# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address
-dhcp_release: CommandFilter, dhcp_release, root
-
-# nova/network/linux_net.py: 'kill', '-9', pid
-# nova/network/linux_net.py: 'kill', '-HUP', pid
-kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP
-
-# nova/network/linux_net.py: 'kill', pid
-kill_radvd: KillFilter, root, /usr/sbin/radvd
-
-# nova/network/linux_net.py: dnsmasq call
-dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq
-
-# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'..
-radvd: CommandFilter, radvd, root
-
-# nova/network/linux_net.py: 'brctl', 'addbr', bridge
-# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0
-# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off'
-# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface
-brctl: CommandFilter, brctl, root
-
-# nova/network/linux_net.py: 'sysctl', ....
-sysctl: CommandFilter, sysctl, root
-
-# nova/network/linux_net.py: 'conntrack'
-conntrack: CommandFilter, conntrack, root
-
-# nova/network/linux_net.py: 'fp-vdev'
-fp-vdev: CommandFilter, fp-vdev, root
diff --git a/lower-constraints.txt b/lower-constraints.txt
index b59125dd95..898b81fce5 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -54,7 +54,6 @@ mccabe==0.2.1
microversion-parse==0.2.1
mock==3.0.0
monotonic==1.4
-mox3==0.20.0
msgpack==0.5.6
msgpack-python==0.5.6
munch==2.2.0
diff --git a/nova/conf/__init__.py b/nova/conf/__init__.py
index fc64ceccac..fb6752c8e2 100644
--- a/nova/conf/__init__.py
+++ b/nova/conf/__init__.py
@@ -42,7 +42,6 @@ from nova.conf import keystone
from nova.conf import libvirt
from nova.conf import mks
from nova.conf import netconf
-from nova.conf import network
from nova.conf import neutron
from nova.conf import notifications
from nova.conf import novnc
@@ -94,7 +93,6 @@ key_manager.register_opts(CONF)
keystone.register_opts(CONF)
libvirt.register_opts(CONF)
netconf.register_opts(CONF)
-network.register_opts(CONF)
neutron.register_opts(CONF)
notifications.register_opts(CONF)
novnc.register_opts(CONF)
diff --git a/nova/conf/netconf.py b/nova/conf/netconf.py
index 064bb5f5f1..5fe0f909d7 100644
--- a/nova/conf/netconf.py
+++ b/nova/conf/netconf.py
@@ -34,10 +34,7 @@ Possible values:
Related options:
-* metadata_host
* my_block_storage_ip
-* routing_source_ip
-* vpn_ip
"""),
cfg.StrOpt("my_block_storage_ip",
default="$my_ip",
@@ -71,6 +68,21 @@ Possible values:
* String with hostname, FQDN or IP address. Default is hostname of this host.
"""),
+ # TODO(sfinucan): This option is tied into the XenAPI, VMWare and Libvirt
+ # drivers.
+ # We should remove this dependency by either adding a new opt for each
+ # driver or simply removing the offending code. Until then we cannot
+ # deprecate this option.
+ cfg.BoolOpt("flat_injected",
+ default=False,
+ help="""
+This option determines whether the network setup information is injected into
+the VM before it is booted. While it was originally designed to be used only
+by nova-network, it is also used by the vmware and xenapi virt drivers to
+control whether network information is injected into a VM. The libvirt virt
+driver also uses it when we use config_drive to configure network to control
+whether network information is injected into a VM.
+"""),
]
diff --git a/nova/conf/network.py b/nova/conf/network.py
deleted file mode 100644
index 62beb4cb05..0000000000
--- a/nova/conf/network.py
+++ /dev/null
@@ -1,1336 +0,0 @@
-# Copyright 2016 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Config options for the nova-network service and related services."""
-
-# NOTE(sfinucan): Don't make any non-bugfix changes to this file, as every
-# single option found here will be removed in a future release.
-
-from oslo_config import cfg
-
-from nova.conf import paths
-
-network_opts = [
- cfg.BoolOpt('use_neutron',
- default=True,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Enable neutron as the backend for networking.
-
-Determine whether to use Neutron or Nova Network as the back end. Set to true
-to use neutron.
-"""),
- # TODO(sfinucan): This option is tied into the XenAPI, VMWare and Libvirt
- # drivers.
- # We should remove this dependency by either adding a new opt for each
- # driver or simply removing the offending code. Until then we cannot
- # deprecate this option.
- cfg.BoolOpt("flat_injected",
- default=False,
- help="""
-This option determines whether the network setup information is injected into
-the VM before it is booted. While it was originally designed to be used only
-by nova-network, it is also used by the vmware and xenapi virt drivers to
-control whether network information is injected into a VM. The libvirt virt
-driver also uses it when we use config_drive to configure network to control
-whether network information is injected into a VM.
-"""),
- cfg.StrOpt("flat_network_bridge",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the bridge used for simple network interfaces when no
-bridge is specified in the VM creation request.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Possible values:
-
-* Any string representing a valid network bridge, such as 'br100'
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.StrOpt("flat_network_dns",
- default="8.8.4.4",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the address of the DNS server for a simple network. If this option is
-not specified, the default of '8.8.4.4' is used.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Possible values:
-
-* Any valid IP address.
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.StrOpt("flat_interface",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option is the name of the virtual interface of the VM on which the bridge
-will be built. While it was originally designed to be used only by
-nova-network, it is also used by libvirt for the bridge interface name.
-
-Possible values:
-
-* Any valid virtual interface name, such as 'eth0'
-"""),
- cfg.IntOpt("vlan_start",
- default=100,
- min=1,
- max=4094,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the VLAN number used for private networks. Note that the when creating
-the networks, if the specified number has already been assigned, nova-network
-will increment this number until it finds an available VLAN.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment. It also will be ignored if the configuration option
-for `network_manager` is not set to the default of
-'nova.network.manager.VlanManager'.
-
-Possible values:
-
-* Any integer between 1 and 4094. Values outside of that range will raise a
- ValueError exception.
-
-Related options:
-
-* ``network_manager``
-* ``use_neutron``
-"""),
- cfg.StrOpt("vlan_interface",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options. While
-this option has an effect when using neutron, it incorrectly override the value
-provided by neutron and should therefore not be used.
-""",
- help="""
-This option is the name of the virtual interface of the VM on which the VLAN
-bridge will be built. While it was originally designed to be used only by
-nova-network, it is also used by libvirt and xenapi for the bridge interface
-name.
-
-Please note that this setting will be ignored in nova-network if the
-configuration option for `network_manager` is not set to the default of
-'nova.network.manager.VlanManager'.
-
-Possible values:
-
-* Any valid virtual interface name, such as 'eth0'
-"""),
- cfg.IntOpt("num_networks",
- default=1,
- min=1,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option represents the number of networks to create if not explicitly
-specified when the network is created. The only time this is used is if a CIDR
-is specified, but an explicit network_size is not. In that case, the subnets
-are created by diving the IP address space of the CIDR by num_networks. The
-resulting subnet sizes cannot be larger than the configuration option
-`network_size`; in that event, they are reduced to `network_size`, and a
-warning is logged.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Possible values:
-
-* Any positive integer is technically valid, although there are practical
- limits based upon available IP address space and virtual interfaces.
-
-Related options:
-
-* ``use_neutron``
-* ``network_size``
-"""),
- cfg.StrOpt("vpn_ip",
- default="$my_ip",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option is no longer used since the /os-cloudpipe API was removed in the
-16.0.0 Pike release. This is the public IP address for the cloudpipe VPN
-servers. It defaults to the IP address of the host.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment. It also will be ignored if the configuration option
-for `network_manager` is not set to the default of
-'nova.network.manager.VlanManager'.
-
-Possible values:
-
-* Any valid IP address. The default is ``$my_ip``, the IP address of the VM.
-
-Related options:
-
-* ``network_manager``
-* ``use_neutron``
-* ``vpn_start``
-"""),
- cfg.PortOpt("vpn_start",
- default=1000,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the port number to use as the first VPN port for private networks.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment. It also will be ignored if the configuration option
-for `network_manager` is not set to the default of
-'nova.network.manager.VlanManager', or if you specify a value the 'vpn_start'
-parameter when creating a network.
-
-Possible values:
-
-* Any integer representing a valid port number. The default is 1000.
-
-Related options:
-
-* ``use_neutron``
-* ``vpn_ip``
-* ``network_manager``
-"""),
- cfg.IntOpt("network_size",
- default=256,
- min=1,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the number of addresses in each private subnet.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Possible values:
-
-* Any positive integer that is less than or equal to the available network
- size. Note that if you are creating multiple networks, they must all fit in
- the available IP address space. The default is 256.
-
-Related options:
-
-* ``use_neutron``
-* ``num_networks``
-"""),
- cfg.StrOpt("fixed_range_v6",
- default="fd00::/48",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the fixed IPv6 address block when creating a network.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Possible values:
-
-* Any valid IPv6 CIDR
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.StrOpt("gateway",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the default IPv4 gateway. It is used only in the testing suite.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Possible values:
-
-* Any valid IP address.
-
-Related options:
-
-* ``use_neutron``
-* ``gateway_v6``
-"""),
- cfg.StrOpt("gateway_v6",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the default IPv6 gateway. It is used only in the testing suite.
-
-Please note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Possible values:
-
-* Any valid IP address.
-
-Related options:
-
-* ``use_neutron``
-* ``gateway``
-"""),
- cfg.IntOpt("cnt_vpn_clients",
- default=0,
- min=0,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option represents the number of IP addresses to reserve at the top of the
-address range for VPN clients. It also will be ignored if the configuration
-option for `network_manager` is not set to the default of
-'nova.network.manager.VlanManager'.
-
-Possible values:
-
-* Any integer, 0 or greater.
-
-Related options:
-
-* ``use_neutron``
-* ``network_manager``
-"""),
- cfg.IntOpt("fixed_ip_disassociate_timeout",
- default=600,
- min=0,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the number of seconds to wait before disassociating a deallocated fixed
-IP address. This is only used with the nova-network service, and has no effect
-when using neutron for networking.
-
-Possible values:
-
-* Any integer, zero or greater.
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.IntOpt("create_unique_mac_address_attempts",
- default=5,
- min=1,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines how many times nova-network will attempt to create a
-unique MAC address before giving up and raising a
-`VirtualInterfaceMacAddressException` error.
-
-Possible values:
-
-* Any positive integer. The default is 5.
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.BoolOpt("teardown_unused_network_gateway",
- default=False,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Determines whether unused gateway devices, both VLAN and bridge, are deleted if
-the network is in nova-network VLAN mode and is multi-hosted.
-
-Related options:
-
-* ``use_neutron``
-* ``vpn_ip``
-* ``fake_network``
-"""),
- cfg.BoolOpt("force_dhcp_release",
- default=True,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-When this option is True, a call is made to release the DHCP for the instance
-when that instance is terminated.
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.BoolOpt("update_dns_entries",
- default=False,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-When this option is True, whenever a DNS entry must be updated, a fanout cast
-message is sent to all network hosts to update their DNS entries in multi-host
-mode.
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.IntOpt("dns_update_periodic_interval",
- default=-1,
- min=-1,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the time, in seconds, to wait between refreshing DNS
-entries for the network.
-
-Possible values:
-
-* A positive integer
-* -1 to disable updates
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.StrOpt("l3_lib",
- default="nova.network.l3.LinuxNetL3",
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option allows you to specify the L3 management library to be used.
-
-Possible values:
-
-* Any dot-separated string that represents the import path to an L3 networking
- library.
-
-Related options:
-
-* ``use_neutron``
-"""),
- cfg.BoolOpt("share_dhcp_address",
- default=False,
- deprecated_for_removal=True,
- deprecated_since='2014.2',
- help="""
-THIS VALUE SHOULD BE SET WHEN CREATING THE NETWORK.
-
-If True in multi_host mode, all compute hosts share the same dhcp address. The
-same IP address used for DHCP will be added on each nova-network node which is
-only visible to the VMs on the same host.
-
-The use of this configuration has been deprecated and may be removed in any
-release after Mitaka. It is recommended that instead of relying on this option,
-an explicit value should be passed to 'create_networks()' as a keyword argument
-with the name 'share_address'.
-"""),
-]
-
-linux_net_opts = [
- cfg.MultiStrOpt('dhcpbridge_flagfile',
- default=['/etc/nova/nova-dhcpbridge.conf'],
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option is a list of full paths to one or more configuration files for
-dhcpbridge. In most cases the default path of '/etc/nova/nova-dhcpbridge.conf'
-should be sufficient, but if you have special needs for configuring dhcpbridge,
-you can change or add to this list.
-
-Possible values
-
-* A list of strings, where each string is the full path to a dhcpbridge
- configuration file.
-"""),
- cfg.StrOpt('networks_path',
- default=paths.state_path_def('networks'),
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-The location where the network configuration files will be kept. The default is
-the 'networks' directory off of the location where nova's Python module is
-installed.
-
-Possible values
-
-* A string containing the full path to the desired configuration directory
-"""),
- cfg.StrOpt('public_interface',
- default='eth0',
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the name of the network interface for public IP addresses. The default
-is 'eth0'.
-
-Possible values:
-
-* Any string representing a network interface name
-"""),
- cfg.StrOpt('dhcpbridge',
- default=paths.bindir_def('nova-dhcpbridge'),
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-The location of the binary nova-dhcpbridge. By default it is the binary named
-'nova-dhcpbridge' that is installed with all the other nova binaries.
-
-Possible values:
-
-* Any string representing the full path to the binary for dhcpbridge
-"""),
- cfg.StrOpt('routing_source_ip',
- default='$my_ip',
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-The public IP address of the network host.
-
-This is used when creating an SNAT rule.
-
-Possible values:
-
-* Any valid IP address
-
-Related options:
-
-* ``force_snat_range``
-"""),
- cfg.IntOpt('dhcp_lease_time',
- default=86400,
- min=1,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-The lifetime of a DHCP lease, in seconds. The default is 86400 (one day).
-
-Possible values:
-
-* Any positive integer value.
-"""),
- cfg.MultiStrOpt("dns_server",
- default=[],
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Despite the singular form of the name of this option, it is actually a list of
-zero or more server addresses that dnsmasq will use for DNS nameservers. If
-this is not empty, dnsmasq will not read /etc/resolv.conf, but will only use
-the servers specified in this option. If the option use_network_dns_servers is
-True, the dns1 and dns2 servers from the network will be appended to this list,
-and will be used as DNS servers, too.
-
-Possible values:
-
-* A list of strings, where each string is either an IP address or a FQDN.
-
-Related options:
-
-* ``use_network_dns_servers``
-"""),
- cfg.BoolOpt("use_network_dns_servers",
- default=False,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-When this option is set to True, the dns1 and dns2 servers for the network
-specified by the user on boot will be used for DNS, as well as any specified in
-the `dns_server` option.
-
-Related options:
-
-* ``dns_server``
-"""),
- cfg.ListOpt("dmz_cidr",
- default=[],
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option is a list of zero or more IP address ranges in your network's DMZ
-that should be accepted.
-
-Possible values:
-
-* A list of strings, each of which should be a valid CIDR.
-"""),
- cfg.MultiStrOpt("force_snat_range",
- default=[],
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is a list of zero or more IP ranges that traffic from the
-`routing_source_ip` will be SNATted to. If the list is empty, then no SNAT
-rules are created.
-
-Possible values:
-
-* A list of strings, each of which should be a valid CIDR.
-
-Related options:
-
-* ``routing_source_ip``
-"""),
- cfg.StrOpt("dnsmasq_config_file",
- default="",
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-The path to the custom dnsmasq configuration file, if any.
-
-Possible values:
-
-* The full path to the configuration file, or an empty string if there is no
- custom dnsmasq configuration file.
-"""),
- cfg.StrOpt("linuxnet_interface_driver",
- default="nova.network.linux_net.LinuxBridgeInterfaceDriver",
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This is the class used as the ethernet device driver for linuxnet bridge
-operations. The default value should be all you need for most cases, but if you
-wish to use a customized class, set this option to the full dot-separated
-import path for that class.
-
-Possible values:
-
-* Any string representing a dot-separated class path that Nova can import.
-"""),
- cfg.StrOpt("linuxnet_ovs_integration_bridge",
- default="br-int",
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-The name of the Open vSwitch bridge that is used with linuxnet when connecting
-with Open vSwitch."
-
-Possible values:
-
-* Any string representing a valid bridge name.
-"""),
- cfg.BoolOpt("send_arp_for_ha",
- default=False,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-When True, when a device starts up, and upon binding floating IP addresses, arp
-messages will be sent to ensure that the arp caches on the compute hosts are
-up-to-date.
-
-Related options:
-
-* ``send_arp_for_ha_count``
-"""),
- cfg.IntOpt("send_arp_for_ha_count",
- default=3,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-When arp messages are configured to be sent, they will be sent with the count
-set to the value of this option. Of course, if this is set to zero, no arp
-messages will be sent.
-
-Possible values:
-
-* Any integer greater than or equal to 0
-
-Related options:
-
-* ``send_arp_for_ha``
-"""),
- cfg.BoolOpt("use_single_default_gateway",
- default=False,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-When set to True, only the firt nic of a VM will get its default gateway from
-the DHCP server.
-"""),
- cfg.MultiStrOpt("forward_bridge_interface",
- default=["all"],
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-One or more interfaces that bridges can forward traffic to. If any of the items
-in this list is the special keyword 'all', then all traffic will be forwarded.
-
-Possible values:
-
-* A list of zero or more interface names, or the word 'all'.
-"""),
- cfg.StrOpt("metadata_host",
- default="$my_ip",
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the IP address for the network metadata API server.
-
-This is really the client side of the metadata host equation that allows
-nova-network to find the metadata server when doing a default multi host
-networking.
-
-Possible values:
-
-* Any valid IP address. The default is the address of the Nova API server.
-
-Related options:
-
-* ``metadata_port``
-"""),
- cfg.PortOpt("metadata_port",
- default=8775,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the port used for the metadata API server.
-
-Related options:
-
-* ``metadata_host``
-"""),
- cfg.StrOpt("iptables_top_regex",
- default="",
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This expression, if defined, will select any matching iptables rules and place
-them at the top when applying metadata changes to the rules.
-
-Possible values:
-
-* Any string representing a valid regular expression, or an empty string
-
-Related options:
-
-* ``iptables_bottom_regex``
-"""),
- cfg.StrOpt("iptables_bottom_regex",
- default="",
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This expression, if defined, will select any matching iptables rules and place
-them at the bottom when applying metadata changes to the rules.
-
-Possible values:
-
-* Any string representing a valid regular expression, or an empty string
-
-Related options:
-
-* iptables_top_regex
-"""),
- cfg.StrOpt("iptables_drop_action",
- default="DROP",
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-By default, packets that do not pass the firewall are DROPped. In many cases,
-though, an operator may find it more useful to change this from DROP to REJECT,
-so that the user issuing those packets may have a better idea as to what's
-going on, or LOGDROP in order to record the blocked traffic before DROPping.
-
-Possible values:
-
-* A string representing an iptables chain. The default is DROP.
-"""),
- cfg.BoolOpt('defer_iptables_apply',
- default=False,
- deprecated_for_removal=True,
- deprecated_since="19.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Defer application of IPTables rules until after init phase.
-
-When a compute service is restarted each instance running on the host has its
-iptables rules built and applied sequentially during the host init stage. The
-impact of this, especially on a host running many instances, can be observed as
-a period where some instances are not accessible as the existing iptables rules
-have been torn down and not yet re-applied.
-
-This is a workaround that prevents the application of the iptables rules until
-all instances on the host had been initialised then the rules for all instances
-are applied all at once preventing a 'blackout' period.
-"""),
- cfg.IntOpt("ovs_vsctl_timeout",
- default=120,
- min=0,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option represents the period of time, in seconds, that the ovs_vsctl calls
-will wait for a response from the database before timing out. A setting of 0
-means that the utility should wait forever for a response.
-
-Possible values:
-
-* Any positive integer if a limited timeout is desired, or zero if the calls
- should wait forever for a response.
-"""),
- cfg.BoolOpt("fake_network",
- default=False,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option is used mainly in testing to avoid calls to the underlying network
-utilities.
-"""),
- cfg.IntOpt("ebtables_exec_attempts",
- default=3,
- min=1,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the number of times to retry ebtables commands before
-giving up. The minimum number of retries is 1.
-
-Possible values:
-
-* Any positive integer
-
-Related options:
-
-* ``ebtables_retry_interval``
-"""),
- cfg.FloatOpt("ebtables_retry_interval",
- default=1.0,
- deprecated_for_removal=True,
- deprecated_since="16.0.0",
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-This option determines the time, in seconds, that the system will sleep in
-between ebtables retries. Note that each successive retry waits a multiple of
-this value, so for example, if this is set to the default of 1.0 seconds, and
-ebtables_exec_attempts is 4, after the first failure, the system will sleep for
-1 * 1.0 seconds, after the second failure it will sleep 2 * 1.0 seconds, and
-after the third failure it will sleep 3 * 1.0 seconds.
-
-Possible values:
-
-* Any non-negative float or integer. Setting this to zero will result in no
- waiting between attempts.
-
-Related options:
-
-* ebtables_exec_attempts
-"""),
-]
-
-ldap_dns_opts = [
- cfg.URIOpt('ldap_dns_url',
- default='ldap://ldap.example.com:389',
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-URL for LDAP server which will store DNS entries
-
-Possible values:
-
-* A valid LDAP URL representing the server
-"""),
- cfg.StrOpt('ldap_dns_user',
- default='uid=admin,ou=people,dc=example,dc=org',
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help='Bind user for LDAP server'),
- cfg.StrOpt('ldap_dns_password',
- default='password',
- secret=True,
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="Bind user's password for LDAP server"),
- cfg.StrOpt('ldap_dns_soa_hostmaster',
- default='hostmaster@example.org',
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Hostmaster for LDAP DNS driver Statement of Authority
-
-Possible values:
-
-* Any valid string representing LDAP DNS hostmaster.
-"""),
- cfg.MultiStrOpt('ldap_dns_servers',
- default=['dns.example.org'],
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-DNS Servers for LDAP DNS driver
-
-Possible values:
-
-* A valid URL representing a DNS server
-"""),
- cfg.StrOpt('ldap_dns_base_dn',
- default='ou=hosts,dc=example,dc=org',
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Base distinguished name for the LDAP search query
-
-This option helps to decide where to look up the host in LDAP.
-"""),
- cfg.IntOpt('ldap_dns_soa_refresh',
- default=1800,
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Refresh interval (in seconds) for LDAP DNS driver Start of Authority
-
-Time interval, a secondary/slave DNS server waits before requesting for
-primary DNS server's current SOA record. If the records are different,
-secondary DNS server will request a zone transfer from primary.
-
-NOTE: Lower values would cause more traffic.
-"""),
- cfg.IntOpt('ldap_dns_soa_retry',
- default=3600,
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Retry interval (in seconds) for LDAP DNS driver Start of Authority
-
-Time interval, a secondary/slave DNS server should wait, if an
-attempt to transfer zone failed during the previous refresh interval.
-"""),
- cfg.IntOpt('ldap_dns_soa_expiry',
- default=86400,
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Expiry interval (in seconds) for LDAP DNS driver Start of Authority
-
-Time interval, a secondary/slave DNS server holds the information
-before it is no longer considered authoritative.
-"""),
- cfg.IntOpt('ldap_dns_soa_minimum',
- default=7200,
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Minimum interval (in seconds) for LDAP DNS driver Start of Authority
-
-It is Minimum time-to-live applies for all resource records in the
-zone file. This value is supplied to other servers how long they
-should keep the data in cache.
-"""),
-]
-
-driver_opts = [
- cfg.StrOpt('network_driver',
- default='nova.network.linux_net',
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Driver to use for network creation.
-
-Network driver initializes (creates bridges and so on) only when the
-first VM lands on a host node. All network managers configure the
-network using network drivers. The driver is not tied to any particular
-network manager.
-
-The default Linux driver implements vlans, bridges, and iptables rules
-using linux utilities.
-
-Note that this option is only used when using nova-network instead
-of Neutron in your deployment.
-
-Related options:
-
-* ``use_neutron``
-"""),
-]
-
-rpcapi_opts = [
- cfg.BoolOpt('multi_host',
- default=False,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Default value for multi_host in networks.
-
-nova-network service can operate in a multi-host or single-host mode.
-In multi-host mode each compute node runs a copy of nova-network and the
-instances on that compute node use the compute node as a gateway to the
-Internet. Where as in single-host mode, a central server runs the nova-network
-service. All compute nodes forward traffic from the instances to the
-cloud controller which then forwards traffic to the Internet.
-
-If this options is set to true, some rpc network calls will be sent directly
-to host.
-
-Note that this option is only used when using nova-network instead of
-Neutron in your deployment.
-
-Related options:
-
-* ``use_neutron``
-""")
-]
-
-floating_ip_opts = [
- cfg.StrOpt('default_floating_pool',
- default='nova',
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-This option was used for two purposes: to set the floating IP pool name for
-nova-network and to do the same for neutron. nova-network is deprecated, as are
-any related configuration options. Users of neutron, meanwhile, should use the
-'default_floating_pool' option in the '[neutron]' group.
-""",
- help="""
-Default pool for floating IPs.
-
-This option specifies the default floating IP pool for allocating floating IPs.
-
-While allocating a floating ip, users can optionally pass in the name of the
-pool they want to allocate from, otherwise it will be pulled from the
-default pool.
-
-If this option is not set, then 'nova' is used as default floating pool.
-
-Possible values:
-
-* Any string representing a floating IP pool name
-"""),
- cfg.BoolOpt('auto_assign_floating_ip',
- default=False,
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Autoassigning floating IP to VM
-
-When set to True, floating IP is auto allocated and associated
-to the VM upon creation.
-
-Related options:
-
-* use_neutron: this options only works with nova-network.
-"""),
- cfg.StrOpt('floating_ip_dns_manager',
- default='nova.network.noop_dns_driver.NoopDNSDriver',
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Full class name for the DNS Manager for floating IPs.
-
-This option specifies the class of the driver that provides functionality
-to manage DNS entries associated with floating IPs.
-
-When a user adds a DNS entry for a specified domain to a floating IP,
-nova will add a DNS entry using the specified floating DNS driver.
-When a floating IP is deallocated, its DNS entry will automatically be deleted.
-
-Possible values:
-
-* Full Python path to the class to be used
-
-Related options:
-
-* use_neutron: this options only works with nova-network.
-"""),
- cfg.StrOpt('instance_dns_manager',
- default='nova.network.noop_dns_driver.NoopDNSDriver',
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Full class name for the DNS Manager for instance IPs.
-
-This option specifies the class of the driver that provides functionality
-to manage DNS entries for instances.
-
-On instance creation, nova will add DNS entries for the instance name and
-id, using the specified instance DNS driver and domain. On instance deletion,
-nova will remove the DNS entries.
-
-Possible values:
-
-* Full Python path to the class to be used
-
-Related options:
-
-* use_neutron: this options only works with nova-network.
-"""),
- cfg.StrOpt('instance_dns_domain',
- default='',
- deprecated_for_removal=True,
- deprecated_since='15.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-If specified, Nova checks if the availability_zone of every instance matches
-what the database says the availability_zone should be for the specified
-dns_domain.
-
-Related options:
-
-* use_neutron: this options only works with nova-network.
-""")
-]
-
-ipv6_opts = [
- cfg.BoolOpt('use_ipv6',
- default=False,
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Assign IPv6 and IPv4 addresses when creating instances.
-
-Related options:
-
-* use_neutron: this only works with nova-network.
-"""),
- cfg.StrOpt('ipv6_backend',
- default='rfc2462',
- choices=('rfc2462', 'account_identifier'),
- deprecated_for_removal=True,
- deprecated_since='16.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help="""
-Abstracts out IPv6 address generation to pluggable backends.
-
-nova-network can be put into dual-stack mode, so that it uses
-both IPv4 and IPv6 addresses. In dual-stack mode, by default, instances
-acquire IPv6 global unicast addresses with the help of stateless address
-auto-configuration mechanism.
-
-Related options:
-
-* use_neutron: this option only works with nova-network.
-* use_ipv6: this option only works if ipv6 is enabled for nova-network.
-"""),
-]
-
-
-service_opts = [
- cfg.StrOpt('network_manager',
- choices=[
- 'nova.network.manager.FlatManager',
- 'nova.network.manager.FlatDHCPManager',
- 'nova.network.manager.VlanManager',
- ],
- default='nova.network.manager.VlanManager',
- deprecated_for_removal=True,
- deprecated_since='18.0.0',
- deprecated_reason="""
-nova-network is deprecated, as are any related configuration options.
-""",
- help='Full class name for the Manager for network'),
-]
-
-
-ALL_DEFAULT_OPTS = (linux_net_opts + network_opts + ldap_dns_opts +
- rpcapi_opts + driver_opts + floating_ip_opts +
- ipv6_opts + service_opts)
-
-
-def register_opts(conf):
- conf.register_opts(ALL_DEFAULT_OPTS)
-
-
-def list_opts():
- return {"DEFAULT": ALL_DEFAULT_OPTS}
diff --git a/nova/conf/upgrade_levels.py b/nova/conf/upgrade_levels.py
index 19cc5e23b3..b15f5b0ee1 100644
--- a/nova/conf/upgrade_levels.py
+++ b/nova/conf/upgrade_levels.py
@@ -102,24 +102,6 @@ Possible values:
* An OpenStack release name, in lower case, such as 'mitaka' or
'liberty'.
"""),
- cfg.StrOpt('network',
- deprecated_for_removal=True,
- deprecated_since='18.0.0',
- deprecated_reason="""
-The nova-network service was deprecated in 14.0.0 (Newton) and will be
-removed in an upcoming release.
-""",
- help="""
-Network RPC API version cap.
-
-Possible values:
-
-* By default send the latest version the client knows about
-* A string representing a version number in the format 'N.N';
- for example, possible values might be '1.12' or '2.0'.
-* An OpenStack release name, in lower case, such as 'mitaka' or
- 'liberty'.
-"""),
cfg.StrOpt('baseapi',
help="""
Base API RPC API version cap.
diff --git a/nova/db/api.py b/nova/db/api.py
index 4f3c8e9982..a6845810fe 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -499,31 +499,6 @@ def floating_ip_update(context, address, values):
return IMPL.floating_ip_update(context, address, values)
-def dnsdomain_get_all(context):
- """Get a list of all dnsdomains in our database."""
- return IMPL.dnsdomain_get_all(context)
-
-
-def dnsdomain_register_for_zone(context, fqdomain, zone):
- """Associated a DNS domain with an availability zone."""
- return IMPL.dnsdomain_register_for_zone(context, fqdomain, zone)
-
-
-def dnsdomain_register_for_project(context, fqdomain, project):
- """Associated a DNS domain with a project id."""
- return IMPL.dnsdomain_register_for_project(context, fqdomain, project)
-
-
-def dnsdomain_unregister(context, fqdomain):
- """Purge associations for the specified DNS zone."""
- return IMPL.dnsdomain_unregister(context, fqdomain)
-
-
-def dnsdomain_get(context, fqdomain):
- """Get the db record for the specified domain."""
- return IMPL.dnsdomain_get(context, fqdomain)
-
-
####################
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 3e52b30d39..4009b90425 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1182,58 +1182,6 @@ def floating_ip_update(context, address, values):
###################
-@require_context
-@pick_context_manager_reader
-def dnsdomain_get(context, fqdomain):
- return model_query(context, models.DNSDomain, read_deleted="no").\
- filter_by(domain=fqdomain).\
- with_for_update().\
- first()
-
-
-def _dnsdomain_get_or_create(context, fqdomain):
- domain_ref = dnsdomain_get(context, fqdomain)
- if not domain_ref:
- dns_ref = models.DNSDomain()
- dns_ref.update({'domain': fqdomain,
- 'availability_zone': None,
- 'project_id': None})
- return dns_ref
-
- return domain_ref
-
-
-@pick_context_manager_writer
-def dnsdomain_register_for_zone(context, fqdomain, zone):
- domain_ref = _dnsdomain_get_or_create(context, fqdomain)
- domain_ref.scope = 'private'
- domain_ref.availability_zone = zone
- context.session.add(domain_ref)
-
-
-@pick_context_manager_writer
-def dnsdomain_register_for_project(context, fqdomain, project):
- domain_ref = _dnsdomain_get_or_create(context, fqdomain)
- domain_ref.scope = 'public'
- domain_ref.project_id = project
- context.session.add(domain_ref)
-
-
-@pick_context_manager_writer
-def dnsdomain_unregister(context, fqdomain):
- model_query(context, models.DNSDomain).\
- filter_by(domain=fqdomain).\
- delete()
-
-
-@pick_context_manager_reader
-def dnsdomain_get_all(context):
- return model_query(context, models.DNSDomain, read_deleted="no").all()
-
-
-###################
-
-
@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True)
@pick_context_manager_writer
def fixed_ip_associate(context, address, instance_uuid, network_id=None,
@@ -5329,6 +5277,7 @@ def _archive_deleted_rows_for_table(metadata, tablename, max_rows, before):
# No corresponding shadow table; skip it.
return rows_archived, deleted_instance_uuids
+ # TODO(stephenfin): Drop this when we drop the table
if tablename == "dns_domains":
# We have one table (dns_domains) where the key is called
# "domain" rather than "id"
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index c6f43ef763..8ae9415145 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -971,6 +971,7 @@ class FloatingIp(BASE, NovaBase, models.SoftDeleteMixin):
'FixedIp.deleted == 0)')
+# TODO(stephenfin): Remove in V or later
class DNSDomain(BASE, NovaBase, models.SoftDeleteMixin):
"""Represents a DNS domain with availability zone or project info."""
__tablename__ = 'dns_domains'
diff --git a/nova/ipv6/__init__.py b/nova/ipv6/__init__.py
deleted file mode 100644
index 05bd0358a7..0000000000
--- a/nova/ipv6/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2011 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from nova.ipv6.api import * # noqa
diff --git a/nova/ipv6/account_identifier.py b/nova/ipv6/account_identifier.py
deleted file mode 100644
index a8da65764f..0000000000
--- a/nova/ipv6/account_identifier.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2011 Justin Santa Barbara
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""IPv6 address generation with account identifier embedded."""
-
-import hashlib
-
-import netaddr
-import six
-
-from nova.i18n import _
-
-
-def to_global(prefix, mac, project_id):
- addr = project_id
- if isinstance(addr, six.text_type):
- addr = addr.encode('utf-8')
- addr = hashlib.sha1(addr)
- addr = int(addr.hexdigest()[:8], 16) << 32
-
- project_hash = netaddr.IPAddress(addr)
- static_num = netaddr.IPAddress(0xff << 24)
-
- try:
- mac_suffix = netaddr.EUI(mac).value & 0xffffff
- mac_addr = netaddr.IPAddress(mac_suffix)
- except netaddr.AddrFormatError:
- raise TypeError(_('Bad mac for to_global_ipv6: %s') % mac)
-
- try:
- maskIP = netaddr.IPNetwork(prefix).ip
- return (project_hash ^ static_num ^ mac_addr | maskIP).format()
- except netaddr.AddrFormatError:
- raise TypeError(_('Bad prefix for to_global_ipv6: %s') % prefix)
-
-
-def to_mac(ipv6_address):
- address = netaddr.IPAddress(ipv6_address)
- mask1 = netaddr.IPAddress('::ff:ffff')
- mac = netaddr.EUI(int(address & mask1)).words
- return ':'.join(['02', '16', '3e'] + ['%02x' % i for i in mac[3:6]])
diff --git a/nova/ipv6/api.py b/nova/ipv6/api.py
deleted file mode 100644
index 478fc1f141..0000000000
--- a/nova/ipv6/api.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (c) 2011 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from stevedore import driver
-
-import nova.conf
-
-CONF = nova.conf.CONF
-IMPL = None
-
-
-def reset_backend():
- global IMPL
- IMPL = driver.DriverManager("nova.ipv6_backend",
- CONF.ipv6_backend).driver
-
-
-def to_global(prefix, mac, project_id):
- return IMPL.to_global(prefix, mac, project_id)
-
-
-def to_mac(ipv6_address):
- return IMPL.to_mac(ipv6_address)
-
-
-reset_backend()
diff --git a/nova/ipv6/rfc2462.py b/nova/ipv6/rfc2462.py
deleted file mode 100644
index 9d62f24423..0000000000
--- a/nova/ipv6/rfc2462.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2011 Justin Santa Barbara
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""RFC2462 style IPv6 address generation."""
-
-import netaddr
-
-from nova.i18n import _
-
-
-def to_global(prefix, mac, project_id):
- try:
- mac64 = netaddr.EUI(mac).modified_eui64().value
- mac64_addr = netaddr.IPAddress(mac64)
- except netaddr.AddrFormatError:
- raise TypeError(_('Bad mac for to_global_ipv6: %s') % mac)
-
- try:
- maskIP = netaddr.IPNetwork(prefix).ip
- return (mac64_addr | maskIP).format()
- except netaddr.AddrFormatError:
- raise TypeError(_('Bad prefix for to_global_ipv6: %s') % prefix)
-
-
-def to_mac(ipv6_address):
- address = netaddr.IPAddress(ipv6_address)
- mask1 = netaddr.IPAddress('::ffff:ffff:ffff:ffff')
- mask2 = netaddr.IPAddress('::0200:0:0:0')
- mac64 = netaddr.EUI(int(address & mask1 ^ mask2)).words
- return ':'.join(['%02x' % i for i in mac64[0:3] + mac64[5:8]])
diff --git a/nova/network/__init__.py b/nova/network/__init__.py
index 73835e2a9f..5df6240544 100644
--- a/nova/network/__init__.py
+++ b/nova/network/__init__.py
@@ -16,28 +16,8 @@
from oslo_utils import importutils
-import nova.conf
-
-NOVA_NET_API = 'nova.network.api.API'
-NEUTRON_NET_API = 'nova.network.neutronv2.api.API'
-
-
-CONF = nova.conf.CONF
-
-
-def is_neutron():
- """Does this configuration mean we're neutron.
-
- This logic exists as a separate config option
- """
- return CONF.use_neutron
-
+# TODO(stephenfin): Remove this layer of indirection
def API():
- if is_neutron():
- network_api_class = NEUTRON_NET_API
- else:
- network_api_class = NOVA_NET_API
-
- cls = importutils.import_class(network_api_class)
+ cls = importutils.import_class('nova.network.neutronv2.api.API')
return cls()
diff --git a/nova/network/api.py b/nova/network/api.py
deleted file mode 100644
index ba2ef9ea14..0000000000
--- a/nova/network/api.py
+++ /dev/null
@@ -1,511 +0,0 @@
-# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo_config import cfg
-from oslo_log import log as logging
-from oslo_utils import strutils
-
-from nova import exception
-from nova.network import base_api
-from nova.network import floating_ips
-from nova.network import model as network_model
-from nova.network import rpcapi as network_rpcapi
-from nova import objects
-from nova.objects import base as obj_base
-from nova import profiler
-from nova import utils
-
-CONF = cfg.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-@profiler.trace_cls("network_api")
-class API(base_api.NetworkAPI):
- """API for doing networking via the nova-network network manager.
-
- This is a pluggable module - other implementations do networking via
- other services (such as Neutron).
- """
- def __init__(self, **kwargs):
- self.network_rpcapi = network_rpcapi.NetworkAPI()
- helper = utils.ExceptionHelper
- # NOTE(vish): this local version of floating_manager has to convert
- # ClientExceptions back since they aren't going over rpc.
- self.floating_manager = helper(floating_ips.LocalManager())
- super(API, self).__init__(**kwargs)
-
- def get_all(self, context):
- """Get all the networks.
-
- If it is an admin user then api will return all the
- networks. If it is a normal user and nova Flat or FlatDHCP
- networking is being used then api will return all
- networks. Otherwise api will only return the networks which
- belong to the user's project.
- """
- if "nova.network.manager.Flat" in CONF.network_manager:
- project_only = "allow_none"
- else:
- project_only = True
- try:
- return objects.NetworkList.get_all(context,
- project_only=project_only)
- except exception.NoNetworksFound:
- return []
-
- def get(self, context, network_uuid):
- return objects.Network.get_by_uuid(context, network_uuid)
-
- def create(self, context, **kwargs):
- return self.network_rpcapi.create_networks(context, **kwargs)
-
- def delete(self, context, network_uuid):
- network = self.get(context, network_uuid)
- if network.project_id is not None:
- raise exception.NetworkInUse(network_id=network_uuid)
- return self.network_rpcapi.delete_network(context, network_uuid, None)
-
- def get_fixed_ip(self, context, id):
- return objects.FixedIP.get_by_id(context, id)
-
- def get_fixed_ip_by_address(self, context, address):
- return objects.FixedIP.get_by_address(context, address)
-
- def get_floating_ip(self, context, id):
- if not strutils.is_int_like(id):
- raise exception.InvalidID(id=id)
- return objects.FloatingIP.get_by_id(context, id)
-
- def get_floating_ip_pools(self, context):
- return objects.FloatingIP.get_pool_names(context)
-
- def get_floating_ip_by_address(self, context, address):
- return objects.FloatingIP.get_by_address(context, address)
-
- def get_floating_ips_by_project(self, context):
- return objects.FloatingIPList.get_by_project(context,
- context.project_id)
-
- def get_instance_id_by_floating_address(self, context, address):
- fixed_ip = objects.FixedIP.get_by_floating_address(context, address)
- if fixed_ip is None:
- return None
- else:
- return fixed_ip.instance_uuid
-
- def get_vifs_by_instance(self, context, instance):
- vifs = objects.VirtualInterfaceList.get_by_instance_uuid(context,
- instance.uuid)
- for vif in vifs:
- if vif.network_id is not None:
- network = objects.Network.get_by_id(context, vif.network_id,
- project_only='allow_none')
- vif.net_uuid = network.uuid
- return vifs
-
- def get_vif_by_mac_address(self, context, mac_address):
- vif = objects.VirtualInterface.get_by_address(context,
- mac_address)
- if vif.network_id is not None:
- network = objects.Network.get_by_id(context, vif.network_id,
- project_only='allow_none')
- vif.net_uuid = network.uuid
- return vif
-
- def allocate_floating_ip(self, context, pool=None):
- """Adds (allocates) a floating IP to a project from a pool."""
- return self.floating_manager.allocate_floating_ip(context,
- context.project_id, False, pool)
-
- def release_floating_ip(self, context, address,
- affect_auto_assigned=False):
- """Removes (deallocates) a floating IP with address from a project."""
- return self.floating_manager.deallocate_floating_ip(context, address,
- affect_auto_assigned)
-
- def disassociate_and_release_floating_ip(self, context, instance,
- floating_ip):
- """Removes (deallocates) and deletes the floating IP.
-
- This api call was added to allow this to be done in one operation
- if using neutron.
- """
-
- address = floating_ip['address']
- if floating_ip.get('fixed_ip_id'):
- try:
- self.disassociate_floating_ip(context, instance, address)
- except exception.FloatingIpNotAssociated:
- msg = ("Floating IP %s has already been disassociated, "
- "perhaps by another concurrent action.") % address
- LOG.debug(msg)
-
- # release ip from project
- return self.release_floating_ip(context, address)
-
- @base_api.refresh_cache
- def associate_floating_ip(self, context, instance,
- floating_address, fixed_address,
- affect_auto_assigned=False):
- """Associates a floating IP with a fixed IP.
-
- Ensures floating IP is allocated to the project in context.
- Does not verify ownership of the fixed IP. Caller is assumed to have
- checked that the instance is properly owned.
-
- """
- orig_instance_uuid = self.floating_manager.associate_floating_ip(
- context, floating_address, fixed_address, affect_auto_assigned)
-
- if orig_instance_uuid:
- msg_dict = dict(address=floating_address,
- instance_id=orig_instance_uuid)
- LOG.info('re-assign floating IP %(address)s from '
- 'instance %(instance_id)s', msg_dict)
- orig_instance = objects.Instance.get_by_uuid(
- context, orig_instance_uuid, expected_attrs=['flavor'])
-
- # purge cached nw info for the original instance
- base_api.update_instance_cache_with_nw_info(self, context,
- orig_instance)
-
- @base_api.refresh_cache
- def disassociate_floating_ip(self, context, instance, address,
- affect_auto_assigned=False):
- """Disassociates a floating IP from fixed IP it is associated with."""
- return self.floating_manager.disassociate_floating_ip(context, address,
- affect_auto_assigned)
-
- @staticmethod
- def _requested_nets_as_obj_list(requested_networks):
- """Helper method to convert a list of requested network tuples into an
- objects.NetworkRequestList.
-
- :param requested_networks: List of requested networks.
- :return: objects.NetworkRequestList instance
- """
- if requested_networks and not isinstance(requested_networks,
- objects.NetworkRequestList):
- requested_networks = objects.NetworkRequestList.from_tuples(
- requested_networks)
- return requested_networks
-
- @base_api.refresh_cache
- def allocate_for_instance(self, context, instance, vpn,
- requested_networks,
- security_groups=None,
- bind_host_id=None, attach=False,
- resource_provider_mapping=None):
- """Allocates all network structures for an instance.
-
- :param context: The request context.
- :param instance: nova.objects.instance.Instance object.
- :param vpn: A boolean, if True, indicate a vpn to access the instance.
- :param requested_networks: A list of requested_network tuples
- containing network_id and fixed_ip
- :param security_groups: None or security groups to allocate for
- instance.
- :param bind_host_id: ignored by this driver.
- :param attach: ignored by this driver
- :param resource_provider_mapping: ignored by this driver
- :returns: network info as from get_instance_nw_info() below
- """
- # NOTE(vish): We can't do the floating ip allocation here because
- # this is called from compute.manager which shouldn't
- # have db access so we do it on the other side of the
- # rpc.
- flavor = instance.get_flavor()
- args = {}
- args['vpn'] = vpn
- args['requested_networks'] = requested_networks
- args['instance_id'] = instance.uuid
- args['project_id'] = instance.project_id
- args['host'] = instance.host
- args['rxtx_factor'] = flavor['rxtx_factor']
-
- # Check to see if we're asked to 'auto' allocate networks because if
- # so we need to just null out the requested_networks value so the
- # network manager doesn't try to get networks with uuid 'auto' which
- # doesn't exist.
- if requested_networks:
- requested_networks = self._requested_nets_as_obj_list(
- requested_networks)
-
- if requested_networks.auto_allocate:
- args['requested_networks'] = None
-
- nw_info = self.network_rpcapi.allocate_for_instance(context, **args)
-
- nw_info = network_model.NetworkInfo.hydrate(nw_info)
-
- # check to see if nothing was allocated and we were requested to
- # auto-allocate
- if (not nw_info and requested_networks and
- requested_networks.auto_allocate):
- raise exception.UnableToAutoAllocateNetwork(
- project_id=instance.project_id)
-
- return nw_info
-
- def deallocate_for_instance(self, context, instance,
- requested_networks=None):
- """Deallocates all network structures related to instance."""
- # NOTE(vish): We can't do the floating ip deallocation here because
- # this is called from compute.manager which shouldn't
- # have db access so we do it on the other side of the
- # rpc.
- if not isinstance(instance, obj_base.NovaObject):
- instance = objects.Instance._from_db_object(context,
- objects.Instance(), instance)
-
- # In the case of 'auto' allocation for networks, just pass None for
- # requested_networks since 'auto' isn't an actual network.
- requested_networks = self._requested_nets_as_obj_list(
- requested_networks)
- if requested_networks and requested_networks.auto_allocate:
- requested_networks = None
-
- self.network_rpcapi.deallocate_for_instance(context, instance=instance,
- requested_networks=requested_networks)
-
- # NOTE(danms): Here for neutron compatibility
- def allocate_port_for_instance(self, context, instance, port_id,
- network_id=None, requested_ip=None,
- bind_host_id=None, tag=None):
- raise NotImplementedError()
-
- # NOTE(danms): Here for neutron compatibility
- def deallocate_port_for_instance(self, context, instance, port_id):
- raise NotImplementedError()
-
- # NOTE(danms): Here for neutron compatibility
- def list_ports(self, *args, **kwargs):
- raise NotImplementedError()
-
- # NOTE(danms): Here for neutron compatibility
- def show_port(self, *args, **kwargs):
- raise NotImplementedError()
-
- @base_api.refresh_cache
- def add_fixed_ip_to_instance(self, context, instance, network_id):
- """Adds a fixed IP to instance from specified network."""
- flavor = instance.get_flavor()
- args = {'instance_id': instance.uuid,
- 'rxtx_factor': flavor['rxtx_factor'],
- 'host': instance.host,
- 'network_id': network_id}
- nw_info = self.network_rpcapi.add_fixed_ip_to_instance(
- context, **args)
- return network_model.NetworkInfo.hydrate(nw_info)
-
- @base_api.refresh_cache
- def remove_fixed_ip_from_instance(self, context, instance, address):
- """Removes a fixed IP from instance from specified network."""
-
- flavor = instance.get_flavor()
- args = {'instance_id': instance.uuid,
- 'rxtx_factor': flavor['rxtx_factor'],
- 'host': instance.host,
- 'address': address}
- nw_info = self.network_rpcapi.remove_fixed_ip_from_instance(
- context, **args)
- return network_model.NetworkInfo.hydrate(nw_info)
-
- def _get_instance_nw_info(self, context, instance, **kwargs):
- """Returns all network info related to an instance."""
- flavor = instance.get_flavor()
- args = {'instance_id': instance.uuid,
- 'rxtx_factor': flavor['rxtx_factor'],
- 'host': instance.host,
- 'project_id': instance.project_id}
- nw_info = self.network_rpcapi.get_instance_nw_info(context, **args)
-
- return network_model.NetworkInfo.hydrate(nw_info)
-
- def validate_networks(self, context, requested_networks, num_instances):
- """validate the networks passed at the time of creating
- the server.
-
- Return the number of instances that can be successfully allocated
- with the requested network configuration.
- """
- if requested_networks:
- self.network_rpcapi.validate_networks(context,
- requested_networks)
-
- # Neutron validation checks and returns how many of num_instances
- # instances can be supported by the quota. For Nova network
- # this is part of the subsequent quota check, so we just return
- # the requested number in this case.
- return num_instances
-
- def create_resource_requests(
- self, context, requested_networks, pci_requests=None,
- affinity_policy=None):
- """Retrieve all information for the networks passed at the time of
- creating the server.
-
- :param context: The request context.
- :param requested_networks: The networks requested for the server.
- :type requested_networks: nova.objects.NetworkRequestList
- :param pci_requests: The list of PCI requests to which additional PCI
- requests created here will be added.
- :type pci_requests: nova.objects.InstancePCIRequests
- :param affinity_policy: requested pci numa affinity policy
- :type affinity_policy: nova.objects.fields.PCINUMAAffinityPolicy
-
- :returns: A tuple with an instance of ``objects.NetworkMetadata`` for
- use by the scheduler or None and a list of RequestGroup
- objects representing the resource needs of each requested
- port
- """
- # This is NOOP for Nova network since it doesn't support SR-IOV or
- # NUMA-aware vSwitch functionality.
- return None, []
-
- def get_dns_domains(self, context):
- """Returns a list of available dns domains.
- These can be used to create DNS entries for floating IPs.
- """
- return self.network_rpcapi.get_dns_domains(context)
-
- def add_dns_entry(self, context, address, name, dns_type, domain):
- """Create specified DNS entry for address."""
- args = {'address': address,
- 'name': name,
- 'dns_type': dns_type,
- 'domain': domain}
- return self.network_rpcapi.add_dns_entry(context, **args)
-
- def modify_dns_entry(self, context, name, address, domain):
- """Create specified DNS entry for address."""
- args = {'address': address,
- 'name': name,
- 'domain': domain}
- return self.network_rpcapi.modify_dns_entry(context, **args)
-
- def delete_dns_entry(self, context, name, domain):
- """Delete the specified dns entry."""
- args = {'name': name, 'domain': domain}
- return self.network_rpcapi.delete_dns_entry(context, **args)
-
- def delete_dns_domain(self, context, domain):
- """Delete the specified dns domain."""
- return self.network_rpcapi.delete_dns_domain(context, domain=domain)
-
- def get_dns_entries_by_address(self, context, address, domain):
- """Get entries for address and domain."""
- args = {'address': address, 'domain': domain}
- return self.network_rpcapi.get_dns_entries_by_address(context, **args)
-
- def get_dns_entries_by_name(self, context, name, domain):
- """Get entries for name and domain."""
- args = {'name': name, 'domain': domain}
- return self.network_rpcapi.get_dns_entries_by_name(context, **args)
-
- def create_private_dns_domain(self, context, domain, availability_zone):
- """Create a private DNS domain with nova availability zone."""
- args = {'domain': domain, 'av_zone': availability_zone}
- return self.network_rpcapi.create_private_dns_domain(context, **args)
-
- def create_public_dns_domain(self, context, domain, project=None):
- """Create a public DNS domain with optional nova project."""
- args = {'domain': domain, 'project': project}
- return self.network_rpcapi.create_public_dns_domain(context, **args)
-
- def setup_networks_on_host(self, context, instance, host=None,
- teardown=False):
- """Setup or teardown the network structures on hosts related to
- instance.
- """
- host = host or instance.host
- # NOTE(tr3buchet): host is passed in cases where we need to setup
- # or teardown the networks on a host which has been migrated to/from
- # and instance.host is not yet or is no longer equal to
- args = {'instance_id': instance.id,
- 'host': host,
- 'teardown': teardown,
- 'instance': instance}
-
- self.network_rpcapi.setup_networks_on_host(context, **args)
-
- def _get_multi_addresses(self, context, instance):
- try:
- fixed_ips = objects.FixedIPList.get_by_instance_uuid(
- context, instance.uuid)
- except exception.FixedIpNotFoundForInstance:
- return False, []
- addresses = []
- for fixed in fixed_ips:
- for floating in fixed.floating_ips:
- addresses.append(floating.address)
- return fixed_ips[0].network.multi_host, addresses
-
- def migrate_instance_start(self, context, instance, migration):
- """Start to migrate the network of an instance."""
- flavor = instance.get_flavor()
- args = dict(
- instance_uuid=instance.uuid,
- rxtx_factor=flavor['rxtx_factor'],
- project_id=instance.project_id,
- source_compute=migration['source_compute'],
- dest_compute=migration['dest_compute'],
- floating_addresses=None,
- )
-
- multi_host, addresses = self._get_multi_addresses(context, instance)
- if multi_host:
- args['floating_addresses'] = addresses
- args['host'] = migration['source_compute']
-
- self.network_rpcapi.migrate_instance_start(context, **args)
-
- def migrate_instance_finish(
- self, context, instance, migration, provider_mappings):
- """Finish migrating the network of an instance."""
- flavor = instance.get_flavor()
- args = dict(
- instance_uuid=instance.uuid,
- rxtx_factor=flavor['rxtx_factor'],
- project_id=instance.project_id,
- source_compute=migration.source_compute,
- dest_compute=migration.dest_compute,
- floating_addresses=None,
- )
-
- multi_host, addresses = self._get_multi_addresses(context, instance)
- if multi_host:
- args['floating_addresses'] = addresses
- args['host'] = migration.dest_compute
-
- self.network_rpcapi.migrate_instance_finish(context, **args)
-
- def setup_instance_network_on_host(
- self, context, instance, host, migration=None,
- provider_mappings=None):
- """Setup network for specified instance on host."""
- self.migrate_instance_finish(
- context, instance, {'source_compute': None, 'dest_compute': host},
- None)
-
- def cleanup_instance_network_on_host(self, context, instance, host):
- """Cleanup network for specified instance on host."""
- self.migrate_instance_start(context, instance,
- {'source_compute': host,
- 'dest_compute': None})
diff --git a/nova/network/base_api.py b/nova/network/base_api.py
index 27c366f48d..573bf9abcb 100644
--- a/nova/network/base_api.py
+++ b/nova/network/base_api.py
@@ -102,18 +102,6 @@ class NetworkAPI(base.Base):
"""Get specific network for client."""
raise NotImplementedError()
- def create(self, context, **kwargs):
- """Create a network."""
- raise NotImplementedError()
-
- def delete(self, context, network_uuid):
- """Delete a specific network."""
- raise NotImplementedError()
-
- def get_fixed_ip(self, context, id):
- """Get fixed IP by id."""
- raise NotImplementedError()
-
def get_fixed_ip_by_address(self, context, address):
"""Get fixed IP by address."""
raise NotImplementedError()
@@ -149,10 +137,6 @@ class NetworkAPI(base.Base):
"""
raise NotImplementedError()
- def get_vif_by_mac_address(self, context, mac_address):
- """Get vif mac address."""
- raise NotImplementedError()
-
def allocate_floating_ip(self, context, pool=None):
"""Adds (allocate) floating IP to a project from a pool."""
raise NotImplementedError()
@@ -281,44 +265,6 @@ class NetworkAPI(base.Base):
"""
raise NotImplementedError()
- def get_dns_domains(self, context):
- """Returns a list of available dns domains.
- These can be used to create DNS entries for floating IPs.
- """
- raise NotImplementedError()
-
- def add_dns_entry(self, context, address, name, dns_type, domain):
- """Create specified DNS entry for address."""
- raise NotImplementedError()
-
- def modify_dns_entry(self, context, name, address, domain):
- """Create specified DNS entry for address."""
- raise NotImplementedError()
-
- def delete_dns_entry(self, context, name, domain):
- """Delete the specified dns entry."""
- raise NotImplementedError()
-
- def delete_dns_domain(self, context, domain):
- """Delete the specified dns domain."""
- raise NotImplementedError()
-
- def get_dns_entries_by_address(self, context, address, domain):
- """Get entries for address and domain."""
- raise NotImplementedError()
-
- def get_dns_entries_by_name(self, context, name, domain):
- """Get entries for name and domain."""
- raise NotImplementedError()
-
- def create_private_dns_domain(self, context, domain, availability_zone):
- """Create a private DNS domain with nova availability zone."""
- raise NotImplementedError()
-
- def create_public_dns_domain(self, context, domain, project=None):
- """Create a public DNS domain with optional nova project."""
- raise NotImplementedError()
-
def setup_networks_on_host(self, context, instance, host=None,
teardown=False):
"""Setup or teardown the network structures on hosts related to
diff --git a/nova/network/dns_driver.py b/nova/network/dns_driver.py
deleted file mode 100644
index 07b690b91f..0000000000
--- a/nova/network/dns_driver.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2011 Andrew Bogott for the Wikimedia Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-class DNSDriver(object):
- """Defines the DNS manager interface. Does nothing."""
-
- def __init__(self):
- pass
-
- def get_domains(self):
- raise NotImplementedError()
-
- def create_entry(self, _name, _address, _type, _domain):
- raise NotImplementedError()
-
- def delete_entry(self, _name, _domain):
- raise NotImplementedError()
-
- def modify_address(self, _name, _address, _domain):
- raise NotImplementedError()
-
- def get_entries_by_address(self, _address, _domain):
- raise NotImplementedError()
-
- def get_entries_by_name(self, _name, _domain):
- raise NotImplementedError()
-
- def create_domain(self, _fqdomain):
- raise NotImplementedError()
-
- def delete_domain(self, _fqdomain):
- raise NotImplementedError()
diff --git a/nova/network/driver.py b/nova/network/driver.py
deleted file mode 100644
index f984389c86..0000000000
--- a/nova/network/driver.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2012 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import sys
-
-from oslo_log import log as logging
-from oslo_utils import importutils
-
-import nova.conf
-
-
-CONF = nova.conf.CONF
-LOG = logging.getLogger(__name__)
-
-
-def load_network_driver(network_driver=None):
- if not network_driver:
- network_driver = CONF.network_driver
-
- if not network_driver:
- LOG.error("Network driver option required, but not specified")
- sys.exit(1)
-
- LOG.info("Loading network driver '%s'", network_driver)
-
- return importutils.import_module(network_driver)
diff --git a/nova/network/floating_ips.py b/nova/network/floating_ips.py
deleted file mode 100644
index 04064e6060..0000000000
--- a/nova/network/floating_ips.py
+++ /dev/null
@@ -1,659 +0,0 @@
-# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo_concurrency import processutils
-from oslo_log import log as logging
-import oslo_messaging as messaging
-from oslo_utils import excutils
-from oslo_utils import importutils
-from oslo_utils import uuidutils
-import six
-
-import nova.conf
-from nova import context
-from nova.db import base
-from nova import exception
-from nova.network import rpcapi as network_rpcapi
-from nova import objects
-from nova import rpc
-from nova import servicegroup
-from nova import utils
-
-LOG = logging.getLogger(__name__)
-
-CONF = nova.conf.CONF
-
-
-class FloatingIP(object):
- """Mixin class for adding floating IP functionality to a manager."""
-
- servicegroup_api = None
-
- def init_host_floating_ips(self):
- """Configures floating IPs owned by host."""
-
- admin_context = context.get_admin_context()
- try:
- floating_ips = objects.FloatingIPList.get_by_host(admin_context,
- self.host)
- except exception.NotFound:
- return
-
- for floating_ip in floating_ips:
- if floating_ip.fixed_ip_id:
- try:
- fixed_ip = floating_ip.fixed_ip
- except exception.FixedIpNotFound:
- LOG.debug('Fixed IP %s not found', floating_ip.fixed_ip_id)
- continue
- interface = CONF.public_interface or floating_ip.interface
- try:
- self.l3driver.add_floating_ip(floating_ip.address,
- fixed_ip.address,
- interface,
- fixed_ip.network)
- except processutils.ProcessExecutionError:
- LOG.debug('Interface %s not found', interface)
- raise exception.NoFloatingIpInterface(interface=interface)
-
- def allocate_for_instance(self, context, **kwargs):
- """Handles allocating the floating IP resources for an instance.
-
- calls super class allocate_for_instance() as well
-
- rpc.called by network_api
- """
- instance_uuid = kwargs.get('instance_id')
- if not uuidutils.is_uuid_like(instance_uuid):
- instance_uuid = kwargs.get('instance_uuid')
- project_id = kwargs.get('project_id')
- # call the next inherited class's allocate_for_instance()
- # which is currently the NetworkManager version
- # do this first so fixed ip is already allocated
- nw_info = super(FloatingIP, self).allocate_for_instance(context,
- **kwargs)
- if CONF.auto_assign_floating_ip:
- context = context.elevated()
- # allocate a floating ip
- floating_address = self.allocate_floating_ip(context, project_id,
- True)
- LOG.debug("floating IP allocation for instance "
- "|%s|", floating_address,
- instance_uuid=instance_uuid)
-
- # get the first fixed address belonging to the instance
- fixed_ips = nw_info.fixed_ips()
- fixed_address = fixed_ips[0]['address']
-
- # associate the floating ip to fixed_ip
- self.associate_floating_ip(context,
- floating_address,
- fixed_address,
- affect_auto_assigned=True)
-
- # create a fresh set of network info that contains the floating ip
- nw_info = self.get_instance_nw_info(context, **kwargs)
-
- return nw_info
-
- def deallocate_for_instance(self, context, **kwargs):
- """Handles deallocating floating IP resources for an instance.
-
- calls super class deallocate_for_instance() as well.
-
- rpc.called by network_api
- """
- if 'instance' in kwargs:
- instance_uuid = kwargs['instance'].uuid
- else:
- instance_uuid = kwargs['instance_id']
- if not uuidutils.is_uuid_like(instance_uuid):
- # NOTE(francois.charlier): in some cases the instance might be
- # deleted before the IPs are released, so we need to get
- # deleted instances too
- instance = objects.Instance.get_by_id(
- context.elevated(read_deleted='yes'), instance_uuid)
- instance_uuid = instance.uuid
-
- try:
- fixed_ips = objects.FixedIPList.get_by_instance_uuid(
- context, instance_uuid)
- except exception.FixedIpNotFoundForInstance:
- fixed_ips = []
- # add to kwargs so we can pass to super to save a db lookup there
- kwargs['fixed_ips'] = fixed_ips
- for fixed_ip in fixed_ips:
- fixed_id = fixed_ip.id
- floating_ips = objects.FloatingIPList.get_by_fixed_ip_id(context,
- fixed_id)
- # disassociate floating ips related to fixed_ip
- for floating_ip in floating_ips:
- address = str(floating_ip.address)
- try:
- self.disassociate_floating_ip(context,
- address,
- affect_auto_assigned=True)
- except exception.FloatingIpNotAssociated:
- LOG.info("Floating IP %s is not associated. Ignore.",
- address)
- # deallocate if auto_assigned
- if floating_ip.auto_assigned:
- self.deallocate_floating_ip(context, address,
- affect_auto_assigned=True)
-
- # call the next inherited class's deallocate_for_instance()
- # which is currently the NetworkManager version
- # call this after so floating IPs are handled first
- super(FloatingIP, self).deallocate_for_instance(context, **kwargs)
-
- def _floating_ip_owned_by_project(self, context, floating_ip):
- """Raises if floating IP does not belong to project."""
- if context.is_admin:
- return
-
- if floating_ip.project_id != context.project_id:
- if floating_ip.project_id is None:
- LOG.warning('Address |%(address)s| is not allocated',
- {'address': floating_ip.address})
- raise exception.Forbidden()
- else:
- LOG.warning('Address |%(address)s| is not allocated '
- 'to your project |%(project)s|',
- {'address': floating_ip.address,
- 'project': context.project_id})
- raise exception.Forbidden()
-
- def _floating_ip_pool_exists(self, context, name):
- """Returns true if the specified floating IP pool exists. Otherwise,
- returns false.
- """
- pools = [pool.get('name') for pool in
- self.get_floating_ip_pools(context)]
- if name in pools:
- return True
-
- return False
-
- def allocate_floating_ip(self, context, project_id, auto_assigned=False,
- pool=None):
- """Gets a floating IP from the pool."""
- # NOTE(tr3buchet): all network hosts in zone now use the same pool
- pool = pool or CONF.default_floating_pool
- use_quota = not auto_assigned
-
- if not self._floating_ip_pool_exists(context, pool):
- raise exception.FloatingIpPoolNotFound()
-
- # Check the quota; can't put this in the API because we get
- # called into from other places
- try:
- if use_quota:
- objects.Quotas.check_deltas(context, {'floating_ips': 1},
- project_id)
- except exception.OverQuota:
- LOG.warning("Quota exceeded for %s, tried to allocate "
- "floating IP", context.project_id)
- raise exception.FloatingIpLimitExceeded()
-
- floating_ip = objects.FloatingIP.allocate_address(
- context, project_id, pool, auto_assigned=auto_assigned)
-
- # NOTE(melwitt): We recheck the quota after creating the object to
- # prevent users from allocating more resources than their allowed quota
- # in the event of a race. This is configurable because it can be
- # expensive if strict quota limits are not required in a deployment.
- if CONF.quota.recheck_quota and use_quota:
- try:
- objects.Quotas.check_deltas(context, {'floating_ips': 0},
- project_id)
- except exception.OverQuota:
- objects.FloatingIP.deallocate(context, floating_ip.address)
- LOG.warning("Quota exceeded for %s, tried to allocate "
- "floating IP", context.project_id)
- raise exception.FloatingIpLimitExceeded()
-
- payload = dict(project_id=project_id, floating_ip=floating_ip)
- self.notifier.info(context,
- 'network.floating_ip.allocate', payload)
-
- return floating_ip
-
- @messaging.expected_exceptions(exception.FloatingIpNotFoundForAddress)
- def deallocate_floating_ip(self, context, address,
- affect_auto_assigned=False):
- """Returns a floating IP to the pool."""
- floating_ip = objects.FloatingIP.get_by_address(context, address)
-
- # handle auto_assigned
- if not affect_auto_assigned and floating_ip.auto_assigned:
- return
-
- # make sure project owns this floating ip (allocated)
- self._floating_ip_owned_by_project(context, floating_ip)
-
- # make sure floating ip is not associated
- if floating_ip.fixed_ip_id:
- floating_address = floating_ip.address
- raise exception.FloatingIpAssociated(address=floating_address)
-
- # clean up any associated DNS entries
- self._delete_all_entries_for_ip(context,
- floating_ip.address)
- payload = dict(project_id=floating_ip.project_id,
- floating_ip=str(floating_ip.address))
- self.notifier.info(context, 'network.floating_ip.deallocate', payload)
-
- objects.FloatingIP.deallocate(context, address)
-
- @messaging.expected_exceptions(exception.FloatingIpNotFoundForAddress)
- def associate_floating_ip(self, context, floating_address, fixed_address,
- affect_auto_assigned=False):
- """Associates a floating IP with a fixed IP.
-
- Makes sure everything makes sense then calls _associate_floating_ip,
- rpc'ing to correct host if i'm not it.
-
- Access to the floating_address is verified but access to the
- fixed_address is not verified. This assumes that the calling
- side has already verified that the fixed_address is legal by
- checking access to the instance.
- """
- floating_ip = objects.FloatingIP.get_by_address(context,
- floating_address)
- # handle auto_assigned
- if not affect_auto_assigned and floating_ip.auto_assigned:
- return
-
- # make sure project owns this floating ip (allocated)
- self._floating_ip_owned_by_project(context, floating_ip)
-
- # disassociate any already associated
- orig_instance_uuid = None
- if floating_ip.fixed_ip_id:
- # find previously associated instance
- fixed_ip = floating_ip.fixed_ip
- if str(fixed_ip.address) == fixed_address:
- # NOTE(vish): already associated to this address
- return
- orig_instance_uuid = fixed_ip.instance_uuid
-
- self.disassociate_floating_ip(context, floating_address)
-
- fixed_ip = objects.FixedIP.get_by_address(context, fixed_address)
-
- # send to correct host, unless i'm the correct host
- network = objects.Network.get_by_id(context.elevated(),
- fixed_ip.network_id)
- if network.multi_host:
- instance = objects.Instance.get_by_uuid(
- context, fixed_ip.instance_uuid)
- host = instance.host
- else:
- host = network.host
-
- interface = floating_ip.interface
- if host == self.host:
- # i'm the correct host
- self._associate_floating_ip(context, floating_address,
- fixed_address, interface,
- fixed_ip.instance_uuid)
- else:
- # send to correct host
- self.network_rpcapi._associate_floating_ip(context,
- floating_address, fixed_address, interface, host,
- fixed_ip.instance_uuid)
-
- return orig_instance_uuid
-
- def _associate_floating_ip(self, context, floating_address, fixed_address,
- interface, instance_uuid):
- """Performs db and driver calls to associate floating IP & fixed IP."""
- interface = CONF.public_interface or interface
-
- @utils.synchronized(six.text_type(floating_address))
- def do_associate():
- # associate floating ip
- floating = objects.FloatingIP.associate(context, floating_address,
- fixed_address, self.host)
- fixed = floating.fixed_ip
- if not fixed:
- # NOTE(vish): ip was already associated
- return
- try:
- # gogo driver time
- self.l3driver.add_floating_ip(floating_address, fixed_address,
- interface, fixed['network'])
- except processutils.ProcessExecutionError as e:
- with excutils.save_and_reraise_exception():
- try:
- objects.FloatingIP.disassociate(context,
- floating_address)
- except Exception:
- LOG.warning('Failed to disassociated floating '
- 'address: %s', floating_address)
- pass
- if "Cannot find device" in six.text_type(e):
- try:
- LOG.error('Interface %s not found', interface)
- except Exception:
- pass
- raise exception.NoFloatingIpInterface(
- interface=interface)
-
- payload = dict(project_id=context.project_id,
- instance_id=instance_uuid,
- floating_ip=floating_address)
- self.notifier.info(context,
- 'network.floating_ip.associate', payload)
- do_associate()
-
- @messaging.expected_exceptions(exception.FloatingIpNotFoundForAddress)
- def disassociate_floating_ip(self, context, address,
- affect_auto_assigned=False):
- """Disassociates a floating IP from its fixed IP.
-
- Makes sure everything makes sense then calls _disassociate_floating_ip,
- rpc'ing to correct host if i'm not it.
- """
- floating_ip = objects.FloatingIP.get_by_address(context, address)
-
- # handle auto assigned
- if not affect_auto_assigned and floating_ip.auto_assigned:
- raise exception.CannotDisassociateAutoAssignedFloatingIP()
-
- # make sure project owns this floating ip (allocated)
- self._floating_ip_owned_by_project(context, floating_ip)
-
- # make sure floating ip is associated
- if not floating_ip.fixed_ip_id:
- floating_address = floating_ip.address
- raise exception.FloatingIpNotAssociated(address=floating_address)
-
- fixed_ip = objects.FixedIP.get_by_id(context, floating_ip.fixed_ip_id)
-
- # send to correct host, unless i'm the correct host
- network = objects.Network.get_by_id(context.elevated(),
- fixed_ip.network_id)
- interface = floating_ip.interface
- if network.multi_host:
- instance = objects.Instance.get_by_uuid(
- context, fixed_ip.instance_uuid)
- service = objects.Service.get_by_host_and_binary(
- context.elevated(), instance.host, 'nova-network')
- if service and self.servicegroup_api.service_is_up(service):
- host = instance.host
- else:
- # NOTE(vish): if the service is down just deallocate the data
- # locally. Set the host to local so the call will
- # not go over rpc and set interface to None so the
- # teardown in the driver does not happen.
- host = self.host
- interface = None
- else:
- host = network.host
-
- if host == self.host:
- # i'm the correct host
- self._disassociate_floating_ip(context, address, interface,
- fixed_ip.instance_uuid)
- else:
- # send to correct host
- self.network_rpcapi._disassociate_floating_ip(context, address,
- interface, host, fixed_ip.instance_uuid)
-
- def _disassociate_floating_ip(self, context, address, interface,
- instance_uuid):
- """Performs db and driver calls to disassociate floating IP."""
- interface = CONF.public_interface or interface
-
- @utils.synchronized(six.text_type(address))
- def do_disassociate():
- # NOTE(vish): Note that we are disassociating in the db before we
- # actually remove the ip address on the host. We are
- # safe from races on this host due to the decorator,
- # but another host might grab the ip right away. We
- # don't worry about this case because the minuscule
- # window where the ip is on both hosts shouldn't cause
- # any problems.
- floating = objects.FloatingIP.disassociate(context, address)
- fixed = floating.fixed_ip
- if not fixed:
- # NOTE(vish): ip was already disassociated
- return
- if interface:
- # go go driver time
- self.l3driver.remove_floating_ip(address, fixed.address,
- interface, fixed.network)
- payload = dict(project_id=context.project_id,
- instance_id=instance_uuid,
- floating_ip=address)
- self.notifier.info(context,
- 'network.floating_ip.disassociate', payload)
- do_disassociate()
-
- @messaging.expected_exceptions(exception.FloatingIpNotFound)
- def get_floating_ip(self, context, id):
- """Returns a floating IP as a dict."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- return dict(objects.FloatingIP.get_by_id(context, id))
-
- def get_floating_pools(self, context):
- """Returns list of floating pools."""
- # NOTE(maurosr) This method should be removed in future, replaced by
- # get_floating_ip_pools. See bug #1091668
- return self.get_floating_ip_pools(context)
-
- def get_floating_ip_pools(self, context):
- """Returns list of floating ip pools."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- pools = objects.FloatingIP.get_pool_names(context)
- return [dict(name=name) for name in pools]
-
- def get_floating_ip_by_address(self, context, address):
- """Returns a floating IP as a dict."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- return objects.FloatingIP.get_by_address(context, address)
-
- def get_floating_ips_by_project(self, context):
- """Returns the floating IPs allocated to a project."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- return objects.FloatingIPList.get_by_project(context,
- context.project_id)
-
- def get_floating_ips_by_fixed_address(self, context, fixed_address):
- """Returns the floating IPs associated with a fixed_address."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- floating_ips = objects.FloatingIPList.get_by_fixed_address(
- context, fixed_address)
- return [str(floating_ip.address) for floating_ip in floating_ips]
-
- def _is_stale_floating_ip_address(self, context, floating_ip):
- try:
- self._floating_ip_owned_by_project(context, floating_ip)
- except exception.Forbidden:
- return True
- return False if floating_ip.get('fixed_ip_id') else True
-
- def migrate_instance_start(self, context, instance_uuid,
- floating_addresses,
- rxtx_factor=None, project_id=None,
- source=None, dest=None):
- # We only care if floating_addresses are provided and we're
- # switching hosts
- if not floating_addresses or (source and source == dest):
- return
-
- LOG.info("Starting migration network for instance %s", instance_uuid)
- for address in floating_addresses:
- floating_ip = objects.FloatingIP.get_by_address(context, address)
-
- if self._is_stale_floating_ip_address(context, floating_ip):
- LOG.warning("Floating IP address |%(address)s| no longer "
- "belongs to instance %(instance_uuid)s. "
- "Will not migrate it ",
- {'address': address,
- 'instance_uuid': instance_uuid})
- continue
-
- interface = CONF.public_interface or floating_ip.interface
- fixed_ip = floating_ip.fixed_ip
- self.l3driver.remove_floating_ip(floating_ip.address,
- fixed_ip.address,
- interface,
- fixed_ip.network)
-
- # NOTE(wenjianhn): Make this address will not be bound to public
- # interface when restarts nova-network on dest compute node
- floating_ip.host = None
- floating_ip.save()
-
- def migrate_instance_finish(self, context, instance_uuid,
- floating_addresses, host=None,
- rxtx_factor=None, project_id=None,
- source=None, dest=None):
- # We only care if floating_addresses are provided and we're
- # switching hosts
- if host and not dest:
- dest = host
- if not floating_addresses or (source and source == dest):
- return
-
- LOG.info("Finishing migration network for instance %s", instance_uuid)
-
- for address in floating_addresses:
- floating_ip = objects.FloatingIP.get_by_address(context, address)
-
- if self._is_stale_floating_ip_address(context, floating_ip):
- LOG.warning("Floating IP address |%(address)s| no longer "
- "belongs to instance %(instance_uuid)s. "
- "Will not setup it.",
- {'address': address,
- 'instance_uuid': instance_uuid})
- continue
-
- floating_ip.host = dest
- floating_ip.save()
-
- interface = CONF.public_interface or floating_ip.interface
- fixed_ip = floating_ip.fixed_ip
- self.l3driver.add_floating_ip(floating_ip.address,
- fixed_ip.address,
- interface,
- fixed_ip.network)
-
- def _prepare_domain_entry(self, context, domainref):
- scope = domainref.scope
- if scope == 'private':
- this_domain = {'domain': domainref.domain,
- 'scope': scope,
- 'availability_zone': domainref.availability_zone}
- else:
- this_domain = {'domain': domainref.domain,
- 'scope': scope,
- 'project': domainref.project_id}
- return this_domain
-
- def get_dns_domains(self, context):
- domains = []
-
- domain_list = objects.DNSDomainList.get_all(context)
- floating_driver_domain_list = self.floating_dns_manager.get_domains()
- instance_driver_domain_list = self.instance_dns_manager.get_domains()
-
- for dns_domain in domain_list:
- if (dns_domain.domain in floating_driver_domain_list or
- dns_domain.domain in instance_driver_domain_list):
- domain_entry = self._prepare_domain_entry(context, dns_domain)
- if domain_entry:
- domains.append(domain_entry)
- else:
- LOG.warning('Database inconsistency: DNS domain |%s| is '
- 'registered in the Nova db but not visible to '
- 'either the floating or instance DNS driver. '
- 'It will be ignored.', dns_domain.domain)
-
- return domains
-
- def add_dns_entry(self, context, address, name, dns_type, domain):
- self.floating_dns_manager.create_entry(name, address,
- dns_type, domain)
-
- def modify_dns_entry(self, context, address, name, domain):
- self.floating_dns_manager.modify_address(name, address,
- domain)
-
- def delete_dns_entry(self, context, name, domain):
- self.floating_dns_manager.delete_entry(name, domain)
-
- def _delete_all_entries_for_ip(self, context, address):
- domain_list = self.get_dns_domains(context)
- for domain in domain_list:
- names = self.get_dns_entries_by_address(context,
- address,
- domain['domain'])
- for name in names:
- self.delete_dns_entry(context, name, domain['domain'])
-
- def get_dns_entries_by_address(self, context, address, domain):
- return self.floating_dns_manager.get_entries_by_address(address,
- domain)
-
- def get_dns_entries_by_name(self, context, name, domain):
- return self.floating_dns_manager.get_entries_by_name(name,
- domain)
-
- def create_private_dns_domain(self, context, domain, av_zone):
- objects.DNSDomain.register_for_zone(context, domain, av_zone)
- try:
- self.instance_dns_manager.create_domain(domain)
- except exception.FloatingIpDNSExists:
- LOG.warning('Domain |%(domain)s| already exists, '
- 'changing zone to |%(av_zone)s|.',
- {'domain': domain, 'av_zone': av_zone})
-
- def create_public_dns_domain(self, context, domain, project):
- objects.DNSDomain.register_for_project(context, domain, project)
- try:
- self.floating_dns_manager.create_domain(domain)
- except exception.FloatingIpDNSExists:
- LOG.warning('Domain |%(domain)s| already exists, '
- 'changing project to |%(project)s|.',
- {'domain': domain, 'project': project})
-
- def delete_dns_domain(self, context, domain):
- objects.DNSDomain.delete_by_domain(context, domain)
- self.floating_dns_manager.delete_domain(domain)
-
-
-class LocalManager(base.Base, FloatingIP):
- def __init__(self):
- super(LocalManager, self).__init__()
- # NOTE(vish): setting the host to none ensures that the actual
- # l3driver commands for l3 are done via rpc.
- self.host = None
- self.servicegroup_api = servicegroup.API()
- self.network_rpcapi = network_rpcapi.NetworkAPI()
- self.floating_dns_manager = importutils.import_object(
- CONF.floating_ip_dns_manager)
- self.instance_dns_manager = importutils.import_object(
- CONF.instance_dns_manager)
- self.notifier = rpc.get_notifier('network', CONF.host)
diff --git a/nova/network/l3.py b/nova/network/l3.py
deleted file mode 100644
index abf3a9b185..0000000000
--- a/nova/network/l3.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# Copyright 2012 Nicira Networks, Inc
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo_log import log as logging
-
-from nova.network import linux_net
-import nova.privsep.linux_net
-from nova import utils
-
-LOG = logging.getLogger(__name__)
-
-
-class L3Driver(object):
- """Abstract class that defines a generic L3 API."""
-
- def __init__(self, l3_lib=None):
- raise NotImplementedError()
-
- def initialize(self, **kwargs):
- """Set up basic L3 networking functionality."""
- raise NotImplementedError()
-
- def initialize_network(self, cidr, is_external):
- """Enable rules for a specific network."""
- raise NotImplementedError()
-
- def initialize_gateway(self, network_ref):
- """Set up a gateway on this network."""
- raise NotImplementedError()
-
- def remove_gateway(self, network_ref):
- """Remove an existing gateway on this network."""
- raise NotImplementedError()
-
- def is_initialized(self):
- """:returns: True/False (whether the driver is initialized)."""
- raise NotImplementedError()
-
- def add_floating_ip(self, floating_ip, fixed_ip, l3_interface_id,
- network=None):
- """Add a floating IP bound to the fixed IP with an optional
- l3_interface_id. Some drivers won't care about the
- l3_interface_id so just pass None in that case. Network
- is also an optional parameter.
- """
- raise NotImplementedError()
-
- def remove_floating_ip(self, floating_ip, fixed_ip, l3_interface_id,
- network=None):
- raise NotImplementedError()
-
- def add_vpn(self, public_ip, port, private_ip):
- raise NotImplementedError()
-
- def remove_vpn(self, public_ip, port, private_ip):
- raise NotImplementedError()
-
- def clean_conntrack(self, fixed_ip):
- raise NotImplementedError()
-
- def teardown(self):
- raise NotImplementedError()
-
-
-class LinuxNetL3(L3Driver):
- """L3 driver that uses linux_net as the backend."""
- def __init__(self):
- self.initialized = False
-
- def initialize(self, **kwargs):
- if self.initialized:
- return
- LOG.debug("Initializing linux_net L3 driver")
- fixed_range = kwargs.get('fixed_range', False)
- networks = kwargs.get('networks', None)
- if not fixed_range and networks is not None:
- for network in networks:
- if network['enable_dhcp']:
- is_ext = (network['dhcp_server'] is not None and
- network['dhcp_server'] != network['gateway'])
- self.initialize_network(network['cidr'], is_ext)
- linux_net.ensure_metadata_ip()
- linux_net.metadata_forward()
- self.initialized = True
-
- def is_initialized(self):
- return self.initialized
-
- def initialize_network(self, cidr, is_external):
- linux_net.init_host(cidr, is_external)
-
- def initialize_gateway(self, network_ref):
- mac_address = utils.generate_mac_address()
- dev = linux_net.plug(network_ref, mac_address,
- gateway=(network_ref['gateway'] is not None))
- linux_net.initialize_gateway_device(dev, network_ref)
-
- def remove_gateway(self, network_ref):
- linux_net.unplug(network_ref)
-
- def add_floating_ip(self, floating_ip, fixed_ip, l3_interface_id,
- network=None):
- linux_net.ensure_floating_forward(floating_ip, fixed_ip,
- l3_interface_id, network)
- linux_net.bind_floating_ip(floating_ip, l3_interface_id)
-
- def remove_floating_ip(self, floating_ip, fixed_ip, l3_interface_id,
- network=None):
- nova.privsep.linux_net.unbind_ip(l3_interface_id, floating_ip)
- linux_net.remove_floating_forward(floating_ip, fixed_ip,
- l3_interface_id, network)
- nova.privsep.linux_net.clean_conntrack(fixed_ip)
-
- def add_vpn(self, public_ip, port, private_ip):
- linux_net.ensure_vpn_forward(public_ip, port, private_ip)
-
- def remove_vpn(self, public_ip, port, private_ip):
- # Linux net currently doesn't implement any way of removing
- # the VPN forwarding rules
- pass
-
- def teardown(self):
- pass
-
-
-class NullL3(L3Driver):
- """The L3 driver that doesn't do anything. This class can be used when
- nova-network should not manipulate L3 forwarding at all (e.g., in a Flat
- or FlatDHCP scenario).
- """
- def __init__(self):
- pass
-
- def initialize(self, **kwargs):
- pass
-
- def is_initialized(self):
- return True
-
- def initialize_network(self, cidr, is_external):
- pass
-
- def initialize_gateway(self, network_ref):
- pass
-
- def remove_gateway(self, network_ref):
- pass
-
- def add_floating_ip(self, floating_ip, fixed_ip, l3_interface_id,
- network=None):
- pass
-
- def remove_floating_ip(self, floating_ip, fixed_ip, l3_interface_id,
- network=None):
- pass
-
- def add_vpn(self, public_ip, port, private_ip):
- pass
-
- def remove_vpn(self, public_ip, port, private_ip):
- pass
-
- def clean_conntrack(self, fixed_ip):
- pass
-
- def teardown(self):
- pass
diff --git a/nova/network/ldapdns.py b/nova/network/ldapdns.py
deleted file mode 100644
index 047d0042ac..0000000000
--- a/nova/network/ldapdns.py
+++ /dev/null
@@ -1,337 +0,0 @@
-# Copyright 2012 Andrew Bogott for the Wikimedia Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-try:
- import ldap
-except ImportError:
- # This module needs to be importable despite ldap not being a requirement
- ldap = None
-
-import time
-
-from oslo_log import log as logging
-
-import nova.conf
-from nova import exception
-from nova.i18n import _
-from nova.network import dns_driver
-from nova import utils
-
-CONF = nova.conf.CONF
-LOG = logging.getLogger(__name__)
-
-
-# Importing ldap.modlist breaks the tests for some reason,
-# so this is an abbreviated version of a function from
-# there.
-def create_modlist(newattrs):
- modlist = []
- for attrtype in newattrs.keys():
- utf8_vals = []
- for val in newattrs[attrtype]:
- utf8_vals.append(utils.utf8(val))
- newattrs[attrtype] = utf8_vals
- modlist.append((attrtype, newattrs[attrtype]))
- return modlist
-
-
-class DNSEntry(object):
-
- def __init__(self, ldap_object):
- """ldap_object is an instance of ldap.LDAPObject.
-
- It should already be initialized and bound before
- getting passed in here.
- """
- self.lobj = ldap_object
- self.ldap_tuple = None
- self.qualified_domain = None
-
- @classmethod
- def _get_tuple_for_domain(cls, lobj, domain):
- entry = lobj.search_s(CONF.ldap_dns_base_dn, ldap.SCOPE_SUBTREE,
- '(associatedDomain=%s)' % utils.utf8(domain))
- if not entry:
- return None
- if len(entry) > 1:
- LOG.warning("Found multiple matches for domain "
- "%(domain)s.\n%(entry)s",
- domain, entry)
- return entry[0]
-
- @classmethod
- def _get_all_domains(cls, lobj):
- entries = lobj.search_s(CONF.ldap_dns_base_dn,
- ldap.SCOPE_SUBTREE, '(sOARecord=*)')
- domains = []
- for entry in entries:
- domain = entry[1].get('associatedDomain')
- if domain:
- domains.append(domain[0])
- return domains
-
- def _set_tuple(self, tuple):
- self.ldap_tuple = tuple
-
- def _qualify(self, name):
- return '%s.%s' % (name, self.qualified_domain)
-
- def _dequalify(self, name):
- z = ".%s" % self.qualified_domain
- if name.endswith(z):
- dequalified = name[0:name.rfind(z)]
- else:
- LOG.warning("Unable to dequalify. %(name)s is not in "
- "%(domain)s.\n",
- {'name': name,
- 'domain': self.qualified_domain})
- dequalified = None
-
- return dequalified
-
- def _dn(self):
- return self.ldap_tuple[0]
- dn = property(_dn)
-
- def _rdn(self):
- return self.dn.partition(',')[0]
- rdn = property(_rdn)
-
-
-class DomainEntry(DNSEntry):
-
- @classmethod
- def _soa(cls):
- date = time.strftime('%Y%m%d%H%M%S')
- soa = '%s %s %s %d %d %d %d' % (
- CONF.ldap_dns_servers[0],
- CONF.ldap_dns_soa_hostmaster,
- date,
- CONF.ldap_dns_soa_refresh,
- CONF.ldap_dns_soa_retry,
- CONF.ldap_dns_soa_expiry,
- CONF.ldap_dns_soa_minimum)
- return utils.utf8(soa)
-
- @classmethod
- def create_domain(cls, lobj, domain):
- """Create a new domain entry, and return an object that wraps it."""
- entry = cls._get_tuple_for_domain(lobj, domain)
- if entry:
- raise exception.FloatingIpDNSExists(name=domain, domain='')
-
- newdn = 'dc=%s,%s' % (domain, CONF.ldap_dns_base_dn)
- attrs = {'objectClass': ['domainrelatedobject', 'dnsdomain',
- 'domain', 'dcobject', 'top'],
- 'sOARecord': [cls._soa()],
- 'associatedDomain': [domain],
- 'dc': [domain]}
- lobj.add_s(newdn, create_modlist(attrs))
- return DomainEntry(lobj, domain)
-
- def __init__(self, ldap_object, domain):
- super(DomainEntry, self).__init__(ldap_object)
- entry = self._get_tuple_for_domain(self.lobj, domain)
- if not entry:
- raise exception.NotFound()
- self._set_tuple(entry)
- assert(entry[1]['associatedDomain'][0] == domain)
- self.qualified_domain = domain
-
- def delete(self):
- """Delete the domain that this entry refers to."""
- entries = self.lobj.search_s(self.dn,
- ldap.SCOPE_SUBTREE,
- '(aRecord=*)')
- for entry in entries:
- self.lobj.delete_s(entry[0])
-
- self.lobj.delete_s(self.dn)
-
- def update_soa(self):
- mlist = [(ldap.MOD_REPLACE, 'sOARecord', self._soa())]
- self.lobj.modify_s(self.dn, mlist)
-
- def subentry_with_name(self, name):
- entry = self.lobj.search_s(self.dn, ldap.SCOPE_SUBTREE,
- '(associatedDomain=%s.%s)' %
- (utils.utf8(name),
- utils.utf8(self.qualified_domain)))
- if entry:
- return HostEntry(self, entry[0])
- else:
- return None
-
- def subentries_with_ip(self, ip):
- entries = self.lobj.search_s(self.dn, ldap.SCOPE_SUBTREE,
- '(aRecord=%s)' % utils.utf8(ip))
- objs = []
- for entry in entries:
- if 'associatedDomain' in entry[1]:
- objs.append(HostEntry(self, entry))
-
- return objs
-
- def add_entry(self, name, address):
- if self.subentry_with_name(name):
- raise exception.FloatingIpDNSExists(name=name,
- domain=self.qualified_domain)
-
- entries = self.subentries_with_ip(address)
- if entries:
- # We already have an ldap entry for this IP, so we just
- # need to add the new name.
- existingdn = entries[0].dn
- self.lobj.modify_s(existingdn, [(ldap.MOD_ADD,
- 'associatedDomain',
- utils.utf8(self._qualify(name)))])
-
- return self.subentry_with_name(name)
- else:
- # We need to create an entirely new entry.
- newdn = 'dc=%s,%s' % (name, self.dn)
- attrs = {'objectClass': ['domainrelatedobject', 'dnsdomain',
- 'domain', 'dcobject', 'top'],
- 'aRecord': [address],
- 'associatedDomain': [self._qualify(name)],
- 'dc': [name]}
- self.lobj.add_s(newdn, create_modlist(attrs))
- return self.subentry_with_name(name)
-
- def remove_entry(self, name):
- entry = self.subentry_with_name(name)
- if not entry:
- raise exception.NotFound()
- entry.remove_name(name)
- self.update_soa()
-
-
-class HostEntry(DNSEntry):
-
- def __init__(self, parent, tuple):
- super(HostEntry, self).__init__(parent.lobj)
- self.parent_entry = parent
- self._set_tuple(tuple)
- self.qualified_domain = parent.qualified_domain
-
- def remove_name(self, name):
- names = self.ldap_tuple[1]['associatedDomain']
- if not names:
- raise exception.NotFound()
- if len(names) > 1:
- # We just have to remove the requested domain.
- self.lobj.modify_s(self.dn, [(ldap.MOD_DELETE, 'associatedDomain',
- self._qualify(utils.utf8(name)))])
- if (self.rdn[1] == name):
- # We just removed the rdn, so we need to move this entry.
- names.remove(self._qualify(name))
- newrdn = 'dc=%s' % self._dequalify(names[0])
- self.lobj.modrdn_s(self.dn, [newrdn])
- else:
- # We should delete the entire record.
- self.lobj.delete_s(self.dn)
-
- def modify_address(self, name, address):
- names = self.ldap_tuple[1]['associatedDomain']
- if not names:
- raise exception.NotFound()
- if len(names) == 1:
- self.lobj.modify_s(self.dn, [(ldap.MOD_REPLACE, 'aRecord',
- [utils.utf8(address)])])
- else:
- self.remove_name(name)
- self.parent.add_entry(name, address)
-
- def _names(self):
- names = []
- for domain in self.ldap_tuple[1]['associatedDomain']:
- names.append(self._dequalify(domain))
- return names
- names = property(_names)
-
- def _ip(self):
- ip = self.ldap_tuple[1]['aRecord'][0]
- return ip
- ip = property(_ip)
-
- def _parent(self):
- return self.parent_entry
- parent = property(_parent)
-
-
-class LdapDNS(dns_driver.DNSDriver):
- """Driver for PowerDNS using ldap as a back end.
-
- This driver assumes ldap-method=strict, with all domains
- in the top-level, aRecords only.
- """
-
- def __init__(self):
- if not ldap:
- raise ImportError(_('ldap not installed'))
-
- self.lobj = ldap.initialize(CONF.ldap_dns_url)
- self.lobj.simple_bind_s(CONF.ldap_dns_user,
- CONF.ldap_dns_password)
-
- def get_domains(self):
- return DomainEntry._get_all_domains(self.lobj)
-
- def create_entry(self, name, address, type, domain):
- if type.lower() != 'a':
- raise exception.InvalidInput(_("This driver only supports "
- "type 'a' entries."))
-
- dEntry = DomainEntry(self.lobj, domain)
- dEntry.add_entry(name, address)
-
- def delete_entry(self, name, domain):
- dEntry = DomainEntry(self.lobj, domain)
- dEntry.remove_entry(name)
-
- def get_entries_by_address(self, address, domain):
- try:
- dEntry = DomainEntry(self.lobj, domain)
- except exception.NotFound:
- return []
- entries = dEntry.subentries_with_ip(address)
- names = []
- for entry in entries:
- names.extend(entry.names)
- return names
-
- def get_entries_by_name(self, name, domain):
- try:
- dEntry = DomainEntry(self.lobj, domain)
- except exception.NotFound:
- return []
- nEntry = dEntry.subentry_with_name(name)
- if nEntry:
- return [nEntry.ip]
-
- def modify_address(self, name, address, domain):
- dEntry = DomainEntry(self.lobj, domain)
- nEntry = dEntry.subentry_with_name(name)
- nEntry.modify_address(name, address)
-
- def create_domain(self, domain):
- DomainEntry.create_domain(self.lobj, domain)
-
- def delete_domain(self, domain):
- dEntry = DomainEntry(self.lobj, domain)
- dEntry.delete()
-
- def delete_dns_file(self):
- LOG.warning("This shouldn't be getting called except during testing.")
- pass
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
deleted file mode 100644
index 233005f381..0000000000
--- a/nova/network/linux_net.py
+++ /dev/null
@@ -1,1632 +0,0 @@
-# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Implements vlans, bridges, and iptables rules using linux utilities."""
-
-import calendar
-import inspect
-import os
-import re
-import signal
-import time
-
-import netaddr
-import netifaces
-from oslo_concurrency import processutils
-from oslo_log import log as logging
-from oslo_serialization import jsonutils
-from oslo_utils import excutils
-from oslo_utils import fileutils
-from oslo_utils import importutils
-from oslo_utils import timeutils
-import six
-
-import nova.conf
-from nova import exception
-from nova.i18n import _
-from nova import objects
-from nova.pci import utils as pci_utils
-import nova.privsep.linux_net
-from nova import utils
-
-LOG = logging.getLogger(__name__)
-
-
-CONF = nova.conf.CONF
-
-
-# NOTE(vish): Iptables supports chain names of up to 28 characters, and we
-# add up to 12 characters to binary_name which is used as a prefix,
-# so we limit it to 16 characters.
-# (max_chain_name_length - len('-POSTROUTING') == 16)
-def get_binary_name():
- """Grab the name of the binary we're running in."""
- return os.path.basename(inspect.stack()[-1][1])[:16]
-
-
-binary_name = get_binary_name()
-
-
-class IptablesRule(object):
- """An iptables rule.
-
- You shouldn't need to use this class directly, it's only used by
- IptablesManager.
-
- """
-
- def __init__(self, chain, rule, wrap=True, top=False):
- self.chain = chain
- self.rule = rule
- self.wrap = wrap
- self.top = top
-
- def __eq__(self, other):
- return ((self.chain == other.chain) and
- (self.rule == other.rule) and
- (self.top == other.top) and
- (self.wrap == other.wrap))
-
- def __ne__(self, other):
- return not self == other
-
- def __repr__(self):
- if self.wrap:
- chain = '%s-%s' % (binary_name, self.chain)
- else:
- chain = self.chain
- # new rules should have a zero [packet: byte] count
- return '[0:0] -A %s %s' % (chain, self.rule)
-
-
-class IptablesTable(object):
- """An iptables table."""
-
- def __init__(self):
- self.rules = []
- self.remove_rules = []
- self.chains = set()
- self.unwrapped_chains = set()
- self.remove_chains = set()
- self.dirty = True
-
- def has_chain(self, name, wrap=True):
- if wrap:
- return name in self.chains
- else:
- return name in self.unwrapped_chains
-
- def add_chain(self, name, wrap=True):
- """Adds a named chain to the table.
-
- The chain name is wrapped to be unique for the component creating
- it, so different components of Nova can safely create identically
- named chains without interfering with one another.
-
- At the moment, its wrapped name is <binary name>-<chain name>,
- so if nova-compute creates a chain named 'OUTPUT', it'll actually
- end up named 'nova-compute-OUTPUT'.
-
- """
- if wrap:
- self.chains.add(name)
- else:
- self.unwrapped_chains.add(name)
- self.dirty = True
-
- def remove_chain(self, name, wrap=True):
- """Remove named chain.
-
- This removal "cascades". All rule in the chain are removed, as are
- all rules in other chains that jump to it.
-
- If the chain is not found, this is merely logged.
-
- """
- if wrap:
- chain_set = self.chains
- else:
- chain_set = self.unwrapped_chains
-
- if name not in chain_set:
- LOG.warning('Attempted to remove chain %s which does not exist',
- name)
- return
- self.dirty = True
-
- # non-wrapped chains and rules need to be dealt with specially,
- # so we keep a list of them to be iterated over in apply()
- if not wrap:
- self.remove_chains.add(name)
- chain_set.remove(name)
- if not wrap:
- self.remove_rules += [r for r in self.rules if r.chain == name]
- self.rules = [r for r in self.rules if r.chain != name]
-
- if wrap:
- jump_snippet = '-j %s-%s' % (binary_name, name)
- else:
- jump_snippet = '-j %s' % (name,)
-
- if not wrap:
- self.remove_rules += [r for r in self.rules
- if jump_snippet in r.rule]
- self.rules = [r for r in self.rules if jump_snippet not in r.rule]
-
- def add_rule(self, chain, rule, wrap=True, top=False):
- """Add a rule to the table.
-
- This is just like what you'd feed to iptables, just without
- the '-A <chain name>' bit at the start.
-
- However, if you need to jump to one of your wrapped chains,
- prepend its name with a '$' which will ensure the wrapping
- is applied correctly.
-
- """
- if wrap and chain not in self.chains:
- raise ValueError(_('Unknown chain: %r') % chain)
-
- if '$' in rule:
- rule = ' '.join(map(self._wrap_target_chain, rule.split(' ')))
-
- rule_obj = IptablesRule(chain, rule, wrap, top)
- if rule_obj in self.rules:
- LOG.debug("Skipping duplicate iptables rule addition. "
- "%(rule)r already in %(rules)r",
- {'rule': rule_obj, 'rules': self.rules})
- else:
- self.rules.append(IptablesRule(chain, rule, wrap, top))
- self.dirty = True
-
- def _wrap_target_chain(self, s):
- if s.startswith('$'):
- return '%s-%s' % (binary_name, s[1:])
- return s
-
- def remove_rule(self, chain, rule, wrap=True, top=False):
- """Remove a rule from a chain.
-
- Note: The rule must be exactly identical to the one that was added.
- You cannot switch arguments around like you can with the iptables
- CLI tool.
-
- """
- try:
- self.rules.remove(IptablesRule(chain, rule, wrap, top))
- if not wrap:
- self.remove_rules.append(IptablesRule(chain, rule, wrap, top))
- self.dirty = True
- except ValueError:
- LOG.warning('Tried to remove rule that was not there:'
- ' %(chain)r %(rule)r %(wrap)r %(top)r',
- {'chain': chain, 'rule': rule,
- 'top': top, 'wrap': wrap})
-
- def remove_rules_regex(self, regex):
- """Remove all rules matching regex."""
- if isinstance(regex, six.string_types):
- regex = re.compile(regex)
- num_rules = len(self.rules)
- self.rules = [r for r in self.rules if not regex.match(str(r))]
- removed = num_rules - len(self.rules)
- if removed > 0:
- self.dirty = True
- return removed
-
- def empty_chain(self, chain, wrap=True):
- """Remove all rules from a chain."""
- chained_rules = [rule for rule in self.rules
- if rule.chain == chain and rule.wrap == wrap]
- if chained_rules:
- self.dirty = True
- for rule in chained_rules:
- self.rules.remove(rule)
-
-
-class IptablesManager(object):
- """Wrapper for iptables.
-
- See IptablesTable for some usage docs
-
- A number of chains are set up to begin with.
-
- First, nova-filter-top. It's added at the top of FORWARD and OUTPUT. Its
- name is not wrapped, so it's shared between the various nova workers. It's
- intended for rules that need to live at the top of the FORWARD and OUTPUT
- chains. It's in both the ipv4 and ipv6 set of tables.
-
- For ipv4 and ipv6, the built-in INPUT, OUTPUT, and FORWARD filter chains
- are wrapped, meaning that the "real" INPUT chain has a rule that jumps to
- the wrapped INPUT chain, etc. Additionally, there's a wrapped chain named
- "local" which is jumped to from nova-filter-top.
-
- For ipv4, the built-in PREROUTING, OUTPUT, and POSTROUTING nat chains are
- wrapped in the same was as the built-in filter chains. Additionally,
- there's a snat chain that is applied after the POSTROUTING chain.
-
- """
-
- def __init__(self, redirect_privsep_calls_to=None):
- # NOTE(mikal): This is only used by the xenapi hypervisor driver,
- # which wants to intercept our calls to iptables and redirect them
- # to an agent running in dom0.
- # TODO(mikal): We really should make the dom0 agent feel more like
- # privsep. They really are the same thing, just one is from a simpler
- # time in our past.
- self.redirect_privsep = redirect_privsep_calls_to
-
- self.ipv4 = {'filter': IptablesTable(),
- 'nat': IptablesTable(),
- 'mangle': IptablesTable()}
- self.ipv6 = {'filter': IptablesTable()}
-
- self.iptables_apply_deferred = False
-
- # Add a nova-filter-top chain. It's intended to be shared
- # among the various nova components. It sits at the very top
- # of FORWARD and OUTPUT.
- for tables in [self.ipv4, self.ipv6]:
- tables['filter'].add_chain('nova-filter-top', wrap=False)
- tables['filter'].add_rule('FORWARD', '-j nova-filter-top',
- wrap=False, top=True)
- tables['filter'].add_rule('OUTPUT', '-j nova-filter-top',
- wrap=False, top=True)
-
- tables['filter'].add_chain('local')
- tables['filter'].add_rule('nova-filter-top', '-j $local',
- wrap=False)
-
- # Wrap the built-in chains
- builtin_chains = {4: {'filter': ['INPUT', 'OUTPUT', 'FORWARD'],
- 'nat': ['PREROUTING', 'OUTPUT', 'POSTROUTING'],
- 'mangle': ['POSTROUTING']},
- 6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
-
- for ip_version in builtin_chains:
- if ip_version == 4:
- tables = self.ipv4
- elif ip_version == 6:
- tables = self.ipv6
-
- for table, chains in builtin_chains[ip_version].items():
- for chain in chains:
- tables[table].add_chain(chain)
- tables[table].add_rule(chain, '-j $%s' % (chain,),
- wrap=False)
-
- # Add a nova-postrouting-bottom chain. It's intended to be shared
- # among the various nova components. We set it as the last chain
- # of POSTROUTING chain.
- self.ipv4['nat'].add_chain('nova-postrouting-bottom', wrap=False)
- self.ipv4['nat'].add_rule('POSTROUTING', '-j nova-postrouting-bottom',
- wrap=False)
-
- # We add a snat chain to the shared nova-postrouting-bottom chain
- # so that it's applied last.
- self.ipv4['nat'].add_chain('snat')
- self.ipv4['nat'].add_rule('nova-postrouting-bottom', '-j $snat',
- wrap=False)
-
- # And then we add a float-snat chain and jump to first thing in
- # the snat chain.
- self.ipv4['nat'].add_chain('float-snat')
- self.ipv4['nat'].add_rule('snat', '-j $float-snat')
-
- def defer_apply_on(self):
- self.iptables_apply_deferred = True
-
- def defer_apply_off(self):
- self.iptables_apply_deferred = False
- self.apply()
-
- def dirty(self):
- for table in six.itervalues(self.ipv4):
- if table.dirty:
- return True
- if CONF.use_ipv6:
- for table in six.itervalues(self.ipv6):
- if table.dirty:
- return True
- return False
-
- def apply(self):
- if self.iptables_apply_deferred:
- return
- if self.dirty():
- self._apply()
- else:
- LOG.debug("Skipping apply due to lack of new rules")
-
- @utils.synchronized('iptables', external=True)
- def _apply(self):
- """Apply the current in-memory set of iptables rules.
-
- This will blow away any rules left over from previous runs of the
- same component of Nova, and replace them with our current set of
- rules. This happens atomically, thanks to iptables-restore.
-
- """
- s = [(True, self.ipv4)]
- if CONF.use_ipv6:
- s += [(False, self.ipv6)]
-
- for is_ipv4, tables in s:
- if not self.redirect_privsep:
- all_tables, _err = nova.privsep.linux_net.iptables_get_rules(
- ipv4=is_ipv4)
- else:
- if is_ipv4:
- cmd = 'iptables-save'
- else:
- cmd = 'ip6tables-save'
- all_tables, _err = self.redirect_privsep(
- cmd, '-c', run_as_root=True, attempts=5)
-
- all_lines = all_tables.split('\n')
- for table_name, table in tables.items():
- start, end = self._find_table(all_lines, table_name)
- all_lines[start:end] = self._modify_rules(
- all_lines[start:end], table, table_name)
- table.dirty = False
-
- if not self.redirect_privsep:
- nova.privsep.linux_net.iptables_set_rules(all_lines,
- ipv4=is_ipv4)
- else:
- if is_ipv4:
- cmd = 'iptables-restore'
- else:
- cmd = 'ip6tables-restore'
- self.redirect_privsep(
- cmd, '-c', run_as_root=True,
- process_input=six.b('\n'.join(all_lines)),
- attempts=5)
-
- LOG.debug("IPTablesManager.apply completed with success")
-
- def _find_table(self, lines, table_name):
- if len(lines) < 3:
- # length only <2 when fake iptables
- return (0, 0)
- try:
- start = lines.index('*%s' % table_name) - 1
- except ValueError:
- # Couldn't find table_name
- return (0, 0)
- end = lines[start:].index('COMMIT') + start + 2
- return (start, end)
-
- @staticmethod
- def create_rules_from_regexp(criterion, new_filter):
- if not criterion:
- return [], new_filter
- regex = re.compile(criterion)
- temp_filter = [line for line in new_filter if regex.search(line)]
- for rule_str in temp_filter:
- new_filter = [s for s in new_filter
- if s.strip() != rule_str.strip()]
- return temp_filter, new_filter
-
- def _modify_rules(self, current_lines, table, table_name):
- unwrapped_chains = table.unwrapped_chains
- chains = sorted(table.chains)
- remove_chains = table.remove_chains
- rules = table.rules
- remove_rules = table.remove_rules
-
- if not current_lines:
- fake_table = ['#Generated by nova',
- '*' + table_name, 'COMMIT',
- '#Completed by nova']
- current_lines = fake_table
-
- # Remove any trace of our rules
- new_filter = [line for line in current_lines
- if binary_name not in line]
-
- top_rules, new_filter = self.create_rules_from_regexp(
- CONF.iptables_top_regex, new_filter)
- bottom_rules, new_filter = self.create_rules_from_regexp(
- CONF.iptables_bottom_regex, new_filter)
-
- seen_chains = False
- rules_index = 0
- for rules_index, rule in enumerate(new_filter):
- if not seen_chains:
- if rule.startswith(':'):
- seen_chains = True
- else:
- if not rule.startswith(':'):
- break
-
- if not seen_chains:
- rules_index = 2
-
- our_rules = top_rules
- bot_rules = []
- for rule in rules:
- rule_str = str(rule)
- if rule.top:
- # rule.top == True means we want this rule to be at the top.
- # Further down, we weed out duplicates from the bottom of the
- # list, so here we remove the dupes ahead of time.
-
- # We don't want to remove an entry if it has non-zero
- # [packet:byte] counts and replace it with [0:0], so let's
- # go look for a duplicate, and over-ride our table rule if
- # found.
-
- # ignore [packet:byte] counts at beginning of line
- if rule_str.startswith('['):
- rule_str = rule_str.split(']', 1)[1]
- dup_filter = [s for s in new_filter
- if rule_str.strip() in s.strip()]
-
- new_filter = [s for s in new_filter
- if rule_str.strip() not in s.strip()]
- # if no duplicates, use original rule
- if dup_filter:
- # grab the last entry, if there is one
- dup = list(dup_filter)[-1]
- rule_str = str(dup)
- else:
- rule_str = str(rule)
- rule_str.strip()
-
- our_rules += [rule_str]
- else:
- bot_rules += [rule_str]
-
- our_rules += bot_rules
-
- new_filter = list(new_filter)
- new_filter[rules_index:rules_index] = our_rules
-
- new_filter[rules_index:rules_index] = [':%s - [0:0]' % (name,)
- for name in unwrapped_chains]
- new_filter[rules_index:rules_index] = [':%s-%s - [0:0]' %
- (binary_name, name,)
- for name in chains]
-
- commit_index = new_filter.index('COMMIT')
- new_filter[commit_index:commit_index] = bottom_rules
- seen_lines = set()
-
- def _weed_out_duplicates(line):
- # ignore [packet:byte] counts at beginning of lines
- if line.startswith('['):
- line = line.split(']', 1)[1]
- line = line.strip()
- if line in seen_lines:
- return False
- else:
- seen_lines.add(line)
- return True
-
- def _weed_out_removes(line):
- # We need to find exact matches here
- if line.startswith(':'):
- # it's a chain, for example, ":nova-billing - [0:0]"
- # strip off everything except the chain name
- line = line.split(':')[1]
- line = line.split('- [')[0]
- line = line.strip()
- for chain in remove_chains:
- if chain == line:
- remove_chains.remove(chain)
- return False
- elif line.startswith('['):
- # it's a rule
- # ignore [packet:byte] counts at beginning of lines
- line = line.split(']', 1)[1]
- line = line.strip()
- for rule in remove_rules:
- # ignore [packet:byte] counts at beginning of rules
- rule_str = str(rule)
- rule_str = rule_str.split(' ', 1)[1]
- rule_str = rule_str.strip()
- if rule_str == line:
- remove_rules.remove(rule)
- return False
-
- # Leave it alone
- return True
-
- # We filter duplicates, letting the *last* occurrence take
- # precedence. We also filter out anything in the "remove"
- # lists.
- new_filter = list(new_filter)
- new_filter.reverse()
- new_filter = filter(_weed_out_duplicates, new_filter)
- new_filter = filter(_weed_out_removes, new_filter)
- new_filter = list(new_filter)
- new_filter.reverse()
-
- # flush lists, just in case we didn't find something
- remove_chains.clear()
- for rule in remove_rules:
- remove_rules.remove(rule)
-
- return new_filter
-
-
-# NOTE(jkoelker) This is just a nice little stub point since mocking
-# builtins with mox is a nightmare
-def write_to_file(file, data, mode='w'):
- with open(file, mode) as f:
- f.write(data)
-
-
-def is_pid_cmdline_correct(pid, match):
- """Ensure that the cmdline for a pid seems sane
-
- Because pids are recycled, blindly killing by pid is something to
- avoid. This provides the ability to include a substring that is
- expected in the cmdline as a safety check.
- """
- try:
- with open('/proc/%d/cmdline' % pid) as f:
- cmdline = f.read()
- return match in cmdline
- except EnvironmentError:
- return False
-
-
-def metadata_forward():
- """Create forwarding rule for metadata."""
- if CONF.metadata_host != '127.0.0.1':
- iptables_manager.ipv4['nat'].add_rule('PREROUTING',
- '-s 0.0.0.0/0 -d 169.254.169.254/32 '
- '-p tcp -m tcp --dport 80 -j DNAT '
- '--to-destination %s:%s' %
- (CONF.metadata_host,
- CONF.metadata_port))
- else:
- iptables_manager.ipv4['nat'].add_rule('PREROUTING',
- '-s 0.0.0.0/0 -d 169.254.169.254/32 '
- '-p tcp -m tcp --dport 80 '
- '-j REDIRECT --to-ports %s' %
- CONF.metadata_port)
- iptables_manager.apply()
-
-
-def _iptables_dest(ip):
- if ((netaddr.IPAddress(ip).version == 4 and ip == '127.0.0.1') or
- ip == '::1'):
- return '-m addrtype --dst-type LOCAL'
- else:
- return '-d %s' % ip
-
-
-def metadata_accept():
- """Create the filter accept rule for metadata."""
-
- rule = ('-p tcp -m tcp --dport %s %s -j ACCEPT' %
- (CONF.metadata_port, _iptables_dest(CONF.metadata_host)))
-
- if netaddr.IPAddress(CONF.metadata_host).version == 4:
- iptables_manager.ipv4['filter'].add_rule('INPUT', rule)
- else:
- iptables_manager.ipv6['filter'].add_rule('INPUT', rule)
-
- iptables_manager.apply()
-
-
-def add_snat_rule(ip_range, is_external=False):
- if CONF.routing_source_ip:
- if is_external:
- if CONF.force_snat_range:
- snat_range = CONF.force_snat_range
- else:
- snat_range = []
- else:
- snat_range = ['0.0.0.0/0']
- for dest_range in snat_range:
- rule = ('-s %s -d %s -j SNAT --to-source %s'
- % (ip_range, dest_range, CONF.routing_source_ip))
- if not is_external and CONF.public_interface:
- rule += ' -o %s' % CONF.public_interface
- iptables_manager.ipv4['nat'].add_rule('snat', rule)
- iptables_manager.apply()
-
-
-def init_host(ip_range, is_external=False):
- """Basic networking setup goes here."""
- # NOTE(devcamcar): Cloud public SNAT entries and the default
- # SNAT rule for outbound traffic.
-
- add_snat_rule(ip_range, is_external)
-
- rules = []
- if is_external:
- for snat_range in CONF.force_snat_range:
- rules.append('PREROUTING -p ipv4 --ip-src %s --ip-dst %s '
- '-j redirect --redirect-target ACCEPT' %
- (ip_range, snat_range))
- if rules:
- ensure_ebtables_rules(rules, 'nat')
-
- iptables_manager.ipv4['nat'].add_rule('POSTROUTING',
- '-s %s -d %s/32 -j ACCEPT' %
- (ip_range, CONF.metadata_host))
-
- for dmz in CONF.dmz_cidr:
- iptables_manager.ipv4['nat'].add_rule('POSTROUTING',
- '-s %s -d %s -j ACCEPT' %
- (ip_range, dmz))
-
- iptables_manager.ipv4['nat'].add_rule('POSTROUTING',
- '-s %(range)s -d %(range)s '
- '-m conntrack ! --ctstate DNAT '
- '-j ACCEPT' %
- {'range': ip_range})
- iptables_manager.apply()
-
-
-def bind_floating_ip(floating_ip, device):
- """Bind IP to public interface."""
- nova.privsep.linux_net.bind_ip(device, floating_ip)
- if CONF.send_arp_for_ha and CONF.send_arp_for_ha_count > 0:
- nova.privsep.linux_net.send_arp_for_ip(
- floating_ip, device, CONF.send_arp_for_ha_count)
-
-
-def ensure_metadata_ip():
- """Sets up local metadata IP."""
- nova.privsep.linux_net.bind_ip('lo', '169.254.169.254',
- scope_is_link=True)
-
-
-def ensure_vpn_forward(public_ip, port, private_ip):
- """Sets up forwarding rules for vlan."""
- iptables_manager.ipv4['filter'].add_rule('FORWARD',
- '-d %s -p udp '
- '--dport 1194 '
- '-j ACCEPT' % private_ip)
- iptables_manager.ipv4['nat'].add_rule('PREROUTING',
- '-d %s -p udp '
- '--dport %s -j DNAT --to %s:1194' %
- (public_ip, port, private_ip))
- iptables_manager.ipv4['nat'].add_rule('OUTPUT',
- '-d %s -p udp '
- '--dport %s -j DNAT --to %s:1194' %
- (public_ip, port, private_ip))
- iptables_manager.apply()
-
-
-def ensure_floating_forward(floating_ip, fixed_ip, device, network):
- """Ensure floating IP forwarding rule."""
- # NOTE(vish): Make sure we never have duplicate rules for the same ip
- regex = r'.*\s+%s(/32|\s+|$)' % floating_ip
- num_rules = iptables_manager.ipv4['nat'].remove_rules_regex(regex)
- if num_rules:
- LOG.warning('Removed %(num)d duplicate rules for floating IP '
- '%(float)s', {'num': num_rules, 'float': floating_ip})
- for chain, rule in floating_forward_rules(floating_ip, fixed_ip, device):
- iptables_manager.ipv4['nat'].add_rule(chain, rule)
- iptables_manager.apply()
- if device != network['bridge']:
- ensure_ebtables_rules(*floating_ebtables_rules(fixed_ip, network))
-
-
-def remove_floating_forward(floating_ip, fixed_ip, device, network):
- """Remove forwarding for floating IP."""
- for chain, rule in floating_forward_rules(floating_ip, fixed_ip, device):
- iptables_manager.ipv4['nat'].remove_rule(chain, rule)
- iptables_manager.apply()
- if device != network['bridge']:
- remove_ebtables_rules(*floating_ebtables_rules(fixed_ip, network))
-
-
-def floating_ebtables_rules(fixed_ip, network):
- """Makes sure only in-network traffic is bridged."""
- return (['PREROUTING --logical-in %s -p ipv4 --ip-src %s '
- '! --ip-dst %s -j redirect --redirect-target ACCEPT' %
- (network['bridge'], fixed_ip, network['cidr'])], 'nat')
-
-
-def floating_forward_rules(floating_ip, fixed_ip, device):
- rules = []
- rule = '-s %s -j SNAT --to %s' % (fixed_ip, floating_ip)
- if device:
- rules.append(('float-snat', rule + ' -d %s' % fixed_ip))
- rules.append(('float-snat', rule + ' -o %s' % device))
- else:
- rules.append(('float-snat', rule))
- rules.append(
- ('PREROUTING', '-d %s -j DNAT --to %s' % (floating_ip, fixed_ip)))
- rules.append(
- ('OUTPUT', '-d %s -j DNAT --to %s' % (floating_ip, fixed_ip)))
- rules.append(('POSTROUTING', '-s %s -m conntrack --ctstate DNAT -j SNAT '
- '--to-source %s' %
- (fixed_ip, floating_ip)))
- return rules
-
-
-@utils.synchronized('lock_gateway', external=True)
-def initialize_gateway_device(dev, network_ref):
- if not network_ref:
- return
-
- nova.privsep.linux_net.enable_ipv4_forwarding()
-
- # NOTE(vish): The ip for dnsmasq has to be the first address on the
- # bridge for it to respond to requests properly
- try:
- prefix = network_ref.cidr.prefixlen
- except AttributeError:
- prefix = network_ref['cidr'].rpartition('/')[2]
-
- full_ip = '%s/%s' % (network_ref['dhcp_server'], prefix)
- new_ip_params = [[full_ip, 'brd', network_ref['broadcast']]]
- old_ip_params = []
- out, err = nova.privsep.linux_net.lookup_ip(dev)
- for line in out.split('\n'):
- fields = line.split()
- if fields and fields[0] == 'inet':
- if fields[-2] in ('secondary', 'dynamic'):
- ip_params = fields[1:-2]
- else:
- ip_params = fields[1:-1]
- old_ip_params.append(ip_params)
- if ip_params[0] != full_ip:
- new_ip_params.append(ip_params)
- if not old_ip_params or old_ip_params[0][0] != full_ip:
- old_routes = []
- result = nova.privsep.linux_net.routes_show(dev)
- if result:
- out, err = result
- for line in out.split('\n'):
- fields = line.split()
- if fields and 'via' in fields:
- old_routes.append(fields)
- nova.privsep.linux_net.route_delete(dev, fields[0])
- for ip_params in old_ip_params:
- nova.privsep.linux_net.address_command_deprecated(
- dev, 'del', ip_params)
- for ip_params in new_ip_params:
- nova.privsep.linux_net.address_command_deprecated(
- dev, 'add', ip_params)
-
- for fields in old_routes:
- # TODO(mikal): this is horrible and should be re-written
- nova.privsep.linux_net.route_add_deprecated(fields)
- if CONF.send_arp_for_ha and CONF.send_arp_for_ha_count > 0:
- nova.privsep.linux_net.send_arp_for_ip(
- network_ref['dhcp_server'], dev,
- CONF.send_arp_for_ha_count)
- if CONF.use_ipv6:
- nova.privsep.linux_net.change_ip(dev, network_ref['cidr_v6'])
-
-
-def get_dhcp_leases(context, network_ref):
- """Return a network's hosts config in dnsmasq leasefile format."""
- hosts = []
- host = None
- if network_ref['multi_host']:
- host = CONF.host
- for fixedip in objects.FixedIPList.get_by_network(context,
- network_ref,
- host=host):
- # NOTE(cfb): Don't return a lease entry if the IP isn't
- # already leased
- if fixedip.leased:
- hosts.append(_host_lease(fixedip))
-
- return '\n'.join(hosts)
-
-
-def get_dhcp_hosts(context, network_ref, fixedips):
- """Get network's hosts config in dhcp-host format."""
- hosts = []
- macs = set()
- for fixedip in fixedips:
- if fixedip.allocated:
- if fixedip.virtual_interface.address not in macs:
- hosts.append(_host_dhcp(fixedip))
- macs.add(fixedip.virtual_interface.address)
- return '\n'.join(hosts)
-
-
-def get_dns_hosts(context, network_ref):
- """Get network's DNS hosts in hosts format."""
- hosts = []
- for fixedip in objects.FixedIPList.get_by_network(context, network_ref):
- if fixedip.allocated:
- hosts.append(_host_dns(fixedip))
- return '\n'.join(hosts)
-
-
-def _add_dnsmasq_accept_rules(dev):
- """Allow DHCP and DNS traffic through to dnsmasq."""
- table = iptables_manager.ipv4['filter']
- for port in [67, 53]:
- for proto in ['udp', 'tcp']:
- args = {'dev': dev, 'port': port, 'proto': proto}
- table.add_rule('INPUT',
- '-i %(dev)s -p %(proto)s -m %(proto)s '
- '--dport %(port)s -j ACCEPT' % args)
- iptables_manager.apply()
-
-
-def _remove_dnsmasq_accept_rules(dev):
- """Remove DHCP and DNS traffic allowed through to dnsmasq."""
- table = iptables_manager.ipv4['filter']
- for port in [67, 53]:
- for proto in ['udp', 'tcp']:
- args = {'dev': dev, 'port': port, 'proto': proto}
- table.remove_rule('INPUT',
- '-i %(dev)s -p %(proto)s -m %(proto)s '
- '--dport %(port)s -j ACCEPT' % args)
- iptables_manager.apply()
-
-
-# NOTE(russellb) Curious why this is needed? Check out this explanation from
-# markmc: https://bugzilla.redhat.com/show_bug.cgi?id=910619#c6
-def _add_dhcp_mangle_rule(dev):
- table = iptables_manager.ipv4['mangle']
- table.add_rule('POSTROUTING',
- '-o %s -p udp -m udp --dport 68 -j CHECKSUM '
- '--checksum-fill' % dev)
- iptables_manager.apply()
-
-
-def _remove_dhcp_mangle_rule(dev):
- table = iptables_manager.ipv4['mangle']
- table.remove_rule('POSTROUTING',
- '-o %s -p udp -m udp --dport 68 -j CHECKSUM '
- '--checksum-fill' % dev)
- iptables_manager.apply()
-
-
-def get_dhcp_opts(context, network_ref, fixedips):
- """Get network's hosts config in dhcp-opts format."""
- gateway = network_ref['gateway']
- # NOTE(vish): if we are in multi-host mode and we are not sharing
- # addresses, then we actually need to hand out the
- # dhcp server address as the gateway.
- if network_ref['multi_host'] and not (network_ref['share_address'] or
- CONF.share_dhcp_address):
- gateway = network_ref['dhcp_server']
- hosts = []
- if CONF.use_single_default_gateway:
- for fixedip in fixedips:
- if fixedip.allocated:
- vif_id = fixedip.virtual_interface_id
- if fixedip.default_route:
- hosts.append(_host_dhcp_opts(vif_id, gateway))
- else:
- hosts.append(_host_dhcp_opts(vif_id))
- else:
- hosts.append(_host_dhcp_opts(None, gateway))
- return '\n'.join(hosts)
-
-
-def release_dhcp(dev, address, mac_address):
- if nova.privsep.linux_net.device_exists(dev):
- try:
- nova.privsep.linux_net.dhcp_release(dev, address, mac_address)
- except processutils.ProcessExecutionError:
- raise exception.NetworkDhcpReleaseFailed(address=address,
- mac_address=mac_address)
-
-
-def update_dhcp(context, dev, network_ref):
- conffile = _dhcp_file(dev, 'conf')
- host = None
- if network_ref['multi_host']:
- host = CONF.host
- fixedips = objects.FixedIPList.get_by_network(context,
- network_ref,
- host=host)
- write_to_file(conffile, get_dhcp_hosts(context, network_ref, fixedips))
- restart_dhcp(context, dev, network_ref, fixedips)
-
-
-def update_dns(context, dev, network_ref):
- hostsfile = _dhcp_file(dev, 'hosts')
- host = None
- if network_ref['multi_host']:
- host = CONF.host
- fixedips = objects.FixedIPList.get_by_network(context,
- network_ref,
- host=host)
- write_to_file(hostsfile, get_dns_hosts(context, network_ref))
- restart_dhcp(context, dev, network_ref, fixedips)
-
-
-def kill_dhcp(dev):
- pid = _dnsmasq_pid_for(dev)
- if pid:
- # Check that the process exists and looks like a dnsmasq process
- conffile = _dhcp_file(dev, 'conf')
- if is_pid_cmdline_correct(pid, conffile.split('/')[-1]):
- nova.privsep.utils.kill(pid, signal.SIGKILL)
- else:
- LOG.debug('Pid %d is stale, skip killing dnsmasq', pid)
- _remove_dnsmasq_accept_rules(dev)
- _remove_dhcp_mangle_rule(dev)
-
-
-# NOTE(ja): Sending a HUP only reloads the hostfile, so any
-# configuration options (like dchp-range, vlan, ...)
-# aren't reloaded.
-@utils.synchronized('dnsmasq_start')
-def restart_dhcp(context, dev, network_ref, fixedips):
- """(Re)starts a dnsmasq server for a given network.
-
- If a dnsmasq instance is already running then send a HUP
- signal causing it to reload, otherwise spawn a new instance.
-
- """
- conffile = _dhcp_file(dev, 'conf')
-
- optsfile = _dhcp_file(dev, 'opts')
- write_to_file(optsfile, get_dhcp_opts(context, network_ref, fixedips))
- os.chmod(optsfile, 0o644)
-
- _add_dhcp_mangle_rule(dev)
-
- # Make sure dnsmasq can actually read it (it setuid()s to "nobody")
- os.chmod(conffile, 0o644)
-
- pid = _dnsmasq_pid_for(dev)
-
- # if dnsmasq is already running, then tell it to reload
- if pid:
- if is_pid_cmdline_correct(pid, conffile.split('/')[-1]):
- try:
- nova.privsep.utils.kill(pid, signal.SIGHUP)
- _add_dnsmasq_accept_rules(dev)
- return
- except Exception as exc:
- LOG.error('kill -HUP dnsmasq threw %s', exc)
- else:
- LOG.debug('Pid %d is stale, relaunching dnsmasq', pid)
-
- dns_servers = CONF.dns_server
- if CONF.use_network_dns_servers:
- if network_ref.get('dns1'):
- dns_servers.append(network_ref.get('dns1'))
- if network_ref.get('dns2'):
- dns_servers.append(network_ref.get('dns2'))
-
- hosts_path = None
- if network_ref['multi_host']:
- hosts_path = _dhcp_file(dev, 'hosts')
-
- nova.privsep.linux_net.restart_dnsmasq(
- jsonutils.dumps(CONF.dhcpbridge_flagfile),
- network_ref,
- CONF.dnsmasq_config_file,
- _dhcp_file(dev, 'pid'),
- _dhcp_file(dev, 'opts'),
- CONF.dhcp_lease_time,
- len(netaddr.IPNetwork(network_ref['cidr'])),
- _dhcp_file(dev, 'conf'),
- CONF.dhcpbridge,
- CONF.api.dhcp_domain,
- dns_servers,
- hosts_path)
-
- _add_dnsmasq_accept_rules(dev)
-
-
-@utils.synchronized('radvd_start')
-def update_ra(context, dev, network_ref):
- conffile = _ra_file(dev, 'conf')
- conf_str = """
-interface %s
-{
- AdvSendAdvert on;
- MinRtrAdvInterval 3;
- MaxRtrAdvInterval 10;
- prefix %s
- {
- AdvOnLink on;
- AdvAutonomous on;
- };
-};
-""" % (dev, network_ref['cidr_v6'])
- write_to_file(conffile, conf_str)
-
- # Make sure radvd can actually read it (it setuid()s to "nobody")
- os.chmod(conffile, 0o644)
-
- pid = _ra_pid_for(dev)
-
- # if radvd is already running, then tell it to reload
- if pid:
- if is_pid_cmdline_correct(pid, conffile):
- try:
- nova.privsep.utils.kill(pid, signal.SIGTERM)
- except Exception as exc:
- LOG.error('killing radvd threw %s', exc)
- else:
- LOG.debug('Pid %d is stale, relaunching radvd', pid)
-
- nova.privsep.linux_net.start_ra(_ra_file(dev, 'conf'),
- _ra_file(dev, 'pid'))
-
-
-def _host_lease(fixedip):
- """Return a host string for an address in leasefile format."""
- timestamp = timeutils.utcnow()
- seconds_since_epoch = calendar.timegm(timestamp.utctimetuple())
- return '%d %s %s %s *' % (seconds_since_epoch + CONF.dhcp_lease_time,
- fixedip.virtual_interface.address,
- fixedip.address,
- fixedip.instance.hostname or '*')
-
-
-def _host_dhcp_network(vif_id):
- return 'NW-%s' % vif_id
-
-
-def _host_dhcp(fixedip):
- """Return a host string for an address in dhcp-host format."""
- # NOTE(cfb): dnsmasq on linux only supports 64 characters in the hostname
- # field (LP #1238910). Since the . counts as a character we need
- # to truncate the hostname to only 63 characters.
- hostname = fixedip.instance.hostname
- if len(hostname) > 63:
- LOG.warning('hostname %s too long, truncating.', hostname)
- hostname = fixedip.instance.hostname[:2] + '-' +\
- fixedip.instance.hostname[-60:]
- if CONF.use_single_default_gateway:
- net = _host_dhcp_network(fixedip.virtual_interface_id)
- return '%s,%s.%s,%s,net:%s' % (fixedip.virtual_interface.address,
- hostname,
- CONF.api.dhcp_domain,
- fixedip.address,
- net)
- else:
- return '%s,%s.%s,%s' % (fixedip.virtual_interface.address,
- hostname,
- CONF.api.dhcp_domain,
- fixedip.address)
-
-
-def _host_dns(fixedip):
- return '%s\t%s.%s' % (fixedip.address,
- fixedip.instance.hostname,
- CONF.api.dhcp_domain)
-
-
-def _host_dhcp_opts(vif_id=None, gateway=None):
- """Return an empty gateway option."""
- values = []
- if vif_id is not None:
- values.append(_host_dhcp_network(vif_id))
- # NOTE(vish): 3 is the dhcp option for gateway.
- values.append('3')
- if gateway:
- values.append('%s' % gateway)
- return ','.join(values)
-
-
-def _dhcp_file(dev, kind):
- """Return path to a pid, leases, hosts or conf file for a bridge/device."""
- fileutils.ensure_tree(CONF.networks_path)
- return os.path.abspath('%s/nova-%s.%s' % (CONF.networks_path,
- dev,
- kind))
-
-
-def _ra_file(dev, kind):
- """Return path to a pid or conf file for a bridge/device."""
- fileutils.ensure_tree(CONF.networks_path)
- return os.path.abspath('%s/nova-ra-%s.%s' % (CONF.networks_path,
- dev,
- kind))
-
-
-def _dnsmasq_pid_for(dev):
- """Returns the pid for prior dnsmasq instance for a bridge/device.
-
- Returns None if no pid file exists.
-
- If machine has rebooted pid might be incorrect (caller should check).
-
- """
- pid_file = _dhcp_file(dev, 'pid')
-
- if os.path.exists(pid_file):
- try:
- with open(pid_file, 'r') as f:
- return int(f.read())
- except (ValueError, IOError):
- return None
-
-
-def _ra_pid_for(dev):
- """Returns the pid for prior radvd instance for a bridge/device.
-
- Returns None if no pid file exists.
-
- If machine has rebooted pid might be incorrect (caller should check).
-
- """
- pid_file = _ra_file(dev, 'pid')
-
- if os.path.exists(pid_file):
- with open(pid_file, 'r') as f:
- return int(f.read())
-
-
-def delete_bridge_dev(dev):
- """Delete a network bridge."""
- if nova.privsep.linux_net.device_exists(dev):
- try:
- nova.privsep.linux_net.set_device_disabled(dev)
- nova.privsep.linux_net.delete_bridge(dev)
- except processutils.ProcessExecutionError:
- with excutils.save_and_reraise_exception():
- LOG.error("Failed removing bridge device: '%s'", dev)
-
-
-# Similar to compute virt layers, the Linux network node
-# code uses a flexible driver model to support different ways
-# of creating ethernet interfaces and attaching them to the network.
-# In the case of a network host, these interfaces
-# act as gateway/dhcp/vpn/etc. endpoints not VM interfaces.
-interface_driver = None
-
-
-def _get_interface_driver():
- global interface_driver
- if not interface_driver:
- interface_driver = importutils.import_object(
- CONF.linuxnet_interface_driver)
- return interface_driver
-
-
-def plug(network, mac_address, gateway=True):
- return _get_interface_driver().plug(network, mac_address, gateway)
-
-
-def unplug(network):
- return _get_interface_driver().unplug(network)
-
-
-def get_dev(network):
- return _get_interface_driver().get_dev(network)
-
-
-class LinuxNetInterfaceDriver(object):
- """Abstract class that defines generic network host API
- for all Linux interface drivers.
- """
-
- def plug(self, network, mac_address):
- """Create Linux device, return device name."""
- raise NotImplementedError()
-
- def unplug(self, network):
- """Destroy Linux device, return device name."""
- raise NotImplementedError()
-
- def get_dev(self, network):
- """Get device name."""
- raise NotImplementedError()
-
-
-# plugs interfaces using Linux Bridge
-class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
-
- def plug(self, network, mac_address, gateway=True):
- vlan = network.get('vlan')
- if vlan is not None:
- iface = CONF.vlan_interface or network['bridge_interface']
- LinuxBridgeInterfaceDriver.ensure_vlan_bridge(
- vlan,
- network['bridge'],
- iface,
- network,
- mac_address,
- network.get('mtu'))
- iface = 'vlan%s' % vlan
- else:
- iface = CONF.flat_interface or network['bridge_interface']
- LinuxBridgeInterfaceDriver.ensure_bridge(
- network['bridge'],
- iface,
- network, gateway)
-
- if network['share_address'] or CONF.share_dhcp_address:
- isolate_dhcp_address(iface, network['dhcp_server'])
- # NOTE(vish): applying here so we don't get a lock conflict
- iptables_manager.apply()
- return network['bridge']
-
- def unplug(self, network, gateway=True):
- vlan = network.get('vlan')
- if vlan is not None:
- iface = 'vlan%s' % vlan
- LinuxBridgeInterfaceDriver.remove_vlan_bridge(vlan,
- network['bridge'])
- else:
- iface = CONF.flat_interface or network['bridge_interface']
- LinuxBridgeInterfaceDriver.remove_bridge(network['bridge'],
- gateway)
-
- if network['share_address'] or CONF.share_dhcp_address:
- remove_isolate_dhcp_address(iface, network['dhcp_server'])
-
- iptables_manager.apply()
- return self.get_dev(network)
-
- def get_dev(self, network):
- return network['bridge']
-
- @staticmethod
- def ensure_vlan_bridge(vlan_num, bridge, bridge_interface,
- net_attrs=None, mac_address=None,
- mtu=None):
- """Create a vlan and bridge unless they already exist."""
- interface = LinuxBridgeInterfaceDriver.ensure_vlan(vlan_num,
- bridge_interface, mac_address,
- mtu)
- LinuxBridgeInterfaceDriver.ensure_bridge(bridge, interface, net_attrs)
- return interface
-
- @staticmethod
- def remove_vlan_bridge(vlan_num, bridge):
- """Delete a bridge and vlan."""
- LinuxBridgeInterfaceDriver.remove_bridge(bridge)
- LinuxBridgeInterfaceDriver.remove_vlan(vlan_num)
-
- @staticmethod
- @utils.synchronized('lock_vlan', external=True)
- def ensure_vlan(vlan_num, bridge_interface, mac_address=None, mtu=None,
- interface=None):
- """Create a vlan unless it already exists."""
- if interface is None:
- interface = 'vlan%s' % vlan_num
- if not nova.privsep.linux_net.device_exists(interface):
- LOG.debug('Starting VLAN interface %s', interface)
- nova.privsep.linux_net.add_vlan(bridge_interface, interface,
- vlan_num)
- # (danwent) the bridge will inherit this address, so we want to
- # make sure it is the value set from the NetworkManager
- if mac_address:
- nova.privsep.linux_net.set_device_macaddr(
- interface, mac_address)
- nova.privsep.linux_net.set_device_enabled(interface)
- # NOTE(vish): set mtu every time to ensure that changes to mtu get
- # propagated
- nova.privsep.linux_net.set_device_mtu(interface, mtu)
- return interface
-
- @staticmethod
- @utils.synchronized('lock_vlan', external=True)
- def remove_vlan(vlan_num):
- """Delete a vlan."""
- vlan_interface = 'vlan%s' % vlan_num
- nova.privsep.linux_net.delete_net_dev(vlan_interface)
-
- @staticmethod
- @utils.synchronized('lock_bridge', external=True)
- def ensure_bridge(bridge, interface, net_attrs=None, gateway=True,
- filtering=True):
- """Create a bridge unless it already exists.
-
- :param interface: the interface to create the bridge on.
- :param net_attrs: dictionary with attributes used to create bridge.
- :param gateway: whether or not the bridge is a gateway.
- :param filtering: whether or not to create filters on the bridge.
-
- If net_attrs is set, it will add the net_attrs['gateway'] to the bridge
- using net_attrs['broadcast'] and net_attrs['cidr']. It will also add
- the ip_v6 address specified in net_attrs['cidr_v6'] if use_ipv6 is set.
-
- The code will attempt to move any IPs that already exist on the
- interface onto the bridge and reset the default gateway if necessary.
-
- """
- if not nova.privsep.linux_net.device_exists(bridge):
- LOG.debug('Starting Bridge %s', bridge)
- out, err = nova.privsep.linux_net.add_bridge(bridge)
- if (err and err != "device %s already exists; can't create "
- "bridge with the same name\n" % (bridge)):
- msg = _('Failed to add bridge: %s') % err
- raise exception.NovaException(msg)
-
- nova.privsep.linux_net.bridge_setfd(bridge)
- nova.privsep.linux_net.bridge_disable_stp(bridge)
- nova.privsep.linux_net.set_device_enabled(bridge)
-
- if interface:
- LOG.debug('Adding interface %(interface)s to bridge %(bridge)s',
- {'interface': interface, 'bridge': bridge})
- out, err = nova.privsep.linux_net.bridge_add_interface(
- bridge, interface)
- if (err and err != "device %s is already a member of a bridge; "
- "can't enslave it to bridge %s.\n" % (interface, bridge)):
- msg = _('Failed to add interface: %s') % err
- raise exception.NovaException(msg)
-
- # NOTE(apmelton): Linux bridge's default behavior is to use the
- # lowest mac of all plugged interfaces. This isn't a problem when
- # it is first created and the only interface is the bridged
- # interface. But, as instance interfaces are plugged, there is a
- # chance for the mac to change. So, set it here so that it won't
- # change in the future.
- if not CONF.fake_network:
- interface_addrs = netifaces.ifaddresses(interface)
- interface_mac = interface_addrs[netifaces.AF_LINK][0]['addr']
- nova.privsep.linux_net.set_device_macaddr(
- bridge, interface_mac)
-
- nova.privsep.linux_net.set_device_enabled(interface)
-
- # NOTE(vish): This will break if there is already an ip on the
- # interface, so we move any ips to the bridge
- # NOTE(danms): We also need to copy routes to the bridge so as
- # not to break existing connectivity on the interface
- old_routes = []
- out, err = nova.privsep.linux_net.routes_show(interface)
- for line in out.split('\n'):
- fields = line.split()
- if fields and 'via' in fields:
- old_routes.append(fields)
- nova.privsep.linux_net.route_delete_deprecated(fields)
- out, err = nova.privsep.linux_net.lookup_ip(interface)
- for line in out.split('\n'):
- fields = line.split()
- if fields and fields[0] == 'inet':
- if fields[-2] in ('secondary', 'dynamic', ):
- params = fields[1:-2]
- else:
- params = fields[1:-1]
- nova.privsep.linux_net.address_command_deprecated(
- fields[-1], 'del', params)
- nova.privsep.linux_net.address_command_deprecated(
- bridge, 'add', params)
- for fields in old_routes:
- nova.privsep.linux_net.route_add_deprecated(fields)
-
- if filtering:
- # Don't forward traffic unless we were told to be a gateway
- ipv4_filter = iptables_manager.ipv4['filter']
- if gateway:
- for rule in get_gateway_rules(bridge):
- ipv4_filter.add_rule(*rule)
- else:
- ipv4_filter.add_rule('FORWARD',
- ('--in-interface %s -j %s'
- % (bridge, CONF.iptables_drop_action)))
- ipv4_filter.add_rule('FORWARD',
- ('--out-interface %s -j %s'
- % (bridge, CONF.iptables_drop_action)))
-
- @staticmethod
- @utils.synchronized('lock_bridge', external=True)
- def remove_bridge(bridge, gateway=True, filtering=True):
- """Delete a bridge."""
- if not nova.privsep.linux_net.device_exists(bridge):
- return
- else:
- if filtering:
- ipv4_filter = iptables_manager.ipv4['filter']
- if gateway:
- for rule in get_gateway_rules(bridge):
- ipv4_filter.remove_rule(*rule)
- else:
- drop_actions = ['DROP']
- if CONF.iptables_drop_action != 'DROP':
- drop_actions.append(CONF.iptables_drop_action)
-
- for drop_action in drop_actions:
- ipv4_filter.remove_rule('FORWARD',
- ('--in-interface %s -j %s'
- % (bridge, drop_action)))
- ipv4_filter.remove_rule('FORWARD',
- ('--out-interface %s -j %s'
- % (bridge, drop_action)))
- delete_bridge_dev(bridge)
-
-
-# NOTE(cfb): Fix for LP #1316621, #1501366.
-# We call ebtables with --concurrent which causes ebtables to
-# use a lock file to deal with concurrent calls. Since we can't
-# be sure the libvirt also uses --concurrent we retry in a loop
-# to be sure.
-#
-# ebtables doesn't implement a timeout and doesn't gracefully
-# handle cleaning up a lock file if someone sends a SIGKILL to
-# ebtables while its holding a lock. As a result we want to add
-# a timeout to the ebtables calls but we first need to teach
-# oslo_concurrency how to do that.
-def _exec_ebtables(table, rule, insert_rule=True, check_exit_code=True):
- # List of error strings to re-try.
- retry_strings = (
- 'Multiple ebtables programs',
- )
-
- # We always try at least once
- attempts = CONF.ebtables_exec_attempts
- count = 1
- while count <= attempts:
- # Updated our counters if needed
- sleep = CONF.ebtables_retry_interval * count
- count += 1
- # NOTE(cfb): ebtables reports all errors with a return code of 255.
- # As such we can't know if we hit a locking error, or some
- # other error (like a rule doesn't exist) so we have to
- # to parse stderr.
- try:
- nova.privsep.linux_net.modify_ebtables(table, rule,
- insert_rule=insert_rule)
- except processutils.ProcessExecutionError as exc:
- # See if we can retry the error.
- if any(error in exc.stderr for error in retry_strings):
- if count > attempts and check_exit_code:
- LOG.warning('Rule edit for %s failed. Not Retrying.',
- table)
- raise
- else:
- # We need to sleep a bit before retrying
- LOG.warning('Rule edit for %(table)s failed. '
- 'Sleeping %(time)s seconds before retry.',
- {'table': table, 'time': sleep})
- time.sleep(sleep)
- else:
- # Not eligible for retry
- if check_exit_code:
- LOG.warning('Rule edit for %s failed and not eligible '
- 'for retry.',
- table)
- raise
- else:
- return
- else:
- # Success
- return
-
-
-@utils.synchronized('ebtables', external=True)
-def ensure_ebtables_rules(rules, table='filter'):
- for rule in rules:
- _exec_ebtables(table, rule.split(), insert_rule=False,
- check_exit_code=False)
- _exec_ebtables(table, rule.split())
-
-
-@utils.synchronized('ebtables', external=True)
-def remove_ebtables_rules(rules, table='filter'):
- for rule in rules:
- _exec_ebtables(table, rule.split(), insert_rule=False,
- check_exit_code=False)
-
-
-def isolate_dhcp_address(interface, address):
- # block arp traffic to address across the interface
- rules = []
- rules.append('INPUT -p ARP -i %s --arp-ip-dst %s -j DROP'
- % (interface, address))
- rules.append('OUTPUT -p ARP -o %s --arp-ip-src %s -j DROP'
- % (interface, address))
- rules.append('FORWARD -p IPv4 -i %s --ip-protocol udp '
- '--ip-destination-port 67:68 -j DROP'
- % interface)
- rules.append('FORWARD -p IPv4 -o %s --ip-protocol udp '
- '--ip-destination-port 67:68 -j DROP'
- % interface)
- # NOTE(vish): the above is not possible with iptables/arptables
- ensure_ebtables_rules(rules)
-
-
-def remove_isolate_dhcp_address(interface, address):
- # block arp traffic to address across the interface
- rules = []
- rules.append('INPUT -p ARP -i %s --arp-ip-dst %s -j DROP'
- % (interface, address))
- rules.append('OUTPUT -p ARP -o %s --arp-ip-src %s -j DROP'
- % (interface, address))
- rules.append('FORWARD -p IPv4 -i %s --ip-protocol udp '
- '--ip-destination-port 67:68 -j DROP'
- % interface)
- rules.append('FORWARD -p IPv4 -o %s --ip-protocol udp '
- '--ip-destination-port 67:68 -j DROP'
- % interface)
- remove_ebtables_rules(rules)
- # NOTE(vish): the above is not possible with iptables/arptables
-
-
-def get_gateway_rules(bridge):
- interfaces = CONF.forward_bridge_interface
- if 'all' in interfaces:
- return [('FORWARD', '-i %s -j ACCEPT' % bridge),
- ('FORWARD', '-o %s -j ACCEPT' % bridge)]
- rules = []
- for iface in CONF.forward_bridge_interface:
- if iface:
- rules.append(('FORWARD', '-i %s -o %s -j ACCEPT' % (bridge,
- iface)))
- rules.append(('FORWARD', '-i %s -o %s -j ACCEPT' % (iface,
- bridge)))
- rules.append(('FORWARD', '-i %s -o %s -j ACCEPT' % (bridge, bridge)))
- rules.append(('FORWARD', '-i %s -j %s' % (bridge,
- CONF.iptables_drop_action)))
- rules.append(('FORWARD', '-o %s -j %s' % (bridge,
- CONF.iptables_drop_action)))
- return rules
-
-
-# plugs interfaces using Open vSwitch
-class LinuxOVSInterfaceDriver(LinuxNetInterfaceDriver):
-
- def plug(self, network, mac_address, gateway=True):
- dev = self.get_dev(network)
- if not nova.privsep.linux_net.device_exists(dev):
- bridge = CONF.linuxnet_ovs_integration_bridge
-
- nova.privsep.linux_net.ovs_plug(CONF.ovs_vsctl_timeout,
- bridge, dev, mac_address)
- nova.privsep.linux_net.set_device_macaddr(
- dev, mac_address)
- nova.privsep.linux_net.set_device_mtu(dev, network.get('mtu'))
- nova.privsep.linux_net.set_device_enabled(dev)
- if not gateway:
- # If we weren't instructed to act as a gateway then add the
- # appropriate flows to block all non-dhcp traffic.
- nova.privsep.linux_net.ovs_drop_nondhcp(
- bridge, mac_address)
-
- # .. and make sure iptbles won't forward it as well.
- iptables_manager.ipv4['filter'].add_rule('FORWARD',
- '--in-interface %s -j %s' % (bridge,
- CONF.iptables_drop_action))
- iptables_manager.ipv4['filter'].add_rule('FORWARD',
- '--out-interface %s -j %s' % (bridge,
- CONF.iptables_drop_action))
- else:
- for rule in get_gateway_rules(bridge):
- iptables_manager.ipv4['filter'].add_rule(*rule)
-
- return dev
-
- def unplug(self, network):
- dev = self.get_dev(network)
- bridge = CONF.linuxnet_ovs_integration_bridge
-
- nova.privsep.linux_net.ovs_unplug(CONF.ovs_vsctl_timeout, bridge, dev)
-
- return dev
-
- def get_dev(self, network):
- dev = 'gw-' + str(network['uuid'][0:11])
- return dev
-
-
-iptables_manager = IptablesManager()
-
-
-def set_vf_trusted(pci_addr, trusted):
- """Configures the VF to be trusted or not
-
- :param pci_addr: PCI slot of the device
- :param trusted: Boolean value to indicate whether to
- enable/disable 'trusted' capability
- """
- pf_ifname = pci_utils.get_ifname_by_pci_address(pci_addr,
- pf_interface=True)
- vf_num = pci_utils.get_vf_num_by_pci_address(pci_addr)
- nova.privsep.linux_net.set_device_trust(
- pf_ifname, vf_num, trusted)
diff --git a/nova/network/manager.py b/nova/network/manager.py
deleted file mode 100644
index 9b995f0eef..0000000000
--- a/nova/network/manager.py
+++ /dev/null
@@ -1,2165 +0,0 @@
-# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-# Copyright 2013 IBM Corp.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Network Hosts are responsible for allocating IPs and setting up network.
-
-There are multiple backend drivers that handle specific types of networking
-topologies. All of the network commands are issued to a subclass of
-:class:`NetworkManager`.
-
-"""
-
-import collections
-import datetime
-import functools
-import math
-import re
-
-import netaddr
-from oslo_concurrency import processutils
-from oslo_log import log as logging
-import oslo_messaging as messaging
-from oslo_service import periodic_task
-from oslo_utils import excutils
-from oslo_utils import importutils
-from oslo_utils import netutils
-from oslo_utils import strutils
-from oslo_utils import timeutils
-from oslo_utils import uuidutils
-import six
-
-import nova.conf
-from nova import context
-from nova import exception
-from nova.i18n import _
-from nova import ipv6
-from nova import manager
-from nova.network import api as network_api
-from nova.network import driver
-from nova.network import floating_ips
-from nova.network import model as network_model
-from nova.network import rpcapi as network_rpcapi
-from nova.network.security_group import openstack_driver
-from nova import objects
-from nova.objects import base as obj_base
-from nova.objects import quotas as quotas_obj
-from nova import servicegroup
-from nova import utils
-
-LOG = logging.getLogger(__name__)
-
-CONF = nova.conf.CONF
-
-
-def get_my_linklocal(interface):
- try:
- if_str = processutils.execute(
- 'ip', '-f', 'inet6', '-o', 'addr', 'show', interface)
- condition = r'\s+inet6\s+([0-9a-f:]+)/\d+\s+scope\s+link'
- links = [re.search(condition, x) for x in if_str[0].split('\n')]
- address = [w.group(1) for w in links if w is not None]
- if address[0] is not None:
- return address[0]
- else:
- msg = _('Link Local address is not found.:%s') % if_str
- raise exception.NovaException(msg)
- except Exception as ex:
- msg = _("Couldn't get Link Local IP of %(interface)s"
- " :%(ex)s") % {'interface': interface, 'ex': ex}
- raise exception.NovaException(msg)
-
-
-class RPCAllocateFixedIP(object):
- """Mixin class originally for FlatDCHP and VLAN network managers.
-
- used since they share code to RPC.call allocate_fixed_ip on the
- correct network host to configure dnsmasq
- """
-
- servicegroup_api = None
-
- def _allocate_fixed_ips(self, context, instance_id, host, networks,
- **kwargs):
- """Calls allocate_fixed_ip once for each network."""
- green_threads = []
-
- vpn = kwargs.get('vpn')
- requested_networks = kwargs.get('requested_networks')
- addresses_by_network = {}
- if requested_networks is not None:
- for request in requested_networks:
- addresses_by_network[request.network_id] = request.address
-
- for network in networks:
- if 'uuid' in network and network['uuid'] in addresses_by_network:
- address = addresses_by_network[network['uuid']]
- else:
- address = None
- # NOTE(vish): if we are not multi_host pass to the network host
- # NOTE(tr3buchet): but if we are, host came from instance.host
- if not network['multi_host']:
- host = network['host']
- # NOTE(vish): if there is no network host, set one
- if host is None:
- host = self.network_rpcapi.set_network_host(context,
- network)
- if host != self.host:
- # need to call allocate_fixed_ip to correct network host
- green_threads.append(utils.spawn(
- self.network_rpcapi._rpc_allocate_fixed_ip,
- context, instance_id, network['id'], address, vpn,
- host))
- else:
- # i am the correct host, run here
- self.allocate_fixed_ip(context, instance_id, network,
- vpn=vpn, address=address)
-
- # wait for all of the allocates (if any) to finish
- for gt in green_threads:
- gt.wait()
-
- def _rpc_allocate_fixed_ip(self, context, instance_id, network_id,
- **kwargs):
- """Sits in between _allocate_fixed_ips and allocate_fixed_ip to
- perform network lookup on the far side of rpc.
- """
- network = self._get_network_by_id(context, network_id)
- return self.allocate_fixed_ip(context, instance_id, network, **kwargs)
-
- def deallocate_fixed_ip(self, context, address, host=None, teardown=True,
- instance=None):
- """Call the superclass deallocate_fixed_ip if i'm the correct host
- otherwise call to the correct host
- """
- fixed_ip = objects.FixedIP.get_by_address(
- context, address, expected_attrs=['network'])
- network = fixed_ip.network
-
- # NOTE(vish): if we are not multi_host pass to the network host
- # NOTE(tr3buchet): but if we are, host came from instance.host
- if not network.multi_host:
- host = network.host
- if host == self.host:
- # NOTE(vish): deallocate the fixed ip locally
- return super(RPCAllocateFixedIP, self).deallocate_fixed_ip(context,
- address, instance=instance)
-
- if network.multi_host:
- service = objects.Service.get_by_host_and_binary(
- context, host, 'nova-network')
- if not service or not self.servicegroup_api.service_is_up(service):
- # NOTE(vish): deallocate the fixed ip locally but don't
- # teardown network devices
- return super(RPCAllocateFixedIP, self).deallocate_fixed_ip(
- context, address, teardown=False, instance=instance)
-
- self.network_rpcapi.deallocate_fixed_ip(context, address, host,
- instance)
-
-
-class NetworkManager(manager.Manager):
- """Implements common network manager functionality.
-
- This class must be subclassed to support specific topologies.
-
- host management:
- hosts configure themselves for networks they are assigned to in the
- table upon startup. If there are networks in the table which do not
- have hosts, those will be filled in and have hosts configured
- as the hosts pick them up one at time during their periodic task.
- The one at a time part is to flatten the layout to help scale
- """
-
- target = messaging.Target(version='1.17')
-
- # If True, this manager requires VIF to create a bridge.
- SHOULD_CREATE_BRIDGE = False
-
- # If True, this manager requires VIF to create VLAN tag.
- SHOULD_CREATE_VLAN = False
-
- # if True, this manager leverages DHCP
- DHCP = False
-
- timeout_fixed_ips = True
-
- required_create_args = []
-
- def __init__(self, network_driver=None, *args, **kwargs):
- self.driver = driver.load_network_driver(network_driver)
- self.instance_dns_manager = importutils.import_object(
- CONF.instance_dns_manager)
- self.instance_dns_domain = CONF.instance_dns_domain
- self.floating_dns_manager = importutils.import_object(
- CONF.floating_ip_dns_manager)
- self.network_api = network_api.API()
- self.network_rpcapi = network_rpcapi.NetworkAPI()
- self.security_group_api = (
- openstack_driver.get_openstack_security_group_driver())
-
- self.servicegroup_api = servicegroup.API()
-
- l3_lib = kwargs.get("l3_lib", CONF.l3_lib)
- self.l3driver = importutils.import_object(l3_lib)
-
- self.quotas_cls = objects.Quotas
-
- super(NetworkManager, self).__init__(service_name='network',
- *args, **kwargs)
-
- @staticmethod
- def _uses_shared_ip(network):
- shared = network.get('share_address') or CONF.share_dhcp_address
- return not network.get('multi_host') or shared
-
- @utils.synchronized('get_dhcp')
- def _get_dhcp_ip(self, context, network_ref, host=None):
- """Get the proper dhcp address to listen on."""
- # NOTE(vish): If we are sharing the dhcp_address then we can just
- # return the dhcp_server from the database.
- if self._uses_shared_ip(network_ref):
- return network_ref.get('dhcp_server') or network_ref['gateway']
-
- if not host:
- host = self.host
- network_id = network_ref['id']
- try:
- fip = objects.FixedIP.get_by_network_and_host(context,
- network_id,
- host)
- return fip.address
- except exception.FixedIpNotFoundForNetworkHost:
- elevated = context.elevated()
- fip = objects.FixedIP.associate_pool(elevated,
- network_id,
- host=host)
- return fip.address
-
- def get_dhcp_leases(self, ctxt, network_ref):
- """Broker the request to the driver to fetch the dhcp leases."""
- LOG.debug('Get DHCP leases for network %s', network_ref['uuid'])
- return self.driver.get_dhcp_leases(ctxt, network_ref)
-
- def init_host(self):
- """Do any initialization that needs to be run if this is a
- standalone service.
- """
- # NOTE(vish): Set up networks for which this host already has
- # an ip address.
- ctxt = context.get_admin_context()
- for network in objects.NetworkList.get_by_host(ctxt, self.host):
- self._setup_network_on_host(ctxt, network)
- if CONF.update_dns_entries:
- LOG.debug('Update DNS on network %s for host %s',
- network['uuid'], self.host)
- dev = self.driver.get_dev(network)
- self.driver.update_dns(ctxt, dev, network)
- LOG.info('Configured network %(network)s on host %(host)s',
- {'network': network['uuid'], 'host': self.host})
-
- @periodic_task.periodic_task
- def _disassociate_stale_fixed_ips(self, context):
- if self.timeout_fixed_ips:
- now = timeutils.utcnow()
- timeout = CONF.fixed_ip_disassociate_timeout
- time = now - datetime.timedelta(seconds=timeout)
- num = objects.FixedIP.disassociate_all_by_timeout(context,
- self.host,
- time)
- if num:
- LOG.debug('Disassociated %s stale fixed IP(s)', num)
-
- def set_network_host(self, context, network_ref):
- """Safely sets the host of the network."""
- # TODO(mriedem): Remove this compat shim when network RPC API version
- # 1.0 is dropped.
- if not isinstance(network_ref, obj_base.NovaObject):
- network_ref = objects.Network._from_db_object(
- context, objects.Network(), network_ref)
- LOG.debug('Setting host %s for network %s', self.host,
- network_ref.uuid)
- network_ref.host = self.host
- network_ref.save()
- return self.host
-
- def _do_trigger_security_group_members_refresh_for_instance(self,
- instance_id):
- # NOTE(francois.charlier): the instance may have been deleted already
- # thus enabling `read_deleted`
- admin_context = context.get_admin_context(read_deleted='yes')
- instance = objects.Instance.get_by_uuid(admin_context, instance_id)
-
- try:
- # NOTE(vish): We need to make sure the instance info cache has been
- # updated with new ip info before we trigger the
- # security group refresh. This is somewhat inefficient
- # but avoids doing some dangerous refactoring for a
- # bug fix.
- nw_info = self.get_instance_nw_info(admin_context, instance_id,
- None, None)
- ic = objects.InstanceInfoCache.new(admin_context, instance_id)
- ic.network_info = nw_info
- ic.save()
- except exception.InstanceInfoCacheNotFound:
- pass
- groups = instance.security_groups
- group_ids = [group.id for group in groups]
-
- self.security_group_api.trigger_members_refresh(admin_context,
- group_ids)
-
- # NOTE(hanlind): This method can be removed in version 2.0 of the RPC API
- def get_instance_uuids_by_ip_filter(self, context, filters):
- fixed_ip_filter = filters.get('fixed_ip')
- ip_filter = re.compile(str(filters.get('ip')))
- ipv6_filter = re.compile(str(filters.get('ip6')))
- LOG.debug('Get instance uuids by IP filters. Fixed IP filter: %s. '
- 'IP filter: %s. IPv6 filter: %s', fixed_ip_filter,
- str(filters.get('ip')), str(filters.get('ip6')))
-
- # NOTE(jkoelker) Should probably figure out a better way to do
- # this. But for now it "works", this could suck on
- # large installs.
-
- vifs = objects.VirtualInterfaceList.get_all(context)
- results = []
-
- for vif in vifs:
- if vif.instance_uuid is None:
- continue
-
- network = self._get_network_by_id(context, vif.network_id)
- fixed_ipv6 = None
- if network['cidr_v6'] is not None:
- fixed_ipv6 = ipv6.to_global(network['cidr_v6'],
- vif.address,
- context.project_id)
-
- if fixed_ipv6 and ipv6_filter.match(fixed_ipv6):
- results.append({'instance_uuid': vif.instance_uuid,
- 'ip': fixed_ipv6})
-
- fixed_ips = objects.FixedIPList.get_by_virtual_interface_id(
- context, vif.id)
- for fixed_ip in fixed_ips:
- if not fixed_ip or not fixed_ip.address:
- continue
- if str(fixed_ip.address) == fixed_ip_filter:
- results.append({'instance_uuid': vif.instance_uuid,
- 'ip': fixed_ip.address})
- continue
- if ip_filter.match(str(fixed_ip.address)):
- results.append({'instance_uuid': vif.instance_uuid,
- 'ip': fixed_ip.address})
- continue
- for floating_ip in fixed_ip.floating_ips:
- if not floating_ip or not floating_ip.address:
- continue
- if ip_filter.match(str(floating_ip.address)):
- results.append({'instance_uuid': vif.instance_uuid,
- 'ip': floating_ip.address})
- continue
-
- return results
-
- def _get_networks_for_instance(self, context, instance_id, project_id,
- requested_networks=None):
- """Determine & return which networks an instance should connect to."""
- # TODO(tr3buchet) maybe this needs to be updated in the future if
- # there is a better way to determine which networks
- # a non-vlan instance should connect to
- if requested_networks is not None and len(requested_networks) != 0:
- network_uuids = [request.network_id
- for request in requested_networks]
- networks = self._get_networks_by_uuids(context, network_uuids)
- else:
- try:
- networks = objects.NetworkList.get_all(context)
- except exception.NoNetworksFound:
- return []
- # return only networks which are not vlan networks
- return [network for network in networks if not network.vlan]
-
- def allocate_for_instance(self, context, **kwargs):
- """Handles allocating the various network resources for an instance.
-
- rpc.called by network_api
- """
- instance_uuid = kwargs['instance_id']
- if not uuidutils.is_uuid_like(instance_uuid):
- instance_uuid = kwargs.get('instance_uuid')
- host = kwargs['host']
- project_id = kwargs['project_id']
- rxtx_factor = kwargs['rxtx_factor']
- requested_networks = kwargs.get('requested_networks')
- if (requested_networks and
- not isinstance(requested_networks,
- objects.NetworkRequestList)):
- requested_networks = objects.NetworkRequestList.from_tuples(
- requested_networks)
- vpn = kwargs['vpn']
- macs = kwargs['macs']
- admin_context = context.elevated()
- networks = self._get_networks_for_instance(context,
- instance_uuid, project_id,
- requested_networks=requested_networks)
- networks_list = [self._get_network_dict(network)
- for network in networks]
- LOG.debug('Networks retrieved for instance: |%s|',
- networks_list, instance_uuid=instance_uuid)
-
- try:
- self._allocate_mac_addresses(admin_context, instance_uuid,
- networks, macs, requested_networks)
- except Exception:
- with excutils.save_and_reraise_exception():
- # If we fail to allocate any one mac address, clean up all
- # allocated VIFs
- objects.VirtualInterface.delete_by_instance_uuid(
- context, instance_uuid)
-
- self._allocate_fixed_ips(admin_context, instance_uuid,
- host, networks, vpn=vpn,
- requested_networks=requested_networks)
-
- if CONF.update_dns_entries:
- network_ids = [network['id'] for network in networks]
- self.network_rpcapi.update_dns(context, network_ids)
-
- net_info = self.get_instance_nw_info(admin_context, instance_uuid,
- rxtx_factor, host)
- LOG.info("Allocated network: '%s' for instance", net_info,
- instance_uuid=instance_uuid)
- return net_info
-
- def deallocate_for_instance(self, context, **kwargs):
- """Handles deallocating various network resources for an instance.
-
- rpc.called by network_api
- kwargs can contain fixed_ips to circumvent another db lookup
- """
- # NOTE(francois.charlier): in some cases the instance might be
- # deleted before the IPs are released, so we need to get deleted
- # instances too
- read_deleted_context = context.elevated(read_deleted='yes')
- if 'instance' in kwargs:
- instance = kwargs['instance']
- instance_uuid = instance.uuid
- host = instance.host
- else:
- instance_id = kwargs['instance_id']
- if uuidutils.is_uuid_like(instance_id):
- instance = objects.Instance.get_by_uuid(
- read_deleted_context, instance_id)
- else:
- instance = objects.Instance.get_by_id(
- read_deleted_context, instance_id)
- # NOTE(russellb) in case instance_id was an ID and not UUID
- instance_uuid = instance.uuid
- host = kwargs.get('host')
-
- try:
- requested_networks = kwargs.get('requested_networks')
- if requested_networks:
- # NOTE(obondarev): Temporary and transitional
- if isinstance(requested_networks, objects.NetworkRequestList):
- requested_networks = requested_networks.as_tuples()
-
- network_ids = set([net_id for (net_id, ip)
- in requested_networks])
- fixed_ips = [ip for (net_id, ip) in requested_networks if ip]
- else:
- fixed_ip_list = objects.FixedIPList.get_by_instance_uuid(
- read_deleted_context, instance_uuid)
- network_ids = set([str(fixed_ip.network_id) for fixed_ip
- in fixed_ip_list])
- fixed_ips = [str(ip.address) for ip in fixed_ip_list]
- except exception.FixedIpNotFoundForInstance:
- network_ids = set([])
- fixed_ips = []
- LOG.debug("Network deallocation for instance",
- instance_uuid=instance_uuid)
- # deallocate fixed ips
- for fixed_ip in fixed_ips:
- self.deallocate_fixed_ip(context, fixed_ip, host=host,
- instance=instance)
-
- if CONF.update_dns_entries:
- self.network_rpcapi.update_dns(context, list(network_ids))
-
- # deallocate vifs (mac addresses)
- objects.VirtualInterface.delete_by_instance_uuid(
- read_deleted_context, instance_uuid)
- LOG.info("Network deallocated for instance (fixed IPs: '%s')",
- fixed_ips, instance_uuid=instance_uuid)
-
- @messaging.expected_exceptions(exception.InstanceNotFound)
- def get_instance_nw_info(self, context, instance_id, rxtx_factor,
- host, instance_uuid=None, **kwargs):
- """Creates network info list for instance.
-
- called by allocate_for_instance and network_api
- context needs to be elevated
- :returns: network info list [(network,info),(network,info)...]
- where network = dict containing pertinent data from a network db object
- and info = dict containing pertinent networking data
- """
- if not uuidutils.is_uuid_like(instance_id):
- instance_id = instance_uuid
- instance_uuid = instance_id
- LOG.debug('Get instance network info', instance_uuid=instance_uuid)
-
- try:
- fixed_ips = objects.FixedIPList.get_by_instance_uuid(
- context, instance_uuid)
- except exception.FixedIpNotFoundForInstance:
- fixed_ips = []
-
- LOG.debug('Found %d fixed IPs associated to the instance in the '
- 'database.',
- len(fixed_ips), instance_uuid=instance_uuid)
-
- nw_info = network_model.NetworkInfo()
-
- vifs = collections.OrderedDict()
- for fixed_ip in fixed_ips:
- vif = fixed_ip.virtual_interface
- if not vif:
- LOG.warning('No VirtualInterface for FixedIP: %s',
- str(fixed_ip.address), instance_uuid=instance_uuid)
- continue
-
- if not fixed_ip.network:
- LOG.warning('No Network for FixedIP: %s',
- str(fixed_ip.address), instance_uuid=instance_uuid)
- continue
-
- if vif.uuid in vifs:
- current = vifs[vif.uuid]
- else:
- current = {
- 'id': vif.uuid,
- 'type': network_model.VIF_TYPE_BRIDGE,
- 'address': vif.address,
- }
- vifs[vif.uuid] = current
-
- net_dict = self._get_network_dict(fixed_ip.network)
- network = network_model.Network(**net_dict)
- subnets = self._get_subnets_from_network(context,
- fixed_ip.network,
- host)
- network['subnets'] = subnets
- current['network'] = network
- try:
- current['rxtx_cap'] = (fixed_ip.network['rxtx_base'] *
- rxtx_factor)
- except (TypeError, KeyError):
- pass
- if fixed_ip.network.cidr_v6 and vif.address:
- # NOTE(vish): I strongly suspect the v6 subnet is not used
- # anywhere, but support it just in case
- # add the v6 address to the v6 subnet
- address = ipv6.to_global(fixed_ip.network.cidr_v6,
- vif.address,
- fixed_ip.network.project_id)
- model_ip = network_model.FixedIP(address=address)
- current['network']['subnets'][1]['ips'].append(model_ip)
-
- # add the v4 address to the v4 subnet
- model_ip = network_model.FixedIP(address=str(fixed_ip.address))
- for ip in fixed_ip.floating_ips:
- floating_ip = network_model.IP(address=str(ip['address']),
- type='floating')
- model_ip.add_floating_ip(floating_ip)
- current['network']['subnets'][0]['ips'].append(model_ip)
-
- for vif in vifs.values():
- nw_info.append(network_model.VIF(**vif))
-
- LOG.debug('Built network info: |%s|', nw_info,
- instance_uuid=instance_uuid)
- return nw_info
-
- @staticmethod
- def _get_network_dict(network):
- """Returns the dict representing necessary and meta network fields."""
- # get generic network fields
- network_dict = {'id': network['uuid'],
- 'bridge': network['bridge'],
- 'label': network['label'],
- 'tenant_id': network['project_id']}
-
- # get extra information
- if network.get('injected'):
- network_dict['injected'] = network['injected']
-
- return network_dict
-
- @staticmethod
- def _extract_subnets(network):
- """Returns information about the IPv4 and IPv6 subnets
- associated with a Neutron Network UUID.
- """
- subnet_v4 = {
- 'network_id': network.uuid,
- 'cidr': network.cidr,
- 'gateway': network.gateway,
- 'dhcp_server': getattr(network, 'dhcp_server'),
- 'broadcast': network.broadcast,
- 'netmask': network.netmask,
- 'version': 4,
- 'dns1': network.dns1,
- 'dns2': network.dns2}
- # TODO(tr3buchet): I'm noticing we've assumed here that all dns is v4.
- # this is probably bad as there is no way to add v6
- # dns to nova
- subnet_v6 = {
- 'network_id': network.uuid,
- 'cidr': network.cidr_v6,
- 'gateway': network.gateway_v6,
- 'dhcp_server': None,
- 'broadcast': None,
- 'netmask': network.netmask_v6,
- 'version': 6,
- 'dns1': None,
- 'dns2': None}
-
- def ips_to_strs(net):
- for key, value in net.items():
- if isinstance(value, netaddr.ip.BaseIP):
- net[key] = str(value)
- return net
-
- return [ips_to_strs(subnet_v4), ips_to_strs(subnet_v6)]
-
- def _get_subnets_from_network(self, context, network, instance_host=None):
- """Returns the 1 or 2 possible subnets for a nova network."""
- extracted_subnets = self._extract_subnets(network)
- subnets = []
- for subnet in extracted_subnets:
- subnet_dict = {'cidr': subnet['cidr'],
- 'gateway': network_model.IP(
- address=subnet['gateway'],
- type='gateway')}
- # deal with dhcp
- if self.DHCP:
- if network.get('multi_host'):
- dhcp_server = self._get_dhcp_ip(context, network,
- instance_host)
- else:
- dhcp_server = self._get_dhcp_ip(context, subnet)
- subnet_dict['dhcp_server'] = dhcp_server
-
- subnet_object = network_model.Subnet(**subnet_dict)
-
- # add dns info
- for k in ['dns1', 'dns2']:
- if subnet.get(k):
- subnet_object.add_dns(
- network_model.IP(address=subnet[k], type='dns'))
-
- subnet_object['ips'] = []
-
- subnets.append(subnet_object)
-
- return subnets
-
- def _allocate_mac_addresses(self, context, instance_uuid, networks, macs,
- requested_networks):
- """Generates mac addresses and creates vif rows in db for them."""
- # make a copy we can mutate
- if macs is not None:
- available_macs = set(macs)
-
- if requested_networks:
- tags_by_network = {
- network.network_id: network.tag if 'tag' in network else None
- for network in requested_networks}
- else:
- tags_by_network = {}
-
- for network in networks:
- if macs is None:
- self._add_virtual_interface(
- context, instance_uuid,
- network['id'],
- tag=tags_by_network.get(network['uuid']))
- else:
- try:
- mac = available_macs.pop()
- except KeyError:
- raise exception.VirtualInterfaceCreateException()
- self._add_virtual_interface(
- context, instance_uuid,
- network['id'], mac,
- tag=tags_by_network.get(network['uuid']))
-
- def _add_virtual_interface(self, context, instance_uuid, network_id,
- mac=None, tag=None):
- attempts = 1 if mac else CONF.create_unique_mac_address_attempts
- for i in range(attempts):
- try:
- vif = objects.VirtualInterface(context)
- vif.address = mac or utils.generate_mac_address()
- vif.instance_uuid = instance_uuid
- vif.network_id = network_id
- vif.uuid = uuidutils.generate_uuid()
- vif.tag = tag
- vif.create()
- return vif
- except exception.VirtualInterfaceCreateException:
- # Try again up to max number of attempts
- pass
-
- raise exception.VirtualInterfaceMacAddressException()
-
- def add_fixed_ip_to_instance(self, context, instance_id, host, network_id,
- rxtx_factor=None):
- """Adds a fixed IP to an instance from specified network."""
- if uuidutils.is_uuid_like(network_id):
- network = self.get_network(context, network_id)
- else:
- network = self._get_network_by_id(context, network_id)
- LOG.debug('Add fixed IP on network %s', network['uuid'],
- instance_uuid=instance_id)
- self._allocate_fixed_ips(context, instance_id, host, [network])
- return self.get_instance_nw_info(context, instance_id, rxtx_factor,
- host)
-
- # NOTE(russellb) This method can be removed in 2.0 of this API. It is
- # deprecated in favor of the method in the base API.
- def get_backdoor_port(self, context):
- """Return backdoor port for eventlet_backdoor."""
- return self.backdoor_port
-
- def remove_fixed_ip_from_instance(self, context, instance_id, host,
- address, rxtx_factor=None):
- """Removes a fixed IP from an instance from specified network."""
- LOG.debug('Remove fixed IP %s', address, instance_uuid=instance_id)
- fixed_ips = objects.FixedIPList.get_by_instance_uuid(context,
- instance_id)
- for fixed_ip in fixed_ips:
- if str(fixed_ip.address) == address:
- self.deallocate_fixed_ip(context, address, host)
- # NOTE(vish): this probably isn't a dhcp ip so just
- # deallocate it now. In the extremely rare
- # case that this is a race condition, we
- # will just get a warn in lease or release.
- if not fixed_ip.leased:
- fixed_ip.disassociate()
- return self.get_instance_nw_info(context, instance_id,
- rxtx_factor, host)
- raise exception.FixedIpNotFoundForSpecificInstance(
- instance_uuid=instance_id, ip=address)
-
- def _validate_instance_zone_for_dns_domain(self, context, instance):
- if not self.instance_dns_domain:
- return True
- instance_domain = self.instance_dns_domain
-
- domainref = objects.DNSDomain.get_by_domain(context, instance_domain)
- if domainref is None:
- LOG.warning('instance-dns-zone not found |%s|.',
- instance_domain, instance=instance)
- return True
- dns_zone = domainref.availability_zone
-
- instance_zone = instance.get('availability_zone')
- if dns_zone and (dns_zone != instance_zone):
- LOG.warning('instance-dns-zone is |%(domain)s|, '
- 'which is in availability zone |%(zone)s|. '
- 'Instance is in zone |%(zone2)s|. '
- 'No DNS record will be created.',
- {'domain': instance_domain,
- 'zone': dns_zone,
- 'zone2': instance_zone},
- instance=instance)
- return False
- else:
- return True
-
- def allocate_fixed_ip(self, context, instance_id, network, **kwargs):
- """Gets a fixed IP from the pool."""
- # TODO(vish): when this is called by compute, we can associate compute
- # with a network, or a cluster of computes with a network
- # and use that network here with a method like
- # network_get_by_compute_host
- address = None
-
- # NOTE(vish) This db query could be removed if we pass az and name
- # (or the whole instance object).
- instance = objects.Instance.get_by_uuid(context, instance_id)
- LOG.debug('Allocate fixed IP on network %s', network['uuid'],
- instance=instance)
-
- # A list of cleanup functions to call on error
- cleanup = []
-
- # Check the quota; can't put this in the API because we get
- # called into from other places
- quotas = self.quotas_cls(context=context)
- quota_project, quota_user = quotas_obj.ids_from_instance(context,
- instance)
- try:
- quotas.check_deltas(context, {'fixed_ips': 1}, quota_project)
- except exception.OverQuota as exc:
- count = exc.kwargs['usages']['fixed_ips']
- LOG.warning("Quota exceeded for project %(pid)s, tried to "
- "allocate fixed IP. %(used)s of %(allowed)s are "
- "in use or are already reserved.",
- {'pid': quota_project, 'used': count,
- 'allowed': exc.kwargs['quotas']['fixed_ips']},
- instance_uuid=instance_id)
- raise exception.FixedIpLimitExceeded()
-
- try:
- if network['cidr']:
-
- # NOTE(mriedem): allocate the vif before associating the
- # instance to reduce a race window where a previous instance
- # was associated with the fixed IP and has released it, because
- # release_fixed_ip will disassociate if allocated is False.
- vif = objects.VirtualInterface.get_by_instance_and_network(
- context, instance_id, network['id'])
- if vif is None:
- LOG.debug('vif for network %(network)s is used up, '
- 'trying to create new vif',
- {'network': network['id']}, instance=instance)
- vif = self._add_virtual_interface(context,
- instance_id, network['id'])
-
- address = kwargs.get('address', None)
- if address:
- LOG.debug('Associating instance with specified fixed IP '
- '%(address)s in network %(network)s on subnet '
- '%(cidr)s.',
- {'address': address, 'network': network['id'],
- 'cidr': network['cidr']},
- instance=instance)
- fip = objects.FixedIP.associate(
- context, str(address), instance_id, network['id'],
- vif_id=vif.id)
- else:
- LOG.debug('Associating instance with fixed IP from pool '
- 'in network %(network)s on subnet %(cidr)s.',
- {'network': network['id'],
- 'cidr': network['cidr']},
- instance=instance)
- fip = objects.FixedIP.associate_pool(
- context.elevated(), network['id'], instance_id,
- vif_id=vif.id)
- LOG.debug('Associated instance with fixed IP: %s', fip,
- instance=instance)
- address = str(fip.address)
-
- cleanup.append(fip.disassociate)
-
- # NOTE(melwitt): We recheck the quota after creating the object
- # to prevent users from allocating more resources than their
- # allowed quota in the event of a race. This is configurable
- # because it can be expensive if strict quota limits are not
- # required in a deployment.
- if CONF.quota.recheck_quota:
- try:
- quotas.check_deltas(context, {'fixed_ips': 0},
- quota_project)
- except exception.OverQuota as exc:
- # Cleanup of the fixed IP allocation occurs in the
- # outermost catch-all except block.
- count = exc.kwargs['usages']['fixed_ips']
- allowed = exc.kwargs['quotas']['fixed_ips']
- LOG.warning("Quota exceeded for project %(pid)s, "
- "tried to allocate fixed IP. %(used)s "
- "of %(allowed)s are in use or are "
- "already reserved.",
- {'pid': quota_project, 'used': count,
- 'allowed': allowed},
- instance_uuid=instance_id)
- raise exception.FixedIpLimitExceeded()
-
- LOG.debug('Refreshing security group members for instance.',
- instance=instance)
- self._do_trigger_security_group_members_refresh_for_instance(
- instance_id)
- cleanup.append(functools.partial(
- self._do_trigger_security_group_members_refresh_for_instance, # noqa
- instance_id))
-
- name = instance.display_name
-
- if self._validate_instance_zone_for_dns_domain(context, instance):
- self.instance_dns_manager.create_entry(
- name, str(fip.address), "A", self.instance_dns_domain)
- cleanup.append(functools.partial(
- self.instance_dns_manager.delete_entry,
- name, self.instance_dns_domain))
-
- self.instance_dns_manager.create_entry(
- instance_id, str(fip.address), "A",
- self.instance_dns_domain)
- cleanup.append(functools.partial(
- self.instance_dns_manager.delete_entry,
- instance_id, self.instance_dns_domain))
-
- LOG.debug('Setting up network %(network)s on host %(host)s.',
- {'network': network['id'], 'host': self.host},
- instance=instance)
- self._setup_network_on_host(context, network)
- cleanup.append(functools.partial(
- self._teardown_network_on_host,
- context, network))
-
- if address is None:
- # TODO(mriedem): should _setup_network_on_host return the addr?
- LOG.debug('Fixed IP is setup on network %s but not returning '
- 'the specific IP from the base network manager.',
- network['uuid'], instance=instance)
- else:
- LOG.debug('Allocated fixed IP %s on network %s', address,
- network['uuid'], instance=instance)
- return address
-
- except Exception:
- with excutils.save_and_reraise_exception():
- for f in cleanup:
- try:
- f()
- except Exception:
- LOG.warning('Error cleaning up fixed IP '
- 'allocation. Manual cleanup may '
- 'be required.', exc_info=True)
-
- def deallocate_fixed_ip(self, context, address, host=None, teardown=True,
- instance=None):
- """Returns a fixed IP to the pool."""
- fixed_ip_ref = objects.FixedIP.get_by_address(
- context, address, expected_attrs=['network'])
- instance_uuid = fixed_ip_ref.instance_uuid
- vif_id = fixed_ip_ref.virtual_interface_id
- LOG.debug('Deallocate fixed IP %s', address,
- instance_uuid=instance_uuid)
-
- if not instance:
- # NOTE(vish) This db query could be removed if we pass az and name
- # (or the whole instance object).
- # NOTE(danms) We can't use fixed_ip_ref.instance because
- # instance may be deleted and the relationship
- # doesn't extend to deleted instances
- instance = objects.Instance.get_by_uuid(
- context.elevated(read_deleted='yes'), instance_uuid)
-
- self._do_trigger_security_group_members_refresh_for_instance(
- instance_uuid)
-
- if self._validate_instance_zone_for_dns_domain(context, instance):
- for n in self.instance_dns_manager.get_entries_by_address(
- address, self.instance_dns_domain):
- self.instance_dns_manager.delete_entry(n,
- self.instance_dns_domain)
-
- fixed_ip_ref.allocated = False
- fixed_ip_ref.save()
-
- if teardown:
- network = fixed_ip_ref.network
-
- if CONF.force_dhcp_release:
- dev = self.driver.get_dev(network)
- # NOTE(vish): The below errors should never happen, but
- # there may be a race condition that is causing
- # them per
- # https://code.launchpad.net/bugs/968457,
- # so we log a message to help track down
- # the possible race.
- if not vif_id:
- LOG.info("Unable to release %s because vif doesn't exist",
- address)
- return
-
- vif = objects.VirtualInterface.get_by_id(context, vif_id)
-
- if not vif:
- LOG.info("Unable to release %s because vif "
- "object doesn't exist", address)
- return
-
- # NOTE(cfb): Call teardown before release_dhcp to ensure
- # that the IP can't be re-leased after a release
- # packet is sent.
- self._teardown_network_on_host(context, network)
- # NOTE(vish): This forces a packet so that the
- # release_fixed_ip callback will
- # get called by nova-dhcpbridge.
- try:
- self.network_rpcapi.release_dhcp(context,
- instance.launched_on,
- dev, address,
- vif.address)
- except exception.RPCPinnedToOldVersion:
- # Fall back on previous behaviour of calling
- # release_dhcp on the local driver
- self.driver.release_dhcp(dev, address, vif.address)
- except exception.NetworkDhcpReleaseFailed:
- LOG.error("Error releasing DHCP for IP %(address)s"
- " with MAC %(mac_address)s",
- {'address': address,
- 'mac_address': vif.address},
- instance=instance)
-
- # NOTE(yufang521247): This is probably a failed dhcp fixed
- # ip. DHCPRELEASE packet sent to dnsmasq would not trigger
- # dhcp-bridge to run. Thus it is better to disassociate
- # such fixed ip here.
- fixed_ip_ref = objects.FixedIP.get_by_address(
- context, address)
- if (instance_uuid == fixed_ip_ref.instance_uuid and
- not fixed_ip_ref.leased):
- LOG.debug('Explicitly disassociating fixed IP %s from '
- 'instance.', address,
- instance_uuid=instance_uuid)
- fixed_ip_ref.disassociate()
- else:
- # We can't try to free the IP address so just call teardown
- self._teardown_network_on_host(context, network)
-
- def release_dhcp(self, context, dev, address, vif_address):
- self.driver.release_dhcp(dev, address, vif_address)
-
- def lease_fixed_ip(self, context, address):
- """Called by dhcp-bridge when IP is leased."""
- LOG.debug('Leased IP |%s|', address)
- fixed_ip = objects.FixedIP.get_by_address(context, address)
-
- if fixed_ip.instance_uuid is None:
- LOG.warning('IP %s leased that is not associated', fixed_ip)
- return
- fixed_ip.leased = True
- fixed_ip.save()
- if not fixed_ip.allocated:
- LOG.warning('IP |%s| leased that isn\'t allocated', fixed_ip,
- instance_uuid=fixed_ip.instance_uuid)
-
- def release_fixed_ip(self, context, address, mac=None):
- """Called by dhcp-bridge when IP is released."""
- LOG.debug('Released IP |%s|', address)
- fixed_ip = objects.FixedIP.get_by_address(context, address)
-
- if fixed_ip.instance_uuid is None:
- LOG.warning('IP %s released that is not associated', fixed_ip)
- return
- if not fixed_ip.leased:
- LOG.warning('IP %s released that was not leased', fixed_ip,
- instance_uuid=fixed_ip.instance_uuid)
- else:
- fixed_ip.leased = False
- fixed_ip.save()
- if not fixed_ip.allocated:
- # NOTE(mriedem): Sometimes allocate_fixed_ip will associate the
- # fixed IP to a new instance while an old associated instance is
- # being deallocated. So we check to see if the mac is for the VIF
- # that is associated to the instance that is currently associated
- # with the fixed IP because if it's not, we hit this race and
- # should ignore the request so we don't disassociate the fixed IP
- # from the wrong instance.
- if mac:
- LOG.debug('Checking to see if virtual interface with MAC '
- '%(mac)s is still associated to instance.',
- {'mac': mac}, instance_uuid=fixed_ip.instance_uuid)
- vif = objects.VirtualInterface.get_by_address(context, mac)
- if vif:
- LOG.debug('Found VIF: %s', vif,
- instance_uuid=fixed_ip.instance_uuid)
- if vif.instance_uuid != fixed_ip.instance_uuid:
- LOG.info("Ignoring request to release fixed IP "
- "%(address)s with MAC %(mac)s since it "
- "is now associated with a new instance "
- "that is in the process of allocating "
- "it's network.",
- {'address': address, 'mac': mac},
- instance_uuid=fixed_ip.instance_uuid)
- return
- else:
- LOG.debug('No VIF was found for MAC: %s', mac,
- instance_uuid=fixed_ip.instance_uuid)
-
- LOG.debug('Disassociating fixed IP %s from instance.', address,
- instance_uuid=fixed_ip.instance_uuid)
- fixed_ip.disassociate()
-
- @staticmethod
- def _convert_int_args(kwargs):
- int_args = ("network_size", "num_networks",
- "vlan_start", "vpn_start")
- for key in int_args:
- try:
- value = kwargs.get(key)
- if value is None:
- continue
- kwargs[key] = int(value)
- except ValueError:
- raise exception.InvalidIntValue(key=key)
-
- def create_networks(self, context,
- label, cidr=None, multi_host=None, num_networks=None,
- network_size=None, cidr_v6=None,
- gateway=None, gateway_v6=None, bridge=None,
- bridge_interface=None, dns1=None, dns2=None,
- fixed_cidr=None, allowed_start=None,
- allowed_end=None, **kwargs):
- if 'dhcp_server' not in kwargs:
- kwargs['dhcp_server'] = gateway
- if 'enable_dhcp' not in kwargs:
- kwargs['enable_dhcp'] = True
- if 'share_address' not in kwargs:
- kwargs['share_address'] = CONF.share_dhcp_address
- kwargs.update({
- 'label': label,
- 'cidr': cidr,
- 'multi_host': multi_host,
- 'num_networks': num_networks,
- 'network_size': network_size,
- 'cidr_v6': cidr_v6,
- 'gateway': gateway,
- 'gateway_v6': gateway_v6,
- 'bridge': bridge,
- 'bridge_interface': bridge_interface,
- 'dns1': dns1,
- 'dns2': dns2,
- 'fixed_cidr': fixed_cidr,
- 'allowed_start': allowed_start,
- 'allowed_end': allowed_end,
- })
- self._convert_int_args(kwargs)
-
- kwargs["bridge"] = kwargs["bridge"] or CONF.flat_network_bridge
- kwargs["bridge_interface"] = (kwargs["bridge_interface"] or
- CONF.flat_interface)
-
- for fld in self.required_create_args:
- if not kwargs[fld]:
- raise exception.NetworkNotCreated(req=fld)
-
- if kwargs["cidr_v6"]:
- # NOTE(vish): just for validation
- try:
- netaddr.IPNetwork(kwargs["cidr_v6"])
- except netaddr.AddrFormatError:
- raise exception.InvalidCidr(cidr=kwargs["cidr_v6"])
-
- if kwargs["cidr"]:
- try:
- fixnet = netaddr.IPNetwork(kwargs["cidr"])
- except netaddr.AddrFormatError:
- raise exception.InvalidCidr(cidr=kwargs["cidr"])
-
- kwargs["num_networks"] = kwargs["num_networks"] or CONF.num_networks
- if not kwargs["network_size"]:
- if kwargs["cidr"]:
- each_subnet_size = fixnet.size / kwargs["num_networks"]
- if each_subnet_size > CONF.network_size:
- subnet = 32 - int(math.log(CONF.network_size, 2))
- LOG.warning(
- 'Subnet(s) too large, defaulting to /%s.'
- ' To override, specify network_size flag.', subnet)
- kwargs["network_size"] = CONF.network_size
- else:
- kwargs["network_size"] = fixnet.size
- else:
- kwargs["network_size"] = CONF.network_size
-
- kwargs["multi_host"] = (
- CONF.multi_host
- if kwargs["multi_host"] is None
- else strutils.bool_from_string(kwargs["multi_host"]))
-
- kwargs["vlan_start"] = kwargs.get("vlan_start") or CONF.vlan_start
- kwargs["vpn_start"] = kwargs.get("vpn_start") or CONF.vpn_start
- kwargs["dns1"] = kwargs["dns1"] or CONF.flat_network_dns
-
- if kwargs["fixed_cidr"]:
- try:
- kwargs["fixed_cidr"] = netaddr.IPNetwork(kwargs["fixed_cidr"])
- except netaddr.AddrFormatError:
- raise exception.InvalidCidr(cidr=kwargs["fixed_cidr"])
-
- # Subnet of fixed IPs must fall within fixed range
- if kwargs["fixed_cidr"] not in fixnet:
- raise exception.AddressOutOfRange(
- address=kwargs["fixed_cidr"].network, cidr=fixnet)
-
- LOG.debug('Create network: |%s|', kwargs)
- return self._do_create_networks(context, **kwargs)
-
- @staticmethod
- def _index_of(subnet, ip):
- try:
- start = netaddr.IPAddress(ip)
- except netaddr.AddrFormatError:
- raise exception.InvalidAddress(address=ip)
- index = start.value - subnet.value
- if index < 0 or index >= subnet.size:
- raise exception.AddressOutOfRange(address=ip, cidr=str(subnet))
- return index
-
- def _validate_cidr(self, context, nets, subnets_v4, fixed_net_v4):
- used_subnets = [net.cidr for net in nets]
-
- def find_next(subnet):
- next_subnet = subnet.next()
- while next_subnet in subnets_v4:
- next_subnet = next_subnet.next()
- if next_subnet in fixed_net_v4:
- return next_subnet
-
- for subnet in list(subnets_v4):
- if subnet in used_subnets:
- next_subnet = find_next(subnet)
- if next_subnet:
- subnets_v4.remove(subnet)
- subnets_v4.append(next_subnet)
- subnet = next_subnet
- else:
- raise exception.CidrConflict(cidr=subnet,
- other=subnet)
- for used_subnet in used_subnets:
- if subnet in used_subnet:
- raise exception.CidrConflict(cidr=subnet,
- other=used_subnet)
- if used_subnet in subnet:
- next_subnet = find_next(subnet)
- if next_subnet:
- subnets_v4.remove(subnet)
- subnets_v4.append(next_subnet)
- subnet = next_subnet
- else:
- raise exception.CidrConflict(cidr=subnet,
- other=used_subnet)
-
- def _do_create_networks(self, context,
- label, cidr, multi_host, num_networks,
- network_size, cidr_v6, gateway, gateway_v6, bridge,
- bridge_interface, dns1=None, dns2=None,
- fixed_cidr=None, mtu=None, dhcp_server=None,
- enable_dhcp=None, share_address=None,
- allowed_start=None, allowed_end=None, **kwargs):
- """Create networks based on parameters."""
- # NOTE(jkoelker): these are dummy values to make sure iter works
- # TODO(tr3buchet): disallow carving up networks
- fixed_net_v4 = netaddr.IPNetwork('0/32')
- fixed_net_v6 = netaddr.IPNetwork('::0/128')
- subnets_v4 = []
- subnets_v6 = []
-
- if kwargs.get('ipam'):
- if cidr_v6:
- subnets_v6 = [netaddr.IPNetwork(cidr_v6)]
- if cidr:
- subnets_v4 = [netaddr.IPNetwork(cidr)]
- else:
- subnet_bits = int(math.ceil(math.log(network_size, 2)))
- if cidr_v6:
- fixed_net_v6 = netaddr.IPNetwork(cidr_v6)
- prefixlen_v6 = 128 - subnet_bits
- # smallest subnet in IPv6 ethernet network is /64
- if prefixlen_v6 > 64:
- prefixlen_v6 = 64
- subnets_v6 = fixed_net_v6.subnet(prefixlen_v6,
- count=num_networks)
- if cidr:
- fixed_net_v4 = netaddr.IPNetwork(cidr)
- prefixlen_v4 = 32 - subnet_bits
- subnets_v4 = list(fixed_net_v4.subnet(prefixlen_v4,
- count=num_networks))
-
- if cidr:
- # NOTE(jkoelker): This replaces the _validate_cidrs call and
- # prevents looping multiple times
- try:
- nets = objects.NetworkList.get_all(context)
- except exception.NoNetworksFound:
- nets = []
- num_used_nets = len(nets)
- self._validate_cidr(context, nets, subnets_v4, fixed_net_v4)
-
- networks = objects.NetworkList(context=context, objects=[])
- subnets = six.moves.zip_longest(subnets_v4, subnets_v6)
- for index, (subnet_v4, subnet_v6) in enumerate(subnets):
- net = objects.Network(context=context)
- uuid = kwargs.get('uuid')
- if uuid:
- net.uuid = uuid
- net.bridge = bridge
- net.bridge_interface = bridge_interface
- net.multi_host = multi_host
-
- net.dns1 = dns1
- net.dns2 = dns2
- net.mtu = mtu
- net.enable_dhcp = enable_dhcp
- net.share_address = share_address
-
- net.project_id = kwargs.get('project_id')
-
- if num_networks > 1:
- net.label = '%s_%d' % (label, index)
- else:
- net.label = label
-
- bottom_reserved = self._bottom_reserved_ips
- top_reserved = self._top_reserved_ips
- extra_reserved = []
- if cidr and subnet_v4:
- current = subnet_v4[1]
- if allowed_start:
- val = self._index_of(subnet_v4, allowed_start)
- current = netaddr.IPAddress(allowed_start)
- bottom_reserved = val
- if allowed_end:
- val = self._index_of(subnet_v4, allowed_end)
- top_reserved = subnet_v4.size - 1 - val
- net.cidr = str(subnet_v4)
- net.netmask = str(subnet_v4.netmask)
- net.broadcast = str(subnet_v4.broadcast)
- if gateway:
- net.gateway = gateway
- else:
- net.gateway = current
- current += 1
- net.dhcp_server = dhcp_server or net.gateway
- net.dhcp_start = current
- current += 1
- if net.dhcp_start == net.dhcp_server:
- net.dhcp_start = current
- extra_reserved.append(str(net.dhcp_server))
- extra_reserved.append(str(net.gateway))
-
- if cidr_v6 and subnet_v6:
- net.cidr_v6 = str(subnet_v6)
- if gateway_v6:
- # use a pre-defined gateway if one is provided
- net.gateway_v6 = str(gateway_v6)
- else:
- net.gateway_v6 = str(subnet_v6[1])
-
- net.netmask_v6 = str(subnet_v6.netmask)
-
- if CONF.network_manager == 'nova.network.manager.VlanManager':
- vlan = kwargs.get('vlan', None)
- if not vlan:
- index_vlan = index + num_used_nets
- vlan = kwargs['vlan_start'] + index_vlan
- used_vlans = [x.vlan for x in nets]
- if vlan in used_vlans:
- # That vlan is used, try to get another one
- used_vlans.sort()
- vlan = used_vlans[-1] + 1
-
- net.vpn_private_address = net.dhcp_start
- extra_reserved.append(str(net.vpn_private_address))
- net.dhcp_start = net.dhcp_start + 1
- net.vlan = vlan
- net.bridge = 'br%s' % vlan
-
- # NOTE(vish): This makes ports unique across the cloud, a more
- # robust solution would be to make them uniq per ip
- index_vpn = index + num_used_nets
- net.vpn_public_port = kwargs['vpn_start'] + index_vpn
-
- net.create()
- networks.objects.append(net)
-
- if cidr and subnet_v4:
- self._create_fixed_ips(context, net.id, fixed_cidr,
- extra_reserved, bottom_reserved,
- top_reserved)
- # NOTE(danms): Remove this in RPC API v2.0
- return obj_base.obj_to_primitive(networks)
-
- def delete_network(self, context, fixed_range, uuid,
- require_disassociated=True):
-
- # Prefer uuid but we'll also take cidr for backwards compatibility
- elevated = context.elevated()
- if uuid:
- network = objects.Network.get_by_uuid(elevated, uuid)
- elif fixed_range:
- network = objects.Network.get_by_cidr(elevated, fixed_range)
- LOG.debug('Delete network %s', network['uuid'])
-
- if require_disassociated and network.project_id is not None:
- raise exception.NetworkHasProject(project_id=network.project_id)
- network.destroy()
-
- @property
- def _bottom_reserved_ips(self):
- """Number of reserved IPs at the bottom of the range."""
- return 2 # network, gateway
-
- @property
- def _top_reserved_ips(self):
- """Number of reserved IPs at the top of the range."""
- return 1 # broadcast
-
- def _create_fixed_ips(self, context, network_id, fixed_cidr=None,
- extra_reserved=None, bottom_reserved=0,
- top_reserved=0):
- """Create all fixed IPs for network."""
- network = self._get_network_by_id(context, network_id)
- if extra_reserved is None:
- extra_reserved = []
- if not fixed_cidr:
- fixed_cidr = netaddr.IPNetwork(network['cidr'])
- num_ips = len(fixed_cidr)
- ips = []
- for index in range(num_ips):
- address = str(fixed_cidr[index])
- if (index < bottom_reserved or num_ips - index <= top_reserved or
- address in extra_reserved):
- reserved = True
- else:
- reserved = False
-
- ips.append({'network_id': network_id,
- 'address': address,
- 'reserved': reserved})
- objects.FixedIPList.bulk_create(context, ips)
-
- def _allocate_fixed_ips(self, context, instance_id, host, networks,
- **kwargs):
- """Calls allocate_fixed_ip once for each network."""
- raise NotImplementedError()
-
- def setup_networks_on_host(self, context, instance_id, host, instance=None,
- teardown=False):
- """calls setup/teardown on network hosts for an instance."""
- green_threads = []
-
- if teardown:
- call_func = self._teardown_network_on_host
- else:
- call_func = self._setup_network_on_host
- if instance is None:
- instance = objects.Instance.get_by_id(context, instance_id)
- vifs = objects.VirtualInterfaceList.get_by_instance_uuid(
- context, instance.uuid)
- LOG.debug('Setup networks on host', instance=instance)
- for vif in vifs:
- network = objects.Network.get_by_id(context, vif.network_id)
- if not network.multi_host:
- # NOTE (tr3buchet): if using multi_host, host is instance.host
- host = network['host']
- if self.host == host or host is None:
- # at this point i am the correct host, or host doesn't
- # matter -> FlatManager
- call_func(context, network)
- else:
- # i'm not the right host, run call on correct host
- green_threads.append(utils.spawn(
- self.network_rpcapi.rpc_setup_network_on_host, context,
- network.id, teardown, host))
-
- # wait for all of the setups (if any) to finish
- for gt in green_threads:
- gt.wait()
-
- def rpc_setup_network_on_host(self, context, network_id, teardown):
- if teardown:
- call_func = self._teardown_network_on_host
- else:
- call_func = self._setup_network_on_host
-
- # subcall from original setup_networks_on_host
- network = objects.Network.get_by_id(context, network_id)
- call_func(context, network)
-
- def _initialize_network(self, network):
- if network.enable_dhcp:
- is_ext = (network.dhcp_server is not None and
- network.dhcp_server != network.gateway)
- self.l3driver.initialize_network(network.cidr, is_ext)
- self.l3driver.initialize_gateway(network)
-
- def _setup_network_on_host(self, context, network):
- """Sets up network on this host."""
- raise NotImplementedError()
-
- def _teardown_network_on_host(self, context, network):
- """Sets up network on this host."""
- raise NotImplementedError()
-
- def validate_networks(self, context, networks):
- """check if the networks exists and host
- is set to each network.
- """
- LOG.debug('Validate networks')
- if networks is None or len(networks) == 0:
- return
-
- for network_uuid, address in networks:
- # check if the fixed IP address is valid and
- # it actually belongs to the network
- if address is not None:
- if not netutils.is_valid_ip(address):
- raise exception.FixedIpInvalid(address=address)
-
- fixed_ip_ref = objects.FixedIP.get_by_address(
- context, address, expected_attrs=['network'])
- network = fixed_ip_ref.network
- if network.uuid != network_uuid:
- raise exception.FixedIpNotFoundForNetwork(
- address=address, network_uuid=network_uuid)
- if fixed_ip_ref.instance_uuid is not None:
- raise exception.FixedIpAlreadyInUse(
- address=address,
- instance_uuid=fixed_ip_ref.instance_uuid)
-
- def _get_network_by_id(self, context, network_id):
- return objects.Network.get_by_id(context, network_id,
- project_only='allow_none')
-
- def _get_networks_by_uuids(self, context, network_uuids):
- networks = objects.NetworkList.get_by_uuids(
- context, network_uuids, project_only="allow_none")
- networks.sort(key=lambda x: network_uuids.index(x.uuid))
- return networks
-
- def get_vifs_by_instance(self, context, instance_id):
- """Returns the vifs associated with an instance."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- instance = objects.Instance.get_by_id(context, instance_id)
- LOG.debug('Get VIFs for instance', instance=instance)
-
- # NOTE(russellb) No need to object-ify this since
- # get_vifs_by_instance() is unused and set to be removed.
- vifs = objects.VirtualInterfaceList.get_by_instance_uuid(context,
- instance.uuid)
- for vif in vifs:
- if vif.network_id is not None:
- network = self._get_network_by_id(context, vif.network_id)
- vif.net_uuid = network.uuid
- return [dict(vif) for vif in vifs]
-
- def get_instance_id_by_floating_address(self, context, address):
- """Returns the instance id a floating IP's fixed IP is allocated to."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- LOG.debug('Get instance for floating address %s', address)
- fixed_ip = objects.FixedIP.get_by_floating_address(context, address)
- if fixed_ip is None:
- return None
- else:
- return fixed_ip.instance_uuid
-
- def get_network(self, context, network_uuid):
- # NOTE(vish): used locally
-
- return objects.Network.get_by_uuid(context.elevated(), network_uuid)
-
- def get_all_networks(self, context):
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- try:
- return obj_base.obj_to_primitive(
- objects.NetworkList.get_all(context))
- except exception.NoNetworksFound:
- return []
-
- def disassociate_network(self, context, network_uuid):
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- network = self.get_network(context, network_uuid)
- network.disassociate(context, network.id)
-
- def get_fixed_ip(self, context, id):
- """Return a fixed IP."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- return objects.FixedIP.get_by_id(context, id)
-
- def get_fixed_ip_by_address(self, context, address):
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- return objects.FixedIP.get_by_address(context, address)
-
- def get_vif_by_mac_address(self, context, mac_address):
- """Returns the vifs record for the mac_address."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- # NOTE(russellb) No need to object-ify this since
- # get_vifs_by_instance() is unused and set to be removed.
- vif = objects.VirtualInterface.get_by_address(context, mac_address)
- if vif.network_id is not None:
- network = self._get_network_by_id(context, vif.network_id)
- vif.net_uuid = network.uuid
- return vif
-
- @periodic_task.periodic_task(
- spacing=CONF.dns_update_periodic_interval)
- def _periodic_update_dns(self, context):
- """Update local DNS entries of all networks on this host."""
- networks = objects.NetworkList.get_by_host(context, self.host)
- for network in networks:
- dev = self.driver.get_dev(network)
- self.driver.update_dns(context, dev, network)
-
- def update_dns(self, context, network_ids):
- """Called when fixed IP is allocated or deallocated."""
- if CONF.fake_network:
- return
-
- LOG.debug('Update DNS for network ids: %s', network_ids)
- networks = [network for network in
- objects.NetworkList.get_by_host(context, self.host)
- if network.multi_host and network.id in network_ids]
- for network in networks:
- dev = self.driver.get_dev(network)
- self.driver.update_dns(context, dev, network)
-
- def add_network_to_project(self, ctxt, project_id, network_uuid):
- raise NotImplementedError()
-
-
-class FlatManager(NetworkManager):
- """Basic network where no vlans are used.
-
- FlatManager does not do any bridge or vlan creation. The user is
- responsible for setting up whatever bridges are specified when creating
- networks through nova-manage. This bridge needs to be created on all
- compute hosts.
-
- The idea is to create a single network for the host with a command like:
- nova-manage network create 192.168.0.0/24 1 256. Creating multiple
- networks for one manager is currently not supported, but could be
- added by modifying allocate_fixed_ip and get_network to get the network
- with new logic. Arbitrary lists of addresses in a single network can
- be accomplished with manual db editing.
-
- If flat_injected is True, the compute host will attempt to inject network
- config into the guest. It attempts to modify /etc/network/interfaces and
- currently only works on debian based systems. To support a wider range of
- OSes, some other method may need to be devised to let the guest know which
- IP it should be using so that it can configure itself. Perhaps an attached
- disk or serial device with configuration info.
-
- Metadata forwarding must be handled by the gateway, and since nova does
- not do any setup in this mode, it must be done manually. Requests to
- 169.254.169.254 port 80 will need to be forwarded to the api server.
-
- """
-
- timeout_fixed_ips = False
-
- required_create_args = ['bridge']
-
- def _allocate_fixed_ips(self, context, instance_id, host, networks,
- **kwargs):
- """Calls allocate_fixed_ip once for each network."""
- requested_networks = kwargs.get('requested_networks')
- addresses_by_network = {}
- if requested_networks is not None:
- for request in requested_networks:
- addresses_by_network[request.network_id] = request.address
- for network in networks:
- if network['uuid'] in addresses_by_network:
- address = addresses_by_network[network['uuid']]
- else:
- address = None
- self.allocate_fixed_ip(context, instance_id,
- network, address=address)
-
- def deallocate_fixed_ip(self, context, address, host=None, teardown=True,
- instance=None):
- """Returns a fixed IP to the pool."""
- super(FlatManager, self).deallocate_fixed_ip(context, address, host,
- teardown,
- instance=instance)
- objects.FixedIP.disassociate_by_address(context, address)
-
- def _setup_network_on_host(self, context, network):
- """Setup Network on this host."""
- # NOTE(tr3buchet): this does not need to happen on every ip
- # allocation, this functionality makes more sense in create_network
- # but we'd have to move the flat_injected flag to compute
- network.injected = CONF.flat_injected
- network.save()
-
- def _teardown_network_on_host(self, context, network):
- """Tear down network on this host."""
- pass
-
- # NOTE(justinsb): The floating ip functions are stub-implemented.
- # We were throwing an exception, but this was messing up horizon.
- # Timing makes it difficult to implement floating ips here, in Essex.
-
- def get_floating_ip(self, context, id):
- """Returns a floating IP as a dict."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- return None
-
- def get_floating_pools(self, context):
- """Returns list of floating pools."""
- # NOTE(maurosr) This method should be removed in future, replaced by
- # get_floating_ip_pools. See bug #1091668
- return {}
-
- def get_floating_ip_pools(self, context):
- """Returns list of floating IP pools."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- return {}
-
- def get_floating_ip_by_address(self, context, address):
- """Returns a floating IP as a dict."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- return None
-
- def get_floating_ips_by_project(self, context):
- """Returns the floating IPs allocated to a project."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- return []
-
- def get_floating_ips_by_fixed_address(self, context, fixed_address):
- """Returns the floating IPs associated with a fixed_address."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- return []
-
- # NOTE(hanlind): This method can be removed in version 2.0 of the RPC API
- def allocate_floating_ip(self, context, project_id, pool):
- """Gets a floating IP from the pool."""
- return None
-
- # NOTE(hanlind): This method can be removed in version 2.0 of the RPC API
- def deallocate_floating_ip(self, context, address,
- affect_auto_assigned):
- """Returns a floating IP to the pool."""
- return None
-
- # NOTE(hanlind): This method can be removed in version 2.0 of the RPC API
- def associate_floating_ip(self, context, floating_address, fixed_address,
- affect_auto_assigned=False):
- """Associates a floating IP with a fixed IP.
-
- Makes sure everything makes sense then calls _associate_floating_ip,
- rpc'ing to correct host if i'm not it.
- """
- return None
-
- # NOTE(hanlind): This method can be removed in version 2.0 of the RPC API
- def disassociate_floating_ip(self, context, address,
- affect_auto_assigned=False):
- """Disassociates a floating IP from its fixed IP.
-
- Makes sure everything makes sense then calls _disassociate_floating_ip,
- rpc'ing to correct host if i'm not it.
- """
- return None
-
- def migrate_instance_start(self, context, instance_uuid,
- floating_addresses,
- rxtx_factor=None, project_id=None,
- source=None, dest=None):
- pass
-
- def migrate_instance_finish(self, context, instance_uuid,
- floating_addresses, host=None,
- rxtx_factor=None, project_id=None,
- source=None, dest=None):
- pass
-
- def update_dns(self, context, network_ids):
- """Called when fixed IP is allocated or deallocated."""
- pass
-
-
-class FlatDHCPManager(RPCAllocateFixedIP, floating_ips.FloatingIP,
- NetworkManager):
- """Flat networking with dhcp.
-
- FlatDHCPManager will start up one dhcp server to give out addresses.
- It never injects network settings into the guest. It also manages bridges.
- Otherwise it behaves like FlatManager.
-
- """
-
- SHOULD_CREATE_BRIDGE = True
- DHCP = True
- required_create_args = ['bridge']
-
- def init_host(self):
- """Do any initialization that needs to be run if this is a
- standalone service.
- """
- ctxt = context.get_admin_context()
- networks = objects.NetworkList.get_by_host(ctxt, self.host)
-
- self.driver.iptables_manager.defer_apply_on()
-
- self.l3driver.initialize(fixed_range=False, networks=networks)
- super(FlatDHCPManager, self).init_host()
- self.init_host_floating_ips()
-
- self.driver.iptables_manager.defer_apply_off()
-
- def _setup_network_on_host(self, context, network):
- """Sets up network on this host."""
- network.dhcp_server = self._get_dhcp_ip(context, network)
-
- self._initialize_network(network)
-
- # NOTE(vish): if dhcp server is not set then don't dhcp
- if not CONF.fake_network and network.enable_dhcp:
- dev = self.driver.get_dev(network)
- # NOTE(dprince): dhcp DB queries require elevated context
- elevated = context.elevated()
- self.driver.update_dhcp(elevated, dev, network)
- if CONF.use_ipv6:
- self.driver.update_ra(context, dev, network)
- gateway = get_my_linklocal(dev)
- network.gateway_v6 = gateway
- network.save()
-
- def _teardown_network_on_host(self, context, network):
- # NOTE(vish): if dhcp server is not set then don't dhcp
- if not CONF.fake_network and network.enable_dhcp:
- network['dhcp_server'] = self._get_dhcp_ip(context, network)
- dev = self.driver.get_dev(network)
- # NOTE(dprince): dhcp DB queries require elevated context
- elevated = context.elevated()
- self.driver.update_dhcp(elevated, dev, network)
-
- def _get_network_dict(self, network):
- """Returns the dict representing necessary and meta network fields."""
-
- # get generic network fields
- network_dict = super(FlatDHCPManager, self)._get_network_dict(network)
-
- # get flat dhcp specific fields
- if self.SHOULD_CREATE_BRIDGE:
- network_dict['should_create_bridge'] = self.SHOULD_CREATE_BRIDGE
- if network.get('bridge_interface'):
- network_dict['bridge_interface'] = network['bridge_interface']
- if network.get('multi_host'):
- network_dict['multi_host'] = network['multi_host']
-
- return network_dict
-
-
-class VlanManager(RPCAllocateFixedIP, floating_ips.FloatingIP, NetworkManager):
- """Vlan network with dhcp.
-
- VlanManager is the most complicated. It will create a host-managed
- vlan for each project. Each project gets its own subnet. The networks
- and associated subnets are created with nova-manage using a command like:
- nova-manage network create 10.0.0.0/8 3 16. This will create 3 networks
- of 16 addresses from the beginning of the 10.0.0.0 range.
-
- A dhcp server is run for each subnet, so each project will have its own.
- For this mode to be useful, each project will need a vpn to access the
- instances in its subnet.
-
- """
-
- SHOULD_CREATE_BRIDGE = True
- SHOULD_CREATE_VLAN = True
- DHCP = True
- required_create_args = ['bridge_interface']
-
- def __init__(self, network_driver=None, *args, **kwargs):
- super(VlanManager, self).__init__(network_driver=network_driver,
- *args, **kwargs)
- # NOTE(cfb) VlanManager doesn't enforce quotas on fixed IP addresses
- # because a project is assigned an entire network.
- self.quotas_cls = objects.QuotasNoOp
-
- def init_host(self):
- """Do any initialization that needs to be run if this is a
- standalone service.
- """
-
- LOG.debug('Setup network on host %s', self.host)
- ctxt = context.get_admin_context()
- networks = objects.NetworkList.get_by_host(ctxt, self.host)
-
- self.driver.iptables_manager.defer_apply_on()
-
- self.l3driver.initialize(fixed_range=False, networks=networks)
- NetworkManager.init_host(self)
- self.init_host_floating_ips()
-
- self.driver.iptables_manager.defer_apply_off()
-
- def allocate_fixed_ip(self, context, instance_id, network, **kwargs):
- """Gets a fixed IP from the pool."""
-
- LOG.debug('Allocate fixed IP on network %s', network['uuid'],
- instance_uuid=instance_id)
-
- # NOTE(mriedem): allocate the vif before associating the
- # instance to reduce a race window where a previous instance
- # was associated with the fixed IP and has released it, because
- # release_fixed_ip will disassociate if allocated is False.
- vif = objects.VirtualInterface.get_by_instance_and_network(
- context, instance_id, network['id'])
- if vif is None:
- LOG.debug('vif for network %(network)s and instance '
- '%(instance_id)s is used up, '
- 'trying to create new vif',
- {'network': network['id'],
- 'instance_id': instance_id})
- vif = self._add_virtual_interface(context,
- instance_id, network['id'])
-
- if kwargs.get('vpn', None):
- address = network['vpn_private_address']
- fip = objects.FixedIP.associate(context, str(address),
- instance_id, network['id'],
- reserved=True,
- vif_id=vif.id)
- else:
- address = kwargs.get('address', None)
- if address:
- fip = objects.FixedIP.associate(context, str(address),
- instance_id,
- network['id'],
- vif_id=vif.id)
- else:
- fip = objects.FixedIP.associate_pool(
- context, network['id'], instance_id,
- vif_id=vif.id)
- address = fip.address
-
- if not kwargs.get('vpn', None):
- self._do_trigger_security_group_members_refresh_for_instance(
- instance_id)
-
- # NOTE(vish) This db query could be removed if we pass az and name
- # (or the whole instance object).
- instance = objects.Instance.get_by_uuid(context, instance_id)
-
- name = instance.display_name
- if self._validate_instance_zone_for_dns_domain(context, instance):
- self.instance_dns_manager.create_entry(name, address,
- "A",
- self.instance_dns_domain)
- self.instance_dns_manager.create_entry(instance_id, address,
- "A",
- self.instance_dns_domain)
-
- self._setup_network_on_host(context, network)
- LOG.debug('Allocated fixed IP %s on network %s', address,
- network['uuid'], instance=instance)
- return address
-
- def add_network_to_project(self, context, project_id, network_uuid=None):
- """Force adds another network to a project."""
- LOG.debug('Add network %s to project %s', network_uuid, project_id)
- if network_uuid is not None:
- network_id = self.get_network(context, network_uuid).id
- else:
- network_id = None
- objects.Network.associate(context, project_id, network_id, force=True)
-
- def associate(self, context, network_uuid, associations):
- """Associate or disassociate host or project to network."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi to 2.0.
- LOG.debug('Associate network %s: |%s|', network_uuid, associations)
- network = self.get_network(context, network_uuid)
- network_id = network.id
- if 'host' in associations:
- host = associations['host']
- if host is None:
- network.disassociate(context, network_id,
- host=True, project=False)
- else:
- network.host = self.host
- network.save()
- if 'project' in associations:
- project = associations['project']
- if project is None:
- network.disassociate(context, network_id,
- host=False, project=True)
- else:
- network.associate(context, project, network_id, force=True)
-
- def _get_network_by_id(self, context, network_id):
- # NOTE(vish): Don't allow access to networks with project_id=None as
- # these are networks that haven't been allocated to a
- # project yet.
- return objects.Network.get_by_id(context, network_id,
- project_only=True)
-
- def _get_networks_by_uuids(self, context, network_uuids):
- # NOTE(vish): Don't allow access to networks with project_id=None as
- # these are networks that haven't been allocated to a
- # project yet.
- networks = objects.NetworkList.get_by_uuids(
- context, network_uuids, project_only=True)
- networks.sort(key=lambda x: network_uuids.index(x.uuid))
- return networks
-
- def _get_networks_for_instance(self, context, instance_id, project_id,
- requested_networks=None):
- """Determine which networks an instance should connect to."""
- # get networks associated with project
- if requested_networks is not None and len(requested_networks) != 0:
- network_uuids = [request.network_id
- for request in requested_networks]
- networks = self._get_networks_by_uuids(context, network_uuids)
- else:
- # NOTE(vish): Allocates network on demand so requires admin.
- networks = objects.NetworkList.get_by_project(
- context.elevated(), project_id)
- return networks
-
- def create_networks(self, context, **kwargs):
- """Create networks based on parameters."""
- self._convert_int_args(kwargs)
-
- kwargs["vlan_start"] = kwargs.get("vlan_start") or CONF.vlan_start
- kwargs["num_networks"] = (kwargs.get("num_networks") or
- CONF.num_networks)
- kwargs["network_size"] = (kwargs.get("network_size") or
- CONF.network_size)
- # Check that num_networks + vlan_start is not > 4094, fixes lp708025
- if kwargs["num_networks"] + kwargs["vlan_start"] > 4094:
- raise ValueError(_('The sum between the number of networks and'
- ' the vlan start cannot be greater'
- ' than 4094'))
-
- # Check that vlan is not greater than 4094 or less then 1
- vlan_num = kwargs.get("vlan", None)
- if vlan_num is not None:
- try:
- vlan_num = int(vlan_num)
- except ValueError:
- raise ValueError(_("vlan must be an integer"))
- if vlan_num > 4094:
- raise ValueError(_('The vlan number cannot be greater than'
- ' 4094'))
- if vlan_num < 1:
- raise ValueError(_('The vlan number cannot be less than 1'))
-
- # check that num networks and network size fits in fixed_net
- fixed_net = netaddr.IPNetwork(kwargs['cidr'])
- if fixed_net.size < kwargs['num_networks'] * kwargs['network_size']:
- raise ValueError(_('The network range is not '
- 'big enough to fit %(num_networks)s networks. Network '
- 'size is %(network_size)s') % kwargs)
-
- kwargs['bridge_interface'] = (kwargs.get('bridge_interface') or
- CONF.vlan_interface)
- LOG.debug('Create network: |%s|', kwargs)
- return NetworkManager.create_networks(
- self, context, vpn=True, **kwargs)
-
- @utils.synchronized('setup_network', external=True)
- def _setup_network_on_host(self, context, network):
- """Sets up network on this host."""
- if not network.vpn_public_address:
- address = CONF.vpn_ip
- network.vpn_public_address = address
- network.save()
- else:
- address = network.vpn_public_address
- network.dhcp_server = self._get_dhcp_ip(context, network)
-
- self._initialize_network(network)
-
- # NOTE(vish): only ensure this forward if the address hasn't been set
- # manually.
- if address == CONF.vpn_ip and hasattr(self.driver,
- "ensure_vpn_forward"):
- self.l3driver.add_vpn(CONF.vpn_ip,
- network.vpn_public_port,
- network.vpn_private_address)
- if not CONF.fake_network:
- dev = self.driver.get_dev(network)
- # NOTE(dprince): dhcp DB queries require elevated context
- if network.enable_dhcp:
- elevated = context.elevated()
- self.driver.update_dhcp(elevated, dev, network)
- if CONF.use_ipv6:
- self.driver.update_ra(context, dev, network)
- gateway = get_my_linklocal(dev)
- network.gateway_v6 = gateway
- network.save()
-
- @utils.synchronized('setup_network', external=True)
- def _teardown_network_on_host(self, context, network):
- if not CONF.fake_network:
- network['dhcp_server'] = self._get_dhcp_ip(context, network)
- dev = self.driver.get_dev(network)
-
- # NOTE(ethuleau): For multi hosted networks, if the network is no
- # more used on this host and if VPN forwarding rule aren't handed
- # by the host, we delete the network gateway.
- vpn_address = network['vpn_public_address']
- if (CONF.teardown_unused_network_gateway and
- network['multi_host'] and vpn_address != CONF.vpn_ip and
- not objects.Network.in_use_on_host(context, network['id'],
- self.host)):
- LOG.debug("Remove unused gateway %s", network['bridge'])
- if network.enable_dhcp:
- self.driver.kill_dhcp(dev)
- self.l3driver.remove_gateway(network)
- if not self._uses_shared_ip(network):
- fip = objects.FixedIP.get_by_address(context,
- network.dhcp_server)
- fip.allocated = False
- fip.host = None
- fip.save()
- # NOTE(vish): if dhcp server is not set then don't dhcp
- elif network.enable_dhcp:
- # NOTE(dprince): dhcp DB queries require elevated context
- elevated = context.elevated()
- self.driver.update_dhcp(elevated, dev, network)
-
- def _get_network_dict(self, network):
- """Returns the dict representing necessary and meta network fields."""
-
- # get generic network fields
- network_dict = super(VlanManager, self)._get_network_dict(network)
-
- # get vlan specific network fields
- if self.SHOULD_CREATE_BRIDGE:
- network_dict['should_create_bridge'] = self.SHOULD_CREATE_BRIDGE
- if self.SHOULD_CREATE_VLAN:
- network_dict['should_create_vlan'] = self.SHOULD_CREATE_VLAN
- for k in ['vlan', 'bridge_interface', 'multi_host']:
- if network.get(k):
- network_dict[k] = network[k]
-
- return network_dict
-
- @property
- def _bottom_reserved_ips(self):
- """Number of reserved IPs at the bottom of the range."""
- return super(VlanManager, self)._bottom_reserved_ips + 1 # vpn server
-
- @property
- def _top_reserved_ips(self):
- """Number of reserved IPs at the top of the range."""
- parent_reserved = super(VlanManager, self)._top_reserved_ips
- return parent_reserved + CONF.cnt_vpn_clients
diff --git a/nova/network/minidns.py b/nova/network/minidns.py
deleted file mode 100644
index 5da77a53e5..0000000000
--- a/nova/network/minidns.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# Copyright 2011 Andrew Bogott for the Wikimedia Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import os
-
-from oslo_config import cfg
-from oslo_log import log as logging
-import six
-
-from nova import exception
-from nova.i18n import _
-from nova.network import dns_driver
-
-
-CONF = cfg.CONF
-LOG = logging.getLogger(__name__)
-
-
-class MiniDNS(dns_driver.DNSDriver):
- """Trivial DNS driver. This will read/write to either a local,
- flat file or an in memory StringIO and have no effect on your actual
- DNS system. This class is strictly for testing purposes, and should
- keep you out of dependency hell.
-
- A file is used when CONF.log_dir is set. This is relevant for when
- two different DNS driver instances share the same data file.
-
- Note that there is almost certainly a race condition here that
- will manifest anytime instances are rapidly created and deleted.
- A proper implementation will need some manner of locking.
- """
-
- def __init__(self):
- filename = None
- if CONF.log_dir:
- filename = os.path.join(CONF.log_dir, "dnstest.txt")
- self.file = open(filename, 'w+')
- else:
- self.file = six.StringIO()
- if not filename or not os.path.exists(filename):
- self.file.write("# minidns\n\n\n")
- self.file.flush()
-
- def get_domains(self):
- entries = []
- self.file.seek(0)
- for line in self.file:
- entry = self.parse_line(line)
- if entry and entry['address'] == 'domain':
- entries.append(entry['name'])
- return entries
-
- def qualify(self, name, domain):
- if domain:
- qualified = "%s.%s" % (name, domain)
- else:
- qualified = name
-
- return qualified.lower()
-
- def create_entry(self, name, address, type, domain):
- if name is None:
- raise exception.InvalidInput(_("Invalid name"))
-
- if type.lower() != 'a':
- raise exception.InvalidInput(_("This driver only supports "
- "type 'a'"))
-
- if self.get_entries_by_name(name, domain):
- raise exception.FloatingIpDNSExists(name=name, domain=domain)
-
- self.file.seek(0, os.SEEK_END)
- self.file.write("%s %s %s\n" %
- (address, self.qualify(name, domain), type))
- self.file.flush()
-
- def parse_line(self, line):
- vals = line.split()
- if len(vals) < 3:
- return None
- else:
- entry = {}
- entry['address'] = vals[0].lower()
- entry['name'] = vals[1].lower()
- entry['type'] = vals[2].lower()
- if entry['address'] == 'domain':
- entry['domain'] = entry['name']
- else:
- entry['domain'] = entry['name'].partition('.')[2]
- return entry
-
- def delete_entry(self, name, domain):
- if name is None:
- raise exception.InvalidInput(_("Invalid name"))
-
- deleted = False
- keeps = []
- self.file.seek(0)
- for line in self.file:
- entry = self.parse_line(line)
- if (not entry or
- entry['name'] != self.qualify(name, domain)):
- keeps.append(line)
- else:
- deleted = True
- self.file.truncate(0)
- self.file.seek(0)
- self.file.write(''.join(keeps))
- self.file.flush()
- if not deleted:
- LOG.warning('Cannot delete entry |%s|', self.qualify(name, domain))
- raise exception.NotFound
-
- def modify_address(self, name, address, domain):
-
- if not self.get_entries_by_name(name, domain):
- raise exception.NotFound
-
- lines = []
- self.file.seek(0)
- for line in self.file:
- entry = self.parse_line(line)
- if (entry and
- entry['name'] == self.qualify(name, domain)):
- lines.append("%s %s %s\n" %
- (address, self.qualify(name, domain), entry['type']))
- else:
- lines.append(line)
- self.file.truncate(0)
- self.file.seek(0)
- self.file.write(''.join(lines))
- self.file.flush()
-
- def get_entries_by_address(self, address, domain):
- entries = []
- self.file.seek(0)
- for line in self.file:
- entry = self.parse_line(line)
- if entry and entry['address'] == address.lower():
- if entry['name'].endswith(domain.lower()):
- name = entry['name'].split(".")[0]
- if name not in entries:
- entries.append(name)
-
- return entries
-
- def get_entries_by_name(self, name, domain):
- entries = []
- self.file.seek(0)
- for line in self.file:
- entry = self.parse_line(line)
- if (entry and
- entry['name'] == self.qualify(name, domain)):
- entries.append(entry['address'])
- return entries
-
- def delete_dns_file(self):
- self.file.close()
- try:
- if os.path.exists(self.file.name):
- try:
- os.remove(self.file.name)
- except OSError:
- pass
- except AttributeError:
- # This was a BytesIO, which has no name.
- pass
-
- def create_domain(self, fqdomain):
- if self.get_entries_by_name(fqdomain, ''):
- raise exception.FloatingIpDNSExists(name=fqdomain, domain='')
-
- self.file.seek(0, os.SEEK_END)
- self.file.write("%s %s %s\n" % ('domain', fqdomain, 'domain'))
- self.file.flush()
-
- def delete_domain(self, fqdomain):
- deleted = False
- keeps = []
- self.file.seek(0)
- for line in self.file:
- entry = self.parse_line(line)
- if (not entry or
- entry['domain'] != fqdomain.lower()):
- keeps.append(line)
- else:
- LOG.info("deleted %s", entry)
- deleted = True
- self.file.truncate(0)
- self.file.seek(0)
- self.file.write(''.join(keeps))
- self.file.flush()
- if not deleted:
- LOG.warning('Cannot delete domain |%s|', fqdomain)
- raise exception.NotFound
diff --git a/nova/network/neutronv2/api.py b/nova/network/neutronv2/api.py
index 5c579c1786..17a0fe4c31 100644
--- a/nova/network/neutronv2/api.py
+++ b/nova/network/neutronv2/api.py
@@ -2496,14 +2496,6 @@ class API(base_api.NetworkAPI):
uuid=network['id'])
return net_obj
- def delete(self, context, network_uuid):
- """Delete a network for client."""
- raise NotImplementedError()
-
- def get_fixed_ip(self, context, id):
- """Get a fixed IP from the id."""
- raise NotImplementedError()
-
def get_fixed_ip_by_address(self, context, address):
"""Return instance uuids given an address."""
uuid_maps = self._get_instance_uuids_by_ip(context, address)
@@ -2563,8 +2555,6 @@ class API(base_api.NetworkAPI):
"""Return floating IP pool names."""
client = get_client(context)
pools = self._get_floating_ip_pools(client)
- # Note(salv-orlando): Return a list of names to be consistent with
- # nova.network.api.get_floating_ip_pools
return [n['name'] or n['id'] for n in pools]
def _make_floating_ip_obj(self, context, fip, pool_dict, port_dict):
@@ -2639,9 +2629,6 @@ class API(base_api.NetworkAPI):
return objects.VirtualInterfaceList.get_by_instance_uuid(context,
instance.uuid)
- def get_vif_by_mac_address(self, context, mac_address):
- raise NotImplementedError()
-
def _get_floating_ip_pool_id_by_name_or_id(self, client, name_or_id):
search_opts = {constants.NET_EXTERNAL: True, 'fields': 'id'}
if uuidutils.is_uuid_like(name_or_id):
@@ -2660,27 +2647,10 @@ class API(base_api.NetworkAPI):
% name_or_id)
raise exception.NovaException(message=msg)
- def _get_default_floating_ip_pool_name(self):
- """Get default pool name from config.
-
- TODO(stephenfin): Remove this helper function in Queens, opting to
- use the [neutron] option only.
- """
- if CONF.default_floating_pool != 'nova':
- LOG.warning("Config option 'default_floating_pool' is set to "
- "a non-default value. Falling back to this value "
- "for now but this behavior will change in a "
- "future release. You should unset this value "
- "and set the '[neutron] default_floating_pool' "
- "option instead.")
- return CONF.default_floating_pool
-
- return CONF.neutron.default_floating_pool
-
def allocate_floating_ip(self, context, pool=None):
"""Add a floating IP to a project from a pool."""
client = get_client(context)
- pool = pool or self._get_default_floating_ip_pool_name()
+ pool = pool or CONF.neutron.default_floating_pool
pool_id = self._get_floating_ip_pool_id_by_name_or_id(client, pool)
param = {'floatingip': {'floating_network_id': pool_id}}
@@ -3277,45 +3247,6 @@ class API(base_api.NetworkAPI):
subnets.append(subnet_object)
return subnets
- def get_dns_domains(self, context):
- """Return a list of available dns domains.
-
- These can be used to create DNS entries for floating IPs.
- """
- raise NotImplementedError()
-
- def add_dns_entry(self, context, address, name, dns_type, domain):
- """Create specified DNS entry for address."""
- raise NotImplementedError()
-
- def modify_dns_entry(self, context, name, address, domain):
- """Create specified DNS entry for address."""
- raise NotImplementedError()
-
- def delete_dns_entry(self, context, name, domain):
- """Delete the specified dns entry."""
- raise NotImplementedError()
-
- def delete_dns_domain(self, context, domain):
- """Delete the specified dns domain."""
- raise NotImplementedError()
-
- def get_dns_entries_by_address(self, context, address, domain):
- """Get entries for address and domain."""
- raise NotImplementedError()
-
- def get_dns_entries_by_name(self, context, name, domain):
- """Get entries for name and domain."""
- raise NotImplementedError()
-
- def create_private_dns_domain(self, context, domain, availability_zone):
- """Create a private DNS domain with nova availability zone."""
- raise NotImplementedError()
-
- def create_public_dns_domain(self, context, domain, project=None):
- """Create a private DNS domain with optional nova project."""
- raise NotImplementedError()
-
def setup_instance_network_on_host(
self, context, instance, host, migration=None,
provider_mappings=None):
diff --git a/nova/network/noop_dns_driver.py b/nova/network/noop_dns_driver.py
deleted file mode 100644
index d6f2783eab..0000000000
--- a/nova/network/noop_dns_driver.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2012 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from nova.network import dns_driver
-
-
-class NoopDNSDriver(dns_driver.DNSDriver):
- """No-op DNS manager. Does nothing."""
-
- def __init__(self):
- pass
-
- def get_domains(self):
- return []
-
- def create_entry(self, _name, _address, _type, _domain):
- pass
-
- def delete_entry(self, _name, _domain):
- pass
-
- def modify_address(self, _name, _address, _domain):
- pass
-
- def get_entries_by_address(self, _address, _domain):
- return []
-
- def get_entries_by_name(self, _name, _domain):
- return []
-
- def create_domain(self, _fqdomain):
- pass
-
- def delete_domain(self, _fqdomain):
- pass
diff --git a/nova/network/rpcapi.py b/nova/network/rpcapi.py
deleted file mode 100644
index ad8f2dc7a4..0000000000
--- a/nova/network/rpcapi.py
+++ /dev/null
@@ -1,369 +0,0 @@
-# Copyright 2013, Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Client side of the network RPC API.
-"""
-
-import oslo_messaging as messaging
-from oslo_serialization import jsonutils
-
-import nova.conf
-from nova import exception
-from nova.objects import base as objects_base
-from nova import profiler
-from nova import rpc
-
-
-CONF = nova.conf.CONF
-RPC_TOPIC = 'network'
-
-
-@profiler.trace_cls("rpc")
-class NetworkAPI(object):
- '''Client side of the network rpc API.
-
- API version history:
-
- * 1.0 - Initial version.
- * 1.1 - Adds migrate_instance_[start|finish]
- * 1.2 - Make migrate_instance_[start|finish] a little more flexible
- * 1.3 - Adds fanout cast update_dns for multi_host networks
- * 1.4 - Add get_backdoor_port()
- * 1.5 - Adds associate
- * 1.6 - Adds instance_uuid to _{dis,}associate_floating_ip
- * 1.7 - Adds method get_floating_ip_pools to replace get_floating_pools
- * 1.8 - Adds macs to allocate_for_instance
- * 1.9 - Adds rxtx_factor to [add|remove]_fixed_ip, removes
- instance_uuid from allocate_for_instance and
- instance_get_nw_info
-
- ... Grizzly supports message version 1.9. So, any changes to existing
- methods in 1.x after that point should be done such that they can
- handle the version_cap being set to 1.9.
-
- * 1.10- Adds (optional) requested_networks to deallocate_for_instance
-
- ... Havana supports message version 1.10. So, any changes to existing
- methods in 1.x after that point should be done such that they can
- handle the version_cap being set to 1.10.
-
- * NOTE: remove unused method get_vifs_by_instance()
- * NOTE: remove unused method get_vif_by_mac_address()
- * NOTE: remove unused method get_network()
- * NOTE: remove unused method get_all_networks()
- * 1.11 - Add instance to deallocate_for_instance().
- Remove instance_id, project_id, and host.
- * 1.12 - Add instance to deallocate_fixed_ip()
-
- ... Icehouse supports message version 1.12. So, any changes to
- existing methods in 1.x after that point should be done such that they
- can handle the version_cap being set to 1.12.
-
- * 1.13 - Convert allocate_for_instance()
- to use NetworkRequestList objects
-
- ... Juno and Kilo supports message version 1.13. So, any changes to
- existing methods in 1.x after that point should be done such that they
- can handle the version_cap being set to 1.13.
-
- * NOTE: remove unused method get_floating_ips_by_fixed_address()
- * NOTE: remove unused method get_instance_uuids_by_ip_filter()
- * NOTE: remove unused method disassociate_network()
- * NOTE: remove unused method get_fixed_ip()
- * NOTE: remove unused method get_fixed_ip_by_address()
- * NOTE: remove unused method get_floating_ip()
- * NOTE: remove unused method get_floating_ip_pools()
- * NOTE: remove unused method get_floating_ip_by_address()
- * NOTE: remove unused method get_floating_ips_by_project()
- * NOTE: remove unused method get_instance_id_by_floating_address()
- * NOTE: remove unused method allocate_floating_ip()
- * NOTE: remove unused method deallocate_floating_ip()
- * NOTE: remove unused method associate_floating_ip()
- * NOTE: remove unused method disassociate_floating_ip()
- * NOTE: remove unused method associate()
-
- * 1.14 - Add mac parameter to release_fixed_ip().
- * 1.15 - Convert set_network_host() to use Network objects.
-
- ... Liberty supports message version 1.15. So, any changes to
- existing methods in 1.x after that point should be done such that they
- can handle the version_cap being set to 1.15.
-
- * 1.16 - Transfer instance in addition to instance_id in
- setup_networks_on_host
-
- ... Mitaka supports message version 1.16. So, any changes to
- existing methods in 1.x after that point should be done such that they
- can handle the version_cap being set to 1.16.
-
- * 1.17 - Add method release_dhcp()
-
- ... Newton and Ocata support message version 1.17. So, any changes to
- existing methods in 1.x after that point should be done such that they
- can handle the version_cap being set to 1.17.
- '''
-
- VERSION_ALIASES = {
- 'grizzly': '1.9',
- 'havana': '1.10',
- 'icehouse': '1.12',
- 'juno': '1.13',
- 'kilo': '1.13',
- 'liberty': '1.15',
- 'mitaka': '1.16',
- 'newton': '1.17',
- 'ocata': '1.17',
- }
-
- def __init__(self, topic=None):
- super(NetworkAPI, self).__init__()
- topic = topic or RPC_TOPIC
- target = messaging.Target(topic=topic, version='1.0')
- version_cap = self.VERSION_ALIASES.get(CONF.upgrade_levels.network,
- CONF.upgrade_levels.network)
- serializer = objects_base.NovaObjectSerializer()
- self.client = rpc.get_client(target, version_cap, serializer)
-
- # TODO(russellb): Convert this to named arguments. It's a pretty large
- # list, so unwinding it all is probably best done in its own patch so it's
- # easier to review.
- def create_networks(self, ctxt, **kwargs):
- return self.client.call(ctxt, 'create_networks', **kwargs)
-
- def delete_network(self, ctxt, uuid, fixed_range):
- return self.client.call(ctxt, 'delete_network',
- uuid=uuid, fixed_range=fixed_range)
-
- def allocate_for_instance(self, ctxt, instance_id, project_id, host,
- rxtx_factor, vpn, requested_networks, macs=None,
- dhcp_options=None):
- # NOTE(mriedem): dhcp_options should be removed in version 2.0
- version = '1.13'
- if not self.client.can_send_version(version):
- version = '1.9'
- if requested_networks:
- requested_networks = requested_networks.as_tuples()
-
- if CONF.multi_host:
- cctxt = self.client.prepare(version=version, server=host)
- else:
- cctxt = self.client.prepare(version=version)
- return cctxt.call(ctxt, 'allocate_for_instance',
- instance_id=instance_id, project_id=project_id,
- host=host, rxtx_factor=rxtx_factor, vpn=vpn,
- requested_networks=requested_networks,
- macs=jsonutils.to_primitive(macs))
-
- def deallocate_for_instance(self, ctxt, instance, requested_networks=None):
- cctxt = self.client
- kwargs = {}
- if self.client.can_send_version('1.11'):
- version = '1.11'
- kwargs['instance'] = instance
- kwargs['requested_networks'] = requested_networks
- else:
- if self.client.can_send_version('1.10'):
- version = '1.10'
- kwargs['requested_networks'] = requested_networks
- else:
- version = '1.0'
- kwargs['host'] = instance.host
- kwargs['instance_id'] = instance.uuid
- kwargs['project_id'] = instance.project_id
- if CONF.multi_host:
- cctxt = cctxt.prepare(server=instance.host, version=version)
- return cctxt.call(ctxt, 'deallocate_for_instance', **kwargs)
-
- def release_dhcp(self, ctxt, host, dev, address, vif_address):
- if self.client.can_send_version('1.17'):
- cctxt = self.client.prepare(version='1.17', server=host)
- return cctxt.call(ctxt, 'release_dhcp', dev=dev, address=address,
- vif_address=vif_address)
- else:
- raise exception.RPCPinnedToOldVersion()
-
- def add_fixed_ip_to_instance(self, ctxt, instance_id, rxtx_factor,
- host, network_id):
- cctxt = self.client.prepare(version='1.9')
- return cctxt.call(ctxt, 'add_fixed_ip_to_instance',
- instance_id=instance_id, rxtx_factor=rxtx_factor,
- host=host, network_id=network_id)
-
- def remove_fixed_ip_from_instance(self, ctxt, instance_id, rxtx_factor,
- host, address):
- cctxt = self.client.prepare(version='1.9')
- return cctxt.call(ctxt, 'remove_fixed_ip_from_instance',
- instance_id=instance_id, rxtx_factor=rxtx_factor,
- host=host, address=address)
-
- def get_instance_nw_info(self, ctxt, instance_id, rxtx_factor, host,
- project_id):
- cctxt = self.client.prepare(version='1.9')
- return cctxt.call(ctxt, 'get_instance_nw_info',
- instance_id=instance_id, rxtx_factor=rxtx_factor,
- host=host, project_id=project_id)
-
- def validate_networks(self, ctxt, networks):
- return self.client.call(ctxt, 'validate_networks', networks=networks)
-
- def get_dns_domains(self, ctxt):
- return self.client.call(ctxt, 'get_dns_domains')
-
- def add_dns_entry(self, ctxt, address, name, dns_type, domain):
- return self.client.call(ctxt, 'add_dns_entry',
- address=address, name=name,
- dns_type=dns_type, domain=domain)
-
- def modify_dns_entry(self, ctxt, address, name, domain):
- return self.client.call(ctxt, 'modify_dns_entry',
- address=address, name=name, domain=domain)
-
- def delete_dns_entry(self, ctxt, name, domain):
- return self.client.call(ctxt, 'delete_dns_entry',
- name=name, domain=domain)
-
- def delete_dns_domain(self, ctxt, domain):
- return self.client.call(ctxt, 'delete_dns_domain', domain=domain)
-
- def get_dns_entries_by_address(self, ctxt, address, domain):
- return self.client.call(ctxt, 'get_dns_entries_by_address',
- address=address, domain=domain)
-
- def get_dns_entries_by_name(self, ctxt, name, domain):
- return self.client.call(ctxt, 'get_dns_entries_by_name',
- name=name, domain=domain)
-
- def create_private_dns_domain(self, ctxt, domain, av_zone):
- return self.client.call(ctxt, 'create_private_dns_domain',
- domain=domain, av_zone=av_zone)
-
- def create_public_dns_domain(self, ctxt, domain, project):
- return self.client.call(ctxt, 'create_public_dns_domain',
- domain=domain, project=project)
-
- def setup_networks_on_host(self, ctxt, instance_id, host, teardown,
- instance):
- # NOTE(tr3buchet): the call is just to wait for completion
- version = '1.16'
- kwargs = {}
- if not self.client.can_send_version(version):
- version = '1.0'
- else:
- kwargs['instance'] = instance
- cctxt = self.client.prepare(version=version)
- return cctxt.call(ctxt, 'setup_networks_on_host',
- instance_id=instance_id, host=host,
- teardown=teardown, **kwargs)
-
- def set_network_host(self, ctxt, network_ref):
- version = '1.15'
- if not self.client.can_send_version(version):
- version = '1.0'
- network_ref = objects_base.obj_to_primitive(network_ref)
- cctxt = self.client.prepare(version=version)
- return cctxt.call(ctxt, 'set_network_host', network_ref=network_ref)
-
- def rpc_setup_network_on_host(self, ctxt, network_id, teardown, host):
- # NOTE(tr3buchet): the call is just to wait for completion
- cctxt = self.client.prepare(server=host)
- return cctxt.call(ctxt, 'rpc_setup_network_on_host',
- network_id=network_id, teardown=teardown)
-
- # NOTE(russellb): Ideally this would not have a prefix of '_' since it is
- # a part of the rpc API. However, this is how it was being called when the
- # 1.0 API was being documented using this client proxy class. It should be
- # changed if there was ever a 2.0.
- def _rpc_allocate_fixed_ip(self, ctxt, instance_id, network_id, address,
- vpn, host):
- cctxt = self.client.prepare(server=host)
- return cctxt.call(ctxt, '_rpc_allocate_fixed_ip',
- instance_id=instance_id, network_id=network_id,
- address=address, vpn=vpn)
-
- def deallocate_fixed_ip(self, ctxt, address, host, instance):
- kwargs = {}
- if self.client.can_send_version('1.12'):
- version = '1.12'
- kwargs['instance'] = instance
- else:
- version = '1.0'
- cctxt = self.client.prepare(server=host, version=version)
- return cctxt.call(ctxt, 'deallocate_fixed_ip',
- address=address, host=host, **kwargs)
-
- def update_dns(self, ctxt, network_ids):
- cctxt = self.client.prepare(fanout=True, version='1.3')
- cctxt.cast(ctxt, 'update_dns', network_ids=network_ids)
-
- # NOTE(russellb): Ideally this would not have a prefix of '_' since it is
- # a part of the rpc API. However, this is how it was being called when the
- # 1.0 API was being documented using this client proxy class. It should be
- # changed if there was ever a 2.0.
- def _associate_floating_ip(self, ctxt, floating_address, fixed_address,
- interface, host, instance_uuid=None):
- cctxt = self.client.prepare(server=host, version='1.6')
- return cctxt.call(ctxt, '_associate_floating_ip',
- floating_address=floating_address,
- fixed_address=fixed_address,
- interface=interface, instance_uuid=instance_uuid)
-
- # NOTE(russellb): Ideally this would not have a prefix of '_' since it is
- # a part of the rpc API. However, this is how it was being called when the
- # 1.0 API was being documented using this client proxy class. It should be
- # changed if there was ever a 2.0.
- def _disassociate_floating_ip(self, ctxt, address, interface, host,
- instance_uuid=None):
- cctxt = self.client.prepare(server=host, version='1.6')
- return cctxt.call(ctxt, '_disassociate_floating_ip',
- address=address, interface=interface,
- instance_uuid=instance_uuid)
-
- def lease_fixed_ip(self, ctxt, address, host):
- cctxt = self.client.prepare(server=host)
- cctxt.cast(ctxt, 'lease_fixed_ip', address=address)
-
- def release_fixed_ip(self, ctxt, address, host, mac):
- kwargs = {}
- if self.client.can_send_version('1.14'):
- version = '1.14'
- kwargs['mac'] = mac
- else:
- version = '1.0'
- cctxt = self.client.prepare(server=host, version=version)
- cctxt.cast(ctxt, 'release_fixed_ip', address=address, **kwargs)
-
- def migrate_instance_start(self, ctxt, instance_uuid, rxtx_factor,
- project_id, source_compute, dest_compute,
- floating_addresses, host=None):
- cctxt = self.client.prepare(server=host, version='1.2')
- return cctxt.call(ctxt, 'migrate_instance_start',
- instance_uuid=instance_uuid,
- rxtx_factor=rxtx_factor,
- project_id=project_id,
- source=source_compute,
- dest=dest_compute,
- floating_addresses=floating_addresses)
-
- def migrate_instance_finish(self, ctxt, instance_uuid, rxtx_factor,
- project_id, source_compute, dest_compute,
- floating_addresses, host=None):
- cctxt = self.client.prepare(server=host, version='1.2')
- return cctxt.call(ctxt, 'migrate_instance_finish',
- instance_uuid=instance_uuid,
- rxtx_factor=rxtx_factor,
- project_id=project_id,
- source=source_compute,
- dest=dest_compute,
- floating_addresses=floating_addresses)
diff --git a/nova/objects/__init__.py b/nova/objects/__init__.py
index 621c2d2ca6..8ce1514f6f 100644
--- a/nova/objects/__init__.py
+++ b/nova/objects/__init__.py
@@ -33,7 +33,6 @@ def register_all():
__import__('nova.objects.compute_node')
__import__('nova.objects.diagnostics')
__import__('nova.objects.console_auth_token')
- __import__('nova.objects.dns_domain')
__import__('nova.objects.ec2')
__import__('nova.objects.external_event')
__import__('nova.objects.fixed_ip')
diff --git a/nova/objects/dns_domain.py b/nova/objects/dns_domain.py
deleted file mode 100644
index b517c7ec69..0000000000
--- a/nova/objects/dns_domain.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2014, Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from nova.db import api as db
-from nova import objects
-from nova.objects import base
-from nova.objects import fields
-
-
-@base.NovaObjectRegistry.register
-class DNSDomain(base.NovaPersistentObject, base.NovaObject):
- # Version 1.0: Initial version
- VERSION = '1.0'
-
- fields = {
- 'domain': fields.StringField(),
- 'scope': fields.StringField(nullable=True),
- 'availability_zone': fields.StringField(nullable=True),
- 'project_id': fields.StringField(nullable=True),
- }
-
- @staticmethod
- def _from_db_object(context, vif, db_vif):
- for field in vif.fields:
- setattr(vif, field, db_vif[field])
- vif._context = context
- vif.obj_reset_changes()
- return vif
-
- @base.remotable_classmethod
- def get_by_domain(cls, context, domain):
- db_dnsd = db.dnsdomain_get(context, domain)
- if db_dnsd:
- return cls._from_db_object(context, cls(), db_dnsd)
-
- @base.remotable_classmethod
- def register_for_zone(cls, context, domain, zone):
- db.dnsdomain_register_for_zone(context, domain, zone)
-
- @base.remotable_classmethod
- def register_for_project(cls, context, domain, project):
- db.dnsdomain_register_for_project(context, domain, project)
-
- @base.remotable_classmethod
- def delete_by_domain(cls, context, domain):
- db.dnsdomain_unregister(context, domain)
-
-
-@base.NovaObjectRegistry.register
-class DNSDomainList(base.ObjectListBase, base.NovaObject):
- # Version 1.0: Initial version
- VERSION = '1.0'
- fields = {
- 'objects': fields.ListOfObjectsField('DNSDomain'),
- }
-
- @base.remotable_classmethod
- def get_all(cls, context):
- db_domains = db.dnsdomain_get_all(context)
- return base.obj_make_list(context, cls(context), objects.DNSDomain,
- db_domains)
diff --git a/nova/objects/network.py b/nova/objects/network.py
index ea35f938a3..eae7824ee9 100644
--- a/nova/objects/network.py
+++ b/nova/objects/network.py
@@ -105,10 +105,8 @@ class Network(obj_base.NovaPersistentObject, obj_base.NovaObject,
db_value = db_network[field]
if field == 'netmask_v6' and db_value is not None:
db_value = network._convert_legacy_ipv6_netmask(db_value)
- if field == 'dhcp_server' and db_value is None:
+ elif field == 'dhcp_server' and db_value is None:
db_value = db_network['gateway']
- if field == 'share_address' and CONF.share_dhcp_address:
- db_value = CONF.share_dhcp_address
network[field] = db_value
network._context = context
diff --git a/nova/objects/network_request.py b/nova/objects/network_request.py
index ff182195cc..ef07d62bf6 100644
--- a/nova/objects/network_request.py
+++ b/nova/objects/network_request.py
@@ -16,7 +16,6 @@ from oslo_utils import versionutils
from nova.objects import base as obj_base
from nova.objects import fields
-from nova import utils
# These are special case enums for the auto-allocate scenario. 'none' means
# do not allocate a network on server create. 'auto' means auto-allocate a
@@ -49,24 +48,15 @@ class NetworkRequest(obj_base.NovaObject):
def obj_load_attr(self, attr):
setattr(self, attr, None)
- # TODO(stephenfin): Drop the two item tuple case when we drop it entirely
def to_tuple(self):
address = str(self.address) if self.address is not None else None
- if utils.is_neutron():
- return self.network_id, address, self.port_id, self.pci_request_id
- else:
- return self.network_id, address
+ return self.network_id, address, self.port_id, self.pci_request_id
- # TODO(stephenfin): Drop the two item tuple case when we drop it entirely
@classmethod
def from_tuple(cls, net_tuple):
- if len(net_tuple) == 4:
- network_id, address, port_id, pci_request_id = net_tuple
- return cls(network_id=network_id, address=address,
- port_id=port_id, pci_request_id=pci_request_id)
- else:
- network_id, address = net_tuple
- return cls(network_id=network_id, address=address)
+ network_id, address, port_id, pci_request_id = net_tuple
+ return cls(network_id=network_id, address=address, port_id=port_id,
+ pci_request_id=pci_request_id)
@property
def auto_allocate(self):
diff --git a/nova/privsep/linux_net.py b/nova/privsep/linux_net.py
index 8e378b8ac8..12a3b11c17 100644
--- a/nova/privsep/linux_net.py
+++ b/nova/privsep/linux_net.py
@@ -19,53 +19,17 @@ Linux network specific helpers.
import os
-import six
from oslo_concurrency import processutils
from oslo_log import log as logging
from oslo_utils import excutils
-from nova import exception
import nova.privsep.linux_net
LOG = logging.getLogger(__name__)
-@nova.privsep.sys_admin_pctxt.entrypoint
-def add_bridge(bridge):
- """Add a bridge.
-
- :param bridge: the name of the bridge
- """
- processutils.execute('brctl', 'addbr', bridge)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def delete_bridge(bridge):
- """Delete a bridge.
-
- :param bridge: the name of the bridge
- """
- processutils.execute('brctl', 'delbr', bridge)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def bridge_setfd(bridge):
- processutils.execute('brctl', 'setfd', bridge, 0)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def bridge_disable_stp(bridge):
- processutils.execute('brctl', 'stp', bridge, 'off')
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def bridge_add_interface(bridge, interface):
- return processutils.execute('brctl', 'addif', bridge, interface,
- check_exit_code=False)
-
-
def device_exists(device):
"""Check if ethernet device exists."""
return os.path.exists('/sys/class/net/%s' % device)
@@ -118,11 +82,6 @@ def _set_device_trust_inner(dev, vf_num, trusted):
@nova.privsep.sys_admin_pctxt.entrypoint
-def set_device_disabled(dev):
- processutils.execute('ip', 'link', 'set', dev, 'down')
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
def set_device_macaddr(dev, mac_addr, port_state=None):
_set_device_macaddr_inner(dev, mac_addr, port_state=port_state)
@@ -147,80 +106,6 @@ def set_device_macaddr_and_vlan(dev, vf_num, mac_addr, vlan):
@nova.privsep.sys_admin_pctxt.entrypoint
-def bind_ip(device, ip, scope_is_link=False):
- if not scope_is_link:
- processutils.execute('ip', 'addr', 'add', str(ip) + '/32',
- 'dev', device, check_exit_code=[0, 2, 254])
- else:
- processutils.execute('ip', 'addr', 'add', str(ip) + '/32',
- 'scope', 'link', 'dev', device,
- check_exit_code=[0, 2, 254])
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def unbind_ip(device, ip):
- processutils.execute('ip', 'addr', 'del', str(ip) + '/32',
- 'dev', device, check_exit_code=[0, 2, 254])
-
-
-def lookup_ip(device):
- return processutils.execute('ip', 'addr', 'show', 'dev', device,
- 'scope', 'global')
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def change_ip(device, ip):
- processutils.execute('ip', '-f', 'inet6', 'addr', 'change', ip,
- 'dev', device)
-
-
-# TODO(mikal): this is horrid. The calling code takes arguments from an
-# interface list and just regurgitates them here. This isn't good enough,
-# but is outside the scope of the privsep transition. Mark it as bonkers and
-# hope we clean it up later.
-@nova.privsep.sys_admin_pctxt.entrypoint
-def address_command_deprecated(device, action, params):
- cmd = ['ip', 'addr', action]
- cmd.extend(params)
- cmd.extend(['dev', device])
- processutils.execute(*cmd, check_exit_code=[0, 2, 254])
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def dhcp_release(dev, address, mac_address):
- processutils.execute('dhcp_release', dev, address, mac_address)
-
-
-def routes_show(dev):
- # Format of output is:
- # 192.168.1.0/24 proto kernel scope link src 192.168.1.6
- return processutils.execute('ip', 'route', 'show', 'dev', dev)
-
-
-# TODO(mikal): this is horrid. The calling code takes arguments from a route
-# list and just regurgitates them into new routes. This isn't good enough,
-# but is outside the scope of the privsep transition. Mark it as bonkers and
-# hope we clean it up later.
-@nova.privsep.sys_admin_pctxt.entrypoint
-def route_add_deprecated(routes):
- processutils.execute('ip', 'route', 'add', *routes)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def route_delete(dev, route):
- processutils.execute('ip', 'route', 'del', route, 'dev', dev)
-
-
-# TODO(mikal): this is horrid. The calling code takes arguments from a route
-# list and just regurgitates them into new routes. This isn't good enough,
-# but is outside the scope of the privsep transition. Mark it as bonkers and
-# hope we clean it up later.
-@nova.privsep.sys_admin_pctxt.entrypoint
-def route_delete_deprecated(dev, routes):
- processutils.execute('ip', 'route', 'del', *routes)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
def create_tap_dev(dev, mac_address=None, multiqueue=False):
if not device_exists(dev):
try:
@@ -246,174 +131,7 @@ def create_tap_dev(dev, mac_address=None, multiqueue=False):
@nova.privsep.sys_admin_pctxt.entrypoint
-def send_arp_for_ip(ip, device, count):
- out, err = processutils.execute(
- 'arping', '-U', ip, '-A', '-I', device, '-c', str(count),
- check_exit_code=False)
-
- if err:
- LOG.debug('arping error for IP %s', ip)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def clean_conntrack(fixed_ip):
- try:
- processutils.execute('conntrack', '-D', '-r', fixed_ip,
- check_exit_code=[0, 1])
- except processutils.ProcessExecutionError:
- LOG.exception('Error deleting conntrack entries for %s', fixed_ip)
-
-
-def enable_ipv4_forwarding():
- if not ipv4_forwarding_check():
- _enable_ipv4_forwarding_inner()
-
-
-def ipv4_forwarding_check():
- with open('/proc/sys/net/ipv4/ip_forward', 'r') as f:
- return f.readline().strip() == '1'
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def _enable_ipv4_forwarding_inner():
- processutils.execute('sysctl', '-w', 'net.ipv4.ip_forward=1')
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def modify_ebtables(table, rule, insert_rule=True):
- cmd = ['ebtables', '--concurrent', '-t', table]
- if insert_rule:
- cmd.append('-I')
- else:
- cmd.append('-D')
- cmd.extend(rule)
-
- processutils.execute(*cmd, check_exit_code=[0])
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
def add_vlan(bridge_interface, interface, vlan_num):
processutils.execute('ip', 'link', 'add', 'link', bridge_interface,
'name', interface, 'type', 'vlan',
'id', vlan_num, check_exit_code=[0, 2, 254])
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def iptables_get_rules(ipv4=True):
- if ipv4:
- cmd = 'iptables'
- else:
- cmd = 'ip6tables'
-
- return processutils.execute('%s-save' % cmd, '-c', attempts=5)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def iptables_set_rules(rules, ipv4=True):
- if ipv4:
- cmd = 'iptables'
- else:
- cmd = 'ip6tables'
-
- processutils.execute('%s-restore' % cmd, '-c',
- process_input=six.b('\n'.join(rules)),
- attempts=5)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def restart_dnsmasq(flag_file, network_ref, config_file, pid_path, opts_path,
- dhcp_lease_time, lease_max, conf_path, dhcp_bridge,
- dhcp_domain, dns_servers, hosts_path):
- _restart_dnsmasq_inner(flag_file, network_ref, config_file, pid_path,
- opts_path, dhcp_lease_time, lease_max, conf_path,
- dhcp_bridge, dhcp_domain, dns_servers, hosts_path)
-
-
-# NOTE(mikal): this is done like this to enable unit testing
-def _restart_dnsmasq_inner(flag_file, network_ref, config_file, pid_path,
- opts_path, dhcp_lease_time, lease_max, conf_path,
- dhcp_bridge, dhcp_domain, dns_servers, hosts_path):
- cmd = ['env',
- 'CONFIG_FILE=%s' % flag_file,
- 'NETWORK_ID=%s' % str(network_ref['id']),
- 'dnsmasq',
- '--strict-order',
- '--bind-interfaces',
- '--conf-file=%s' % config_file,
- '--pid-file=%s' % pid_path,
- '--dhcp-optsfile=%s' % opts_path,
- '--listen-address=%s' % network_ref['dhcp_server'],
- '--except-interface=lo',
- '--dhcp-range=set:%s,%s,static,%s,%ss' %
- (network_ref['label'],
- network_ref['dhcp_start'],
- network_ref['netmask'],
- dhcp_lease_time),
- '--dhcp-lease-max=%s' % lease_max,
- '--dhcp-hostsfile=%s' % conf_path,
- '--dhcp-script=%s' % dhcp_bridge,
- '--no-hosts',
- '--leasefile-ro']
-
- # dnsmasq currently gives an error for an empty domain,
- # rather than ignoring. So only specify it if defined.
- if dhcp_domain:
- cmd.append('--domain=%s' % dhcp_domain)
-
- if dns_servers:
- cmd.append('--no-resolv')
- for dns_server in dns_servers:
- cmd.append('--server=%s' % dns_server)
-
- if network_ref['multi_host']:
- cmd.append('--addn-hosts=%s' % hosts_path)
-
- processutils.execute(*cmd)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def start_ra(conf_path, pid_path):
- cmd = ['radvd',
- '-C', '%s' % conf_path,
- '-p', '%s' % pid_path]
- processutils.execute(*cmd)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def ovs_plug(timeout, bridge, dev, mac_address):
- cmd = ['ovs-vsctl', '--timeout=%s' % timeout,
- '--', '--may-exist', 'add-port', bridge, dev,
- '--', 'set', 'Interface', dev, 'type=internal',
- '--', 'set', 'Interface', dev,
- 'external-ids:iface-id=%s' % dev,
- '--', 'set', 'Interface', dev,
- 'external-ids:iface-status=active',
- '--', 'set', 'Interface', dev,
- 'external-ids:attached-mac=%s' % mac_address]
- try:
- processutils.execute(*cmd)
- except Exception as e:
- LOG.error('Unable to execute %(cmd)s. Exception: %(exception)s',
- {'cmd': cmd, 'exception': e})
- raise exception.OVSConfigurationFailure(inner_exception=e)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def ovs_drop_nondhcp(bridge, mac_address):
- processutils.execute(
- 'ovs-ofctl', 'add-flow', bridge, 'priority=1,actions=drop')
- processutils.execute(
- 'ovs-ofctl', 'add-flow', bridge,
- 'udp,tp_dst=67,dl_dst=%s,priority=2,actions=normal' % mac_address)
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def ovs_unplug(timeout, bridge, dev):
- cmd = ['ovs-vsctl', '--timeout=%s' % timeout,
- '--', '--if-exists', 'del-port', bridge, dev]
- try:
- processutils.execute(*cmd)
- except Exception as e:
- LOG.error('Unable to execute %(cmd)s. Exception: %(exception)s',
- {'cmd': cmd, 'exception': e})
- raise exception.OVSConfigurationFailure(inner_exception=e)
diff --git a/nova/privsep/utils.py b/nova/privsep/utils.py
index 0b98a10ad4..b51bcf5926 100644
--- a/nova/privsep/utils.py
+++ b/nova/privsep/utils.py
@@ -29,8 +29,6 @@ import sys
from oslo_log import log as logging
from oslo_utils import excutils
-import nova.privsep
-
# NOTE(mriedem): Avoid importing nova.utils since that can cause a circular
# import with the privsep code. In fact, avoid importing anything outside
# of nova/privsep/ if possible.
@@ -90,8 +88,3 @@ def supports_direct_io(dirpath):
pass
return hasDirectIO
-
-
-@nova.privsep.sys_admin_pctxt.entrypoint
-def kill(pid, signal):
- os.kill(pid, signal)
diff --git a/nova/test.py b/nova/test.py
index bb0010912e..9b7e1d7db3 100644
--- a/nova/test.py
+++ b/nova/test.py
@@ -48,16 +48,13 @@ from oslo_utils import timeutils
from oslo_versionedobjects import fixture as ovo_fixture
from oslotest import base
from oslotest import mock_fixture
-from oslotest import moxstubout
import six
from six.moves import builtins
import testtools
from nova.compute import rpcapi as compute_rpcapi
from nova import context
-from nova.db import api as db
from nova import exception
-from nova.network import manager as network_manager
from nova.network.security_group import openstack_driver
from nova import objects
from nova.objects import base as objects_base
@@ -89,36 +86,6 @@ CELL1_NAME = 'cell1'
nested = utils.nested_contexts
-class SampleNetworks(fixtures.Fixture):
-
- """Create sample networks in the database."""
-
- def __init__(self, host=None):
- self.host = host
-
- def setUp(self):
- super(SampleNetworks, self).setUp()
- ctxt = context.get_admin_context()
- network = network_manager.VlanManager(host=self.host)
- bridge_interface = CONF.flat_interface or CONF.vlan_interface
- network.create_networks(ctxt,
- label='test',
- cidr='10.0.0.0/8',
- multi_host=CONF.multi_host,
- num_networks=CONF.num_networks,
- network_size=CONF.network_size,
- cidr_v6=CONF.fixed_range_v6,
- gateway=CONF.gateway,
- gateway_v6=CONF.gateway_v6,
- bridge=CONF.flat_network_bridge,
- bridge_interface=bridge_interface,
- vpn_start=CONF.vpn_start,
- vlan_start=CONF.vlan_start,
- dns1=CONF.flat_network_dns)
- for net in db.network_get_all(ctxt):
- network.set_network_host(ctxt, net)
-
-
class TestingException(Exception):
pass
@@ -257,28 +224,12 @@ class TestCase(base.BaseTestCase):
self.useFixture(ovo_fixture.StableObjectJsonFixture())
- # NOTE(mnaser): All calls to utils.is_neutron() are cached in
- # nova.utils._IS_NEUTRON. We set it to None to avoid any
- # caching of that value.
- utils._IS_NEUTRON = None
-
# Reset the global QEMU version flag.
images.QEMU_VERSION = None
# Reset the compute RPC API globals (mostly the _ROUTER).
compute_rpcapi.reset_globals()
- # TODO(takashin): Remove MoxStubout fixture
- # after removing tests which uses mox and are related to
- # nova-network in the following files.
- #
- # - nova/tests/unit/api/openstack/compute/test_floating_ips.py
- # - nova/tests/unit/api/openstack/compute/test_security_groups.py
- # - nova/tests/unit/fake_network.py
- # - nova/tests/unit/network/test_manager.py
- mox_fixture = self.useFixture(moxstubout.MoxStubout())
- self.mox = mox_fixture.mox
- self.stubs = mox_fixture.stubs
self.addCleanup(self._clear_attrs)
self.useFixture(fixtures.EnvironmentVariable('http_proxy'))
self.policy = self.useFixture(policy_fixture.PolicyFixture())
@@ -363,9 +314,6 @@ class TestCase(base.BaseTestCase):
Use the monkey patch fixture to replace a function for the
duration of a test. Useful when you want to provide fake
methods instead of mocks during testing.
-
- This should be used instead of self.stubs.Set (which is based
- on mox) going forward.
"""
self.useFixture(fixtures.MonkeyPatch(old, new))
@@ -747,12 +695,9 @@ class BaseHookTestCase(NoDBTestCase):
class MatchType(object):
"""Matches any instance of a specified type
- The MatchType class is a helper for use with the
- mock.assert_called_with() method that lets you
- assert that a particular parameter has a specific
- data type. It enables strict check than the built
- in mock.ANY helper, and is the equivalent of the
- mox.IsA() function from the legacy mox library
+ The MatchType class is a helper for use with the mock.assert_called_with()
+ method that lets you assert that a particular parameter has a specific data
+ type. It enables stricter checking than the built in mock.ANY helper.
Example usage could be:
@@ -794,11 +739,9 @@ class MatchObjPrims(object):
class ContainKeyValue(object):
"""Checks whether a key/value pair is in a dict parameter.
- The ContainKeyValue class is a helper for use with the
- mock.assert_*() method that lets you assert that a particular
- dict contain a key/value pair. It enables strict check than
- the built in mock.ANY helper, and is the equivalent of the
- mox.ContainsKeyValue() function from the legacy mox library
+ The ContainKeyValue class is a helper for use with the mock.assert_*()
+ method that lets you assert that a particular dict contain a key/value
+ pair. It enables stricter checking than the built in mock.ANY helper.
Example usage could be:
diff --git a/nova/tests/fixtures.py b/nova/tests/fixtures.py
index 86cfbbd17f..dd4e5c5c8a 100644
--- a/nova/tests/fixtures.py
+++ b/nova/tests/fixtures.py
@@ -96,11 +96,6 @@ class ServiceFixture(fixtures.Fixture):
if self.cell:
context.set_target_cell(self.ctxt, self.cell)
- # NOTE(mikal): we don't have root to manipulate iptables, so just
- # zero that bit out.
- self.useFixture(fixtures.MockPatch(
- 'nova.network.linux_net.IptablesManager._apply'))
-
with mock.patch('nova.context.get_admin_context',
return_value=self.ctxt):
self.service = service.Service.create(**self.kwargs)
@@ -791,18 +786,6 @@ class WarningsFixture(fixtures.Fixture):
message='Policy enforcement is depending on the value of is_admin.'
' This key is deprecated. Please update your policy '
'file to use the standard policy values.')
- # TODO(takashin): Remove filtering warnings about mox
- # after removing tests which uses mox and are related to
- # nova-network in the following files.
- #
- # - nova/tests/unit/api/openstack/compute/test_floating_ips.py
- # - nova/tests/unit/api/openstack/compute/test_security_groups.py
- # - nova/tests/unit/fake_network.py
- # - nova/tests/unit/network/test_manager.py
- warnings.filterwarnings('ignore',
- module='mox3.mox')
- # NOTE(gibi): we can remove this once we get rid of Mox in nova
- warnings.filterwarnings('ignore', message="Using class 'MoxStubout'")
# NOTE(mriedem): Ignore scope check UserWarnings from oslo.policy.
warnings.filterwarnings('ignore',
message="Policy .* failed scope check",
@@ -990,12 +973,6 @@ class OSMetadataServer(fixtures.Fixture):
}
self.useFixture(ConfPatcher(**conf_overrides))
- # NOTE(mikal): we don't have root to manipulate iptables, so just
- # zero that bit out.
- self.useFixture(fixtures.MonkeyPatch(
- 'nova.network.linux_net.IptablesManager._apply',
- lambda _: None))
-
self.metadata = service.WSGIService("metadata")
self.metadata.start()
self.addCleanup(self.metadata.stop)
diff --git a/nova/tests/unit/README.rst b/nova/tests/unit/README.rst
deleted file mode 100644
index 8ac999c740..0000000000
--- a/nova/tests/unit/README.rst
+++ /dev/null
@@ -1,95 +0,0 @@
-=====================================
-OpenStack Nova Testing Infrastructure
-=====================================
-
-This README file attempts to provide current and prospective contributors with
-everything they need to know in order to start creating unit tests for nova.
-
-Note: the content for the rest of this file will be added as the work items in
-the following blueprint are completed:
- https://blueprints.launchpad.net/nova/+spec/consolidate-testing-infrastructure
-
-
-Test Types: Unit vs. Functional vs. Integration
------------------------------------------------
-
-TBD
-
-Writing Unit Tests
-------------------
-
-TBD
-
-Using Fakes
-~~~~~~~~~~~
-
-TBD
-
-test.TestCase
--------------
-The TestCase class from nova.test (generally imported as test) will
-automatically manage self.stubs using the stubout module and self.mox
-using the mox module during the setUp step. They will automatically
-verify and clean up during the tearDown step.
-
-If using test.TestCase, calling the super class setUp is required and
-calling the super class tearDown is required to be last if tearDown
-is overridden.
-
-Writing Functional Tests
-------------------------
-
-TBD
-
-Writing Integration Tests
--------------------------
-
-TBD
-
-Tests and Exceptions
---------------------
-A properly written test asserts that particular behavior occurs. This can
-be a success condition or a failure condition, including an exception.
-When asserting that a particular exception is raised, the most specific
-exception possible should be used.
-
-In particular, testing for Exception being raised is almost always a
-mistake since it will match (almost) every exception, even those
-unrelated to the exception intended to be tested.
-
-This applies to catching exceptions manually with a try/except block,
-or using assertRaises().
-
-Example::
-
- self.assertRaises(exception.InstanceNotFound, db.instance_get_by_uuid,
- elevated, instance_uuid)
-
-If a stubbed function/method needs a generic exception for testing
-purposes, test.TestingException is available.
-
-Example::
-
- def stubbed_method(self):
- raise test.TestingException()
- self.stubs.Set(cls, 'inner_method', stubbed_method)
-
- obj = cls()
- self.assertRaises(test.TestingException, obj.outer_method)
-
-
-Stubbing and Mocking
---------------------
-
-Whenever possible, tests SHOULD NOT stub and mock out the same function.
-
-If it's unavoidable, tests SHOULD define stubs before mocks since the
-`TestCase` cleanup routine will un-mock before un-stubbing. Doing otherwise
-results in a test that leaks stubbed functions, causing hard-to-debug
-interference between tests [1]_.
-
-If a mock must take place before a stub, any stubs after the mock call MUST be
-manually unset using `self.cleanUp` calls within the test.
-
-
-.. [1] https://bugs.launchpad.net/nova/+bug/1180671
diff --git a/nova/tests/unit/api/openstack/compute/test_floating_ips.py b/nova/tests/unit/api/openstack/compute/test_floating_ips.py
index 869129ab90..751ad8b369 100644
--- a/nova/tests/unit/api/openstack/compute/test_floating_ips.py
+++ b/nova/tests/unit/api/openstack/compute/test_floating_ips.py
@@ -19,11 +19,7 @@ from oslo_utils.fixture import uuidsentinel as uuids
import webob
from nova.api.openstack.compute import floating_ips as fips_v21
-from nova import compute
-from nova import context
-from nova.db import api as db
from nova import exception
-from nova import network
from nova import objects
from nova import test
from nova.tests.unit.api.openstack import fakes
@@ -195,94 +191,6 @@ class FloatingIpTestV21(test.NoDBTestCase):
expected_exc)
-class ExtendedFloatingIpTestV21(test.TestCase):
- floating_ip = "10.10.10.10"
- floating_ip_2 = "10.10.10.11"
- floating_ips = fips_v21
-
- def _create_floating_ips(self, floating_ips=None):
- """Create a floating IP object."""
- if floating_ips is None:
- floating_ips = [self.floating_ip]
- elif not isinstance(floating_ips, (list, tuple)):
- floating_ips = [floating_ips]
-
- dict_ = {'pool': 'nova', 'host': 'fake_host'}
- return db.floating_ip_bulk_create(
- self.context, [dict(address=ip, **dict_) for ip in floating_ips],
- )
-
- def _delete_floating_ip(self):
- db.floating_ip_destroy(self.context, self.floating_ip)
-
- def setUp(self):
- super(ExtendedFloatingIpTestV21, self).setUp()
- self.stubs.Set(compute.api.API, "get",
- compute_api_get)
- self.stubs.Set(network.api.API, "get_floating_ip",
- network_api_get_floating_ip)
- self.stubs.Set(network.api.API, "get_floating_ip_by_address",
- network_api_get_floating_ip_by_address)
- self.stubs.Set(network.api.API, "get_floating_ips_by_project",
- network_api_get_floating_ips_by_project)
- self.stubs.Set(network.api.API, "release_floating_ip",
- network_api_release)
- self.stubs.Set(network.api.API, "disassociate_floating_ip",
- network_api_disassociate)
- self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
- get_instance_by_floating_ip_addr)
- self.stubs.Set(objects.Instance, "get_network_info",
- stub_nw_info(self))
-
- fake_network.stub_out_nw_api_get_instance_nw_info(self)
- self.stub_out('nova.db.api.instance_get',
- fake_instance_get)
-
- self.context = context.get_admin_context()
- self._create_floating_ips()
-
- self.controller = self.floating_ips.FloatingIPController()
- self.manager = self.floating_ips.\
- FloatingIPActionController()
- self.fake_req = fakes.HTTPRequest.blank('')
-
- def tearDown(self):
- self._delete_floating_ip()
- super(ExtendedFloatingIpTestV21, self).tearDown()
-
- def test_extended_floating_ip_associate_fixed(self):
- fixed_address = '192.168.1.100'
-
- def fake_associate_floating_ip(*args, **kwargs):
- self.assertEqual(fixed_address, kwargs['fixed_address'])
-
- body = dict(addFloatingIp=dict(address=self.floating_ip,
- fixed_address=fixed_address))
-
- with mock.patch.object(self.manager.network_api,
- 'associate_floating_ip',
- fake_associate_floating_ip):
- rsp = self.manager._add_floating_ip(self.fake_req, TEST_INST,
- body=body)
- self.assertEqual(202, rsp.status_int)
-
- def test_extended_floating_ip_associate_fixed_not_allocated(self):
- def fake_associate_floating_ip(*args, **kwargs):
- pass
-
- self.stubs.Set(network.api.API, "associate_floating_ip",
- fake_associate_floating_ip)
- body = dict(addFloatingIp=dict(address=self.floating_ip,
- fixed_address='11.11.11.11'))
-
- ex = self.assertRaises(webob.exc.HTTPBadRequest,
- self.manager._add_floating_ip,
- self.fake_req, TEST_INST, body=body)
-
- self.assertIn("Specified fixed address not assigned to instance",
- ex.explanation)
-
-
class FloatingIPPolicyEnforcementV21(test.NoDBTestCase):
def setUp(self):
diff --git a/nova/tests/unit/conf_fixture.py b/nova/tests/unit/conf_fixture.py
index 6f601fe1af..b02d73b39e 100644
--- a/nova/tests/unit/conf_fixture.py
+++ b/nova/tests/unit/conf_fixture.py
@@ -20,8 +20,6 @@ from oslo_policy import opts as policy_opts
from nova.conf import neutron
from nova.conf import paths
from nova import config
-from nova import ipv6
-from nova.tests.unit import utils
class ConfFixture(config_fixture.Config):
@@ -31,19 +29,8 @@ class ConfFixture(config_fixture.Config):
# default group
self.conf.set_default('compute_driver', 'fake.SmallFakeDriver')
- self.conf.set_default('fake_network', True)
- self.conf.set_default('flat_network_bridge', 'br100')
- self.conf.set_default('floating_ip_dns_manager',
- 'nova.tests.unit.utils.dns_manager')
- self.conf.set_default('force_dhcp_release', False)
self.conf.set_default('host', 'fake-mini')
- self.conf.set_default('instance_dns_manager',
- 'nova.tests.unit.utils.dns_manager')
- self.conf.set_default('network_size', 8)
- self.conf.set_default('num_networks', 2)
self.conf.set_default('periodic_enable', False)
- self.conf.set_default('use_ipv6', True)
- self.conf.set_default('vlan_interface', 'eth0')
# api_database group
self.conf.set_default('connection', "sqlite://", group='api_database')
@@ -77,5 +64,3 @@ class ConfFixture(config_fixture.Config):
init_rpc=False)
policy_opts.set_defaults(self.conf)
neutron.register_dynamic_opts(self.conf)
- self.addCleanup(utils.cleanup_dns_managers)
- self.addCleanup(ipv6.api.reset_backend)
diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py
index db41157e1e..c05014c35e 100644
--- a/nova/tests/unit/db/test_db_api.py
+++ b/nova/tests/unit/db/test_db_api.py
@@ -7854,44 +7854,6 @@ class CertificateTestCase(test.TestCase, ModelsObjectComparatorMixin):
self._assertEqualObjects(self.created[1], cert[0])
-class DnsdomainTestCase(test.TestCase):
-
- def setUp(self):
- super(DnsdomainTestCase, self).setUp()
- self.ctxt = context.get_admin_context()
- self.domain = 'test.domain'
- self.testzone = 'testzone'
- self.project = 'fake'
-
- def test_dnsdomain_register_for_zone(self):
- db.dnsdomain_register_for_zone(self.ctxt, self.domain, self.testzone)
- domain = db.dnsdomain_get(self.ctxt, self.domain)
- self.assertEqual(domain['domain'], self.domain)
- self.assertEqual(domain['availability_zone'], self.testzone)
- self.assertEqual(domain['scope'], 'private')
-
- def test_dnsdomain_register_for_project(self):
- db.dnsdomain_register_for_project(self.ctxt, self.domain, self.project)
- domain = db.dnsdomain_get(self.ctxt, self.domain)
- self.assertEqual(domain['domain'], self.domain)
- self.assertEqual(domain['project_id'], self.project)
- self.assertEqual(domain['scope'], 'public')
-
- def test_dnsdomain_unregister(self):
- db.dnsdomain_register_for_zone(self.ctxt, self.domain, self.testzone)
- db.dnsdomain_unregister(self.ctxt, self.domain)
- domain = db.dnsdomain_get(self.ctxt, self.domain)
- self.assertIsNone(domain)
-
- def test_dnsdomain_get_all(self):
- d_list = ['test.domain.one', 'test.domain.two']
- db.dnsdomain_register_for_zone(self.ctxt, d_list[0], 'zone')
- db.dnsdomain_register_for_zone(self.ctxt, d_list[1], 'zone')
- db_list = db.dnsdomain_get_all(self.ctxt)
- db_domain_list = [d.domain for d in db_list]
- self.assertEqual(sorted(d_list), sorted(db_domain_list))
-
-
class BwUsageTestCase(test.TestCase, ModelsObjectComparatorMixin):
_ignored_keys = ['id', 'deleted', 'deleted_at', 'created_at', 'updated_at']
@@ -8189,9 +8151,6 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.instance_id_mappings = models.InstanceIdMapping.__table__
self.shadow_instance_id_mappings = sqlalchemyutils.get_table(
self.engine, "shadow_instance_id_mappings")
- self.dns_domains = models.DNSDomain.__table__
- self.shadow_dns_domains = sqlalchemyutils.get_table(
- self.engine, "shadow_dns_domains")
self.instances = models.Instance.__table__
self.shadow_instances = sqlalchemyutils.get_table(
self.engine, "shadow_instances")
@@ -8473,31 +8432,6 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.assertEqual(len(rows), 4)
return 0
- def test_archive_deleted_rows_no_id_column(self):
- uuidstr0 = self.uuidstrs[0]
- ins_stmt = self.dns_domains.insert().values(domain=uuidstr0)
- self.conn.execute(ins_stmt)
- update_statement = self.dns_domains.update().\
- where(self.dns_domains.c.domain == uuidstr0).\
- values(deleted=True, deleted_at=timeutils.utcnow())
- self.conn.execute(update_statement)
- qdd = sql.select([self.dns_domains], self.dns_domains.c.domain ==
- uuidstr0)
- rows = self.conn.execute(qdd).fetchall()
- self.assertEqual(len(rows), 1)
- qsdd = sql.select([self.shadow_dns_domains],
- self.shadow_dns_domains.c.domain == uuidstr0)
- rows = self.conn.execute(qsdd).fetchall()
- self.assertEqual(len(rows), 0)
- db.archive_deleted_rows(max_rows=1)
- rows = self.conn.execute(qdd).fetchall()
- self.assertEqual(len(rows), 0)
- rows = self.conn.execute(qsdd).fetchall()
- self.assertEqual(len(rows), 1)
- self._assert_shadow_tables_empty_except(
- 'shadow_dns_domains',
- )
-
def test_archive_deleted_rows_shadow_insertions_equals_deletions(self):
# Add 2 rows to table
for uuidstr in self.uuidstrs[:2]:
diff --git a/nova/tests/unit/fake_network.py b/nova/tests/unit/fake_network.py
index 62ad95e0b9..9725b52cac 100644
--- a/nova/tests/unit/fake_network.py
+++ b/nova/tests/unit/fake_network.py
@@ -15,267 +15,16 @@
from oslo_serialization import jsonutils
from oslo_utils.fixture import uuidsentinel as uuids
-from six.moves import range
-from nova.compute import api as compute_api
from nova.compute import manager as compute_manager
-import nova.conf
-import nova.context
from nova.db import api as db
-from nova import exception
-from nova.network import manager as network_manager
from nova.network import model as network_model
-from nova.network import rpcapi as network_rpcapi
from nova import objects
from nova.objects import base as obj_base
-from nova.objects import network as network_obj
-from nova.objects import virtual_interface as vif_obj
-from nova.tests.unit.objects import test_fixed_ip
from nova.tests.unit.objects import test_instance_info_cache
-from nova.tests.unit.objects import test_pci_device
from nova.tests.unit import utils
-HOST = "testhost"
-CONF = nova.conf.CONF
-
-
-class FakeModel(dict):
- """Represent a model from the db."""
- def __init__(self, *args, **kwargs):
- self.update(kwargs)
-
-
-class FakeNetworkManager(network_manager.NetworkManager):
- """This NetworkManager doesn't call the base class so we can bypass all
- inherited service cruft and just perform unit tests.
- """
-
- class FakeDB(object):
- vifs = [{'id': 0,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'instance_uuid': uuids.instance_1,
- 'network_id': 1,
- 'uuid': uuids.vifs_1,
- 'address': 'DC:AD:BE:FF:EF:01',
- 'tag': 'fake-tag1'},
- {'id': 1,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'instance_uuid': uuids.instance_2,
- 'network_id': 21,
- 'uuid': uuids.vifs_2,
- 'address': 'DC:AD:BE:FF:EF:02',
- 'tag': 'fake-tag2'},
- {'id': 2,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'instance_uuid': uuids.instance_1,
- 'network_id': 31,
- 'uuid': uuids.vifs_3,
- 'address': 'DC:AD:BE:FF:EF:03',
- 'tag': None}]
-
- floating_ips = [dict(address='172.16.1.1',
- fixed_ip_id=100),
- dict(address='172.16.1.2',
- fixed_ip_id=200),
- dict(address='173.16.1.2',
- fixed_ip_id=210)]
-
- fixed_ips = [dict(test_fixed_ip.fake_fixed_ip,
- id=100,
- address='172.16.0.1',
- virtual_interface_id=0),
- dict(test_fixed_ip.fake_fixed_ip,
- id=200,
- address='172.16.0.2',
- virtual_interface_id=1),
- dict(test_fixed_ip.fake_fixed_ip,
- id=210,
- address='173.16.0.2',
- virtual_interface_id=2)]
-
- def fixed_ip_get_by_instance(self, context, instance_uuid):
- return [dict(address='10.0.0.0'), dict(address='10.0.0.1'),
- dict(address='10.0.0.2')]
-
- def network_get_by_cidr(self, context, cidr):
- raise exception.NetworkNotFoundForCidr(cidr=cidr)
-
- def network_create_safe(self, context, net):
- fakenet = dict(net)
- fakenet['id'] = 999
- return fakenet
-
- def network_get(self, context, network_id, project_only="allow_none"):
- return {'cidr_v6': '2001:db8:69:%x::/64' % network_id}
-
- def network_get_by_uuid(self, context, network_uuid):
- raise exception.NetworkNotFoundForUUID(uuid=network_uuid)
-
- def network_get_all(self, context):
- raise exception.NoNetworksFound()
-
- def network_get_all_by_uuids(self, context, project_only="allow_none"):
- raise exception.NoNetworksFound()
-
- def network_disassociate(self, context, network_id):
- return True
-
- def virtual_interface_get_all(self, context):
- return self.vifs
-
- def fixed_ips_by_virtual_interface(self, context, vif_id):
- return [ip for ip in self.fixed_ips
- if ip['virtual_interface_id'] == vif_id]
-
- def fixed_ip_disassociate(self, context, address):
- return True
-
- def __init__(self, stubs=None):
- self.db = self.FakeDB()
- if stubs:
- stubs.Set(vif_obj, 'db', self.db)
- self.deallocate_called = None
- self.deallocate_fixed_ip_calls = []
- self.network_rpcapi = network_rpcapi.NetworkAPI()
-
- # TODO(matelakat) method signature should align with the faked one's
- def deallocate_fixed_ip(self, context, address=None, host=None,
- instance=None):
- self.deallocate_fixed_ip_calls.append((context, address, host))
- # TODO(matelakat) use the deallocate_fixed_ip_calls instead
- self.deallocate_called = address
-
- def _create_fixed_ips(self, context, network_id, fixed_cidr=None,
- extra_reserved=None, bottom_reserved=0,
- top_reserved=0):
- pass
-
- def get_instance_nw_info(context, instance_id, rxtx_factor,
- host, instance_uuid=None, **kwargs):
- pass
-
-
-def fake_network(network_id, ipv6=None):
- if ipv6 is None:
- ipv6 = CONF.use_ipv6
- fake_network = {'id': network_id,
- 'uuid': getattr(uuids, 'network%i' % network_id),
- 'label': 'test%d' % network_id,
- 'injected': False,
- 'multi_host': False,
- 'cidr': '192.168.%d.0/24' % network_id,
- 'cidr_v6': None,
- 'netmask': '255.255.255.0',
- 'netmask_v6': None,
- 'bridge': 'fake_br%d' % network_id,
- 'bridge_interface': 'fake_eth%d' % network_id,
- 'gateway': '192.168.%d.1' % network_id,
- 'gateway_v6': None,
- 'broadcast': '192.168.%d.255' % network_id,
- 'dns1': '192.168.%d.3' % network_id,
- 'dns2': '192.168.%d.4' % network_id,
- 'dns3': '192.168.%d.3' % network_id,
- 'vlan': None,
- 'host': None,
- 'project_id': uuids.project,
- 'vpn_public_address': '192.168.%d.2' % network_id,
- 'vpn_public_port': None,
- 'vpn_private_address': None,
- 'dhcp_start': None,
- 'rxtx_base': network_id * 10,
- 'priority': None,
- 'deleted': False,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'mtu': None,
- 'dhcp_server': '192.168.%d.1' % network_id,
- 'enable_dhcp': True,
- 'share_address': False}
- if ipv6:
- fake_network['cidr_v6'] = '2001:db8:0:%x::/64' % network_id
- fake_network['gateway_v6'] = '2001:db8:0:%x::1' % network_id
- fake_network['netmask_v6'] = '64'
- if CONF.flat_injected:
- fake_network['injected'] = True
-
- return fake_network
-
-
-def fake_network_obj(context, network_id=1, ipv6=None):
- return network_obj.Network._from_db_object(
- context, network_obj.Network(), fake_network(network_id, ipv6))
-
-
-def fake_vif(x):
- return {'id': x,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:%02x' % x,
- 'uuid': getattr(uuids, 'vif%i' % x),
- 'network_id': x,
- 'instance_uuid': uuids.vifs_1,
- 'tag': 'fake-tag'}
-
-
-def floating_ip_ids():
- for i in range(1, 100):
- yield i
-
-
-def fixed_ip_ids():
- for i in range(1, 100):
- yield i
-
-
-floating_ip_id = floating_ip_ids()
-fixed_ip_id = fixed_ip_ids()
-
-
-def next_fixed_ip(network_id, num_floating_ips=0):
- next_id = next(fixed_ip_id)
- f_ips = [FakeModel(**next_floating_ip(next_id))
- for i in range(num_floating_ips)]
- return {'id': next_id,
- 'network_id': network_id,
- 'address': '192.168.%d.%03d' % (network_id, (next_id + 99)),
- 'instance_uuid': uuids.fixed_ip,
- 'allocated': False,
- 'reserved': False,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'leased': True,
- 'host': HOST,
- 'deleted': 0,
- 'network': fake_network(network_id),
- 'virtual_interface': fake_vif(network_id),
- # and since network_id and vif_id happen to be equivalent
- 'virtual_interface_id': network_id,
- 'floating_ips': f_ips}
-
-
-def next_floating_ip(fixed_ip_id):
- next_id = next(floating_ip_id)
- return {'id': next_id,
- 'address': '10.10.10.%03d' % (next_id + 99),
- 'fixed_ip_id': fixed_ip_id,
- 'project_id': None,
- 'auto_assigned': False}
-
-
def fake_get_instance_nw_info(test, num_networks=1):
def update_cache_fake(*args, **kwargs):
@@ -380,16 +129,6 @@ def fake_get_instance_nw_info(test, num_networks=1):
return nw_model
-def stub_out_nw_api_get_instance_nw_info(test, func=None):
-
- def get_instance_nw_info(self, context, instance, conductor_api=None):
- return fake_get_instance_nw_info(test)
-
- if func is None:
- func = get_instance_nw_info
- test.stub_out('nova.network.api.API.get_instance_nw_info', func)
-
-
_real_functions = {}
@@ -421,30 +160,6 @@ def unset_stub_network_methods(test):
_real_functions[name])
-def stub_compute_with_ips(test):
- orig_get = compute_api.API.get
- orig_get_all = compute_api.API.get_all
- orig_create = compute_api.API.create
-
- def fake_get(*args, **kwargs):
- return _get_instances_with_cached_ips(orig_get, *args, **kwargs)
-
- def fake_get_all(*args, **kwargs):
- return _get_instances_with_cached_ips(orig_get_all, *args, **kwargs)
-
- def fake_create(*args, **kwargs):
- return _create_instances_with_cached_ips(orig_create, *args, **kwargs)
-
- def fake_pci_device_get_by_addr(context, node_id, dev_addr):
- return test_pci_device.fake_db_dev
-
- test.stub_out('nova.db.api.pci_device_get_by_addr',
- fake_pci_device_get_by_addr)
- test.stub_out('nova.compute.api.API.get', fake_get)
- test.stub_out('nova.compute.api.API.get_all', fake_get_all)
- test.stub_out('nova.compute.api.API.create', fake_create)
-
-
def _get_fake_cache():
def _ip(ip, fixed=True, floats=None):
ip_dict = {'address': ip, 'type': 'fixed'}
@@ -461,10 +176,9 @@ def _get_fake_cache():
'label': 'private',
'subnets': [{'cidr': '192.168.0.0/24',
'ips': [_ip('192.168.0.3')]}]}}]
- if CONF.use_ipv6:
- ipv6_addr = 'fe80:b33f::a8bb:ccff:fedd:eeff'
- info[0]['network']['subnets'].append({'cidr': 'fe80:b33f::/64',
- 'ips': [_ip(ipv6_addr)]})
+ ipv6_addr = 'fe80:b33f::a8bb:ccff:fedd:eeff'
+ info[0]['network']['subnets'].append({'cidr': 'fe80:b33f::/64',
+ 'ips': [_ip(ipv6_addr)]})
return jsonutils.dumps(info)
@@ -509,4 +223,4 @@ def _create_instances_with_cached_ips(orig_func, *args, **kwargs):
instance['info_cache'].network_info = fake_cache
db.instance_info_cache_update(args[1], instance['uuid'],
{'network_info': fake_cache})
- return (instances, reservation_id)
+ return instances, reservation_id
diff --git a/nova/tests/unit/network/test_api.py b/nova/tests/unit/network/test_api.py
deleted file mode 100644
index 428a0aebf5..0000000000
--- a/nova/tests/unit/network/test_api.py
+++ /dev/null
@@ -1,570 +0,0 @@
-# Copyright 2012 Red Hat, Inc.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Tests for network API."""
-
-import copy
-
-import mock
-from oslo_utils.fixture import uuidsentinel as uuids
-from oslo_utils import uuidutils
-
-from nova import context
-from nova import exception
-from nova import network
-from nova.network import api
-from nova.network import base_api
-from nova.network import floating_ips
-from nova.network import model as network_model
-from nova import objects
-from nova.objects import fields
-from nova.objects import network_request as net_req_obj
-from nova import test
-from nova.tests.unit.api.openstack import fakes
-from nova.tests.unit import fake_instance
-from nova.tests.unit.objects import test_fixed_ip
-from nova.tests.unit.objects import test_virtual_interface
-
-
-FAKE_UUID = 'a47ae74e-ab08-547f-9eee-ffd23fc46c16'
-
-fake_info_cache = {
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': False,
- 'instance_uuid': uuids.instance,
- 'network_info': '[]',
- }
-
-
-class ApiTestCase(test.TestCase):
- def setUp(self):
- super(ApiTestCase, self).setUp()
- self.flags(use_neutron=False)
- self.network_api = network.API()
- self.context = context.RequestContext('fake-user',
- fakes.FAKE_PROJECT_ID)
-
- @mock.patch('nova.objects.NetworkList.get_all')
- def test_get_all(self, mock_get_all):
- mock_get_all.return_value = mock.sentinel.get_all
- self.assertEqual(mock.sentinel.get_all,
- self.network_api.get_all(self.context))
- mock_get_all.assert_called_once_with(self.context,
- project_only=True)
-
- @mock.patch('nova.objects.NetworkList.get_all')
- def test_get_all_liberal(self, mock_get_all):
- self.flags(network_manager='nova.network.manager.FlatDHCPManager')
- mock_get_all.return_value = mock.sentinel.get_all
- self.assertEqual(mock.sentinel.get_all,
- self.network_api.get_all(self.context))
- mock_get_all.assert_called_once_with(self.context,
- project_only="allow_none")
-
- @mock.patch('nova.objects.NetworkList.get_all')
- def test_get_all_no_networks(self, mock_get_all):
- mock_get_all.side_effect = exception.NoNetworksFound
- self.assertEqual([], self.network_api.get_all(self.context))
- mock_get_all.assert_called_once_with(self.context,
- project_only=True)
-
- @mock.patch('nova.objects.Network.get_by_uuid')
- def test_get(self, mock_get):
- mock_get.return_value = mock.sentinel.get_by_uuid
- self.assertEqual(mock.sentinel.get_by_uuid,
- self.network_api.get(self.context, uuids.instance))
-
- @mock.patch('nova.objects.Network.get_by_id')
- @mock.patch('nova.db.api.virtual_interface_get_by_instance')
- def test_get_vifs_by_instance(self, mock_get_by_instance,
- mock_get_by_id):
- mock_get_by_instance.return_value = [
- dict(test_virtual_interface.fake_vif,
- network_id=123)]
- mock_get_by_id.return_value = objects.Network()
- mock_get_by_id.return_value.uuid = uuids.network_1
- instance = objects.Instance(uuid=uuids.instance)
- vifs = self.network_api.get_vifs_by_instance(self.context,
- instance)
- self.assertEqual(1, len(vifs))
- self.assertEqual(123, vifs[0].network_id)
- self.assertEqual(uuids.network_1, vifs[0].net_uuid)
- mock_get_by_instance.assert_called_once_with(
- self.context, uuids.instance)
- mock_get_by_id.assert_called_once_with(self.context, 123,
- project_only='allow_none')
-
- @mock.patch('nova.objects.Network.get_by_id')
- @mock.patch('nova.db.api.virtual_interface_get_by_address')
- def test_get_vif_by_mac_address(self, mock_get_by_address,
- mock_get_by_id):
- mock_get_by_address.return_value = dict(
- test_virtual_interface.fake_vif, network_id=123)
- mock_get_by_id.return_value = objects.Network(
- uuid=uuids.network_1)
- vif = self.network_api.get_vif_by_mac_address(self.context,
- mock.sentinel.mac)
- self.assertEqual(123, vif.network_id)
- self.assertEqual(uuids.network_1, vif.net_uuid)
- mock_get_by_address.assert_called_once_with(self.context,
- mock.sentinel.mac)
- mock_get_by_id.assert_called_once_with(self.context, 123,
- project_only='allow_none')
-
- def _do_test_associate_floating_ip(self, orig_instance_uuid):
- """Test post-association logic."""
-
- new_instance = objects.Instance(uuid=FAKE_UUID)
-
- def fake_associate(*args, **kwargs):
- return orig_instance_uuid
-
- def fake_instance_get_by_uuid(context, instance_uuid,
- columns_to_join=None,
- use_slave=None):
- if instance_uuid == orig_instance_uuid:
- self.assertIn('extra.flavor', columns_to_join)
- return fake_instance.fake_db_instance(uuid=instance_uuid)
-
- def fake_get_nw_info(ctxt, instance):
- class FakeNWInfo(object):
- def json(self):
- pass
- return FakeNWInfo()
-
- if orig_instance_uuid:
- expected_updated_instances = [new_instance.uuid,
- orig_instance_uuid]
- else:
- expected_updated_instances = [new_instance.uuid]
-
- def fake_instance_info_cache_update(context, instance_uuid, cache):
- self.assertEqual(instance_uuid,
- expected_updated_instances.pop())
- return fake_info_cache
-
- def fake_update_instance_cache_with_nw_info(api, context, instance,
- nw_info=None):
- return
-
- with test.nested(
- mock.patch.object(floating_ips.FloatingIP, 'associate_floating_ip',
- fake_associate),
- mock.patch.object(self.network_api.db, 'instance_get_by_uuid',
- fake_instance_get_by_uuid),
- mock.patch.object(self.network_api, '_get_instance_nw_info',
- fake_get_nw_info),
- mock.patch.object(self.network_api.db,
- 'instance_info_cache_update',
- fake_instance_info_cache_update),
- mock.patch.object(base_api, "update_instance_cache_with_nw_info",
- fake_update_instance_cache_with_nw_info)
- ):
- self.network_api.associate_floating_ip(self.context,
- new_instance,
- '172.24.4.225',
- '10.0.0.2')
-
- def test_associate_preassociated_floating_ip(self):
- self._do_test_associate_floating_ip(uuids.orig_uuid)
-
- def test_associate_unassociated_floating_ip(self):
- self._do_test_associate_floating_ip(None)
-
- def test_get_floating_ip_invalid_id(self):
- self.assertRaises(exception.InvalidID,
- self.network_api.get_floating_ip,
- self.context, '123zzz')
-
- @mock.patch('nova.objects.FloatingIP.get_by_id')
- def test_get_floating_ip(self, mock_get):
- floating = mock.sentinel.floating
- mock_get.return_value = floating
- self.assertEqual(floating,
- self.network_api.get_floating_ip(self.context, 123))
- mock_get.assert_called_once_with(self.context, 123)
-
- @mock.patch('nova.objects.FloatingIP.get_pool_names')
- def test_get_floating_ip_pools(self, mock_get):
- pools = ['foo', 'bar']
- mock_get.return_value = pools
- self.assertEqual(pools,
- self.network_api.get_floating_ip_pools(
- self.context))
-
- @mock.patch('nova.objects.FloatingIP.get_by_address')
- def test_get_floating_ip_by_address(self, mock_get):
- floating = mock.sentinel.floating
- mock_get.return_value = floating
- self.assertEqual(floating,
- self.network_api.get_floating_ip_by_address(
- self.context, mock.sentinel.address))
- mock_get.assert_called_once_with(self.context,
- mock.sentinel.address)
-
- @mock.patch('nova.objects.FloatingIPList.get_by_project')
- def test_get_floating_ips_by_project(self, mock_get):
- floatings = mock.sentinel.floating_ips
- mock_get.return_value = floatings
- self.assertEqual(floatings,
- self.network_api.get_floating_ips_by_project(
- self.context))
- mock_get.assert_called_once_with(self.context,
- self.context.project_id)
-
- def _stub_migrate_instance_calls(self, method, multi_host, info):
- fake_flavor = objects.Flavor.get_by_name(self.context, 'm1.small')
- fake_flavor['rxtx_factor'] = 1.21
- fake_instance = objects.Instance(
- uuid=uuidutils.generate_uuid(dashed=False),
- project_id='fake_project_id',
- instance_type_id=fake_flavor['id'],
- flavor=fake_flavor,
- system_metadata={})
- fake_migration = objects.Migration(
- source_compute='fake_compute_source',
- dest_compute='fake_compute_dest')
-
- def fake_mig_inst_method(*args, **kwargs):
- info['kwargs'] = kwargs
-
- def fake_get_multi_addresses(*args, **kwargs):
- return multi_host, ['fake_float1', 'fake_float2']
-
- self.stub_out('nova.network.rpcapi.NetworkAPI.' + method,
- fake_mig_inst_method)
- self.stub_out('nova.network.api.API._get_multi_addresses',
- fake_get_multi_addresses)
-
- expected = {'instance_uuid': fake_instance.uuid,
- 'source_compute': 'fake_compute_source',
- 'dest_compute': 'fake_compute_dest',
- 'rxtx_factor': 1.21,
- 'project_id': 'fake_project_id',
- 'floating_addresses': None}
- if multi_host:
- expected['floating_addresses'] = ['fake_float1', 'fake_float2']
- return fake_instance, fake_migration, expected
-
- def test_migrate_instance_start_with_multihost(self):
- info = {'kwargs': {}}
- arg1, arg2, expected = self._stub_migrate_instance_calls(
- 'migrate_instance_start', True, info)
- expected['host'] = 'fake_compute_source'
- self.network_api.migrate_instance_start(self.context, arg1, arg2)
- self.assertEqual(info['kwargs'], expected)
-
- def test_migrate_instance_start_without_multihost(self):
- info = {'kwargs': {}}
- arg1, arg2, expected = self._stub_migrate_instance_calls(
- 'migrate_instance_start', False, info)
- self.network_api.migrate_instance_start(self.context, arg1, arg2)
- self.assertEqual(info['kwargs'], expected)
-
- def test_migrate_instance_finish_with_multihost(self):
- info = {'kwargs': {}}
- arg1, arg2, expected = self._stub_migrate_instance_calls(
- 'migrate_instance_finish', True, info)
- expected['host'] = 'fake_compute_dest'
- self.network_api.migrate_instance_finish(self.context, arg1, arg2, {})
- self.assertEqual(info['kwargs'], expected)
-
- def test_migrate_instance_finish_without_multihost(self):
- info = {'kwargs': {}}
- arg1, arg2, expected = self._stub_migrate_instance_calls(
- 'migrate_instance_finish', False, info)
- self.network_api.migrate_instance_finish(self.context, arg1, arg2, {})
- self.assertEqual(info['kwargs'], expected)
-
- def test_is_multi_host_instance_has_no_fixed_ip(self):
- with mock.patch.object(self.network_api.db, 'fixed_ip_get_by_instance',
- side_effect=exception.FixedIpNotFoundForInstance(
- instance_uuid=FAKE_UUID)):
- instance = objects.Instance(uuid=FAKE_UUID)
- result, floats = (
- self.network_api._get_multi_addresses(self.context, instance))
- self.assertFalse(result)
-
- @mock.patch('nova.objects.fixed_ip.FixedIPList.get_by_instance_uuid')
- def _test_is_multi_host_network_has_no_project_id(self, is_multi_host,
- fip_get):
- network = objects.Network(
- id=123, project_id=None,
- multi_host=is_multi_host)
- fip_get.return_value = [
- objects.FixedIP(instance_uuid=FAKE_UUID, network=network,
- floating_ips=objects.FloatingIPList())]
- instance = objects.Instance(uuid=FAKE_UUID)
- result, floats = self.network_api._get_multi_addresses(self.context,
- instance)
- self.assertEqual(is_multi_host, result)
-
- def test_is_multi_host_network_has_no_project_id_multi(self):
- self._test_is_multi_host_network_has_no_project_id(True)
-
- def test_is_multi_host_network_has_no_project_id_non_multi(self):
- self._test_is_multi_host_network_has_no_project_id(False)
-
- @mock.patch('nova.objects.fixed_ip.FixedIPList.get_by_instance_uuid')
- def _test_is_multi_host_network_has_project_id(self, is_multi_host,
- fip_get):
- network = objects.Network(
- id=123, project_id=self.context.project_id,
- multi_host=is_multi_host)
- fip_get.return_value = [
- objects.FixedIP(instance_uuid=FAKE_UUID, network=network,
- floating_ips=objects.FloatingIPList())]
- instance = objects.Instance(uuid=FAKE_UUID)
- result, floats = self.network_api._get_multi_addresses(self.context,
- instance)
- self.assertEqual(is_multi_host, result)
-
- def test_is_multi_host_network_has_project_id_multi(self):
- self._test_is_multi_host_network_has_project_id(True)
-
- def test_is_multi_host_network_has_project_id_non_multi(self):
- self._test_is_multi_host_network_has_project_id(False)
-
- def _test_refresh_cache(self, method, *args, **kwargs):
- # This test verifies that no call to get_instance_nw_info() is made
- # from the @refresh_cache decorator for the tested method.
- with test.nested(
- mock.patch.object(self.network_api.network_rpcapi, method),
- mock.patch.object(self.network_api.network_rpcapi,
- 'get_instance_nw_info'),
- mock.patch.object(network_model.NetworkInfo, 'hydrate'),
- mock.patch.object(objects.InstanceInfoCache, 'save'),
- ) as (
- method_mock, nwinfo_mock, hydrate_mock, save_mock
- ):
- nw_info = network_model.NetworkInfo([])
- method_mock.return_value = nw_info
- hydrate_mock.return_value = nw_info
- getattr(self.network_api, method)(*args, **kwargs)
- hydrate_mock.assert_called_once_with(nw_info)
- self.assertFalse(nwinfo_mock.called)
-
- def test_allocate_for_instance_refresh_cache(self):
- instance = fake_instance.fake_instance_obj(self.context)
- vpn = 'fake-vpn'
- requested_networks = [('fake-networks', None)]
- self._test_refresh_cache('allocate_for_instance', self.context,
- instance, vpn, requested_networks)
-
- @mock.patch('nova.network.rpcapi.NetworkAPI.allocate_for_instance')
- def test_allocate_for_instance_no_nets_no_auto(self, mock_rpc_alloc):
- # Tests that nothing fails if no networks are returned and auto
- # allocation wasn't requested.
- mock_rpc_alloc.return_value = []
- instance = fake_instance.fake_instance_obj(self.context)
- nw_info = self.network_api.allocate_for_instance(
- self.context, instance, mock.sentinel.vpn, requested_networks=None)
- self.assertEqual(0, len(nw_info))
-
- @mock.patch('nova.network.rpcapi.NetworkAPI.allocate_for_instance')
- def test_allocate_for_instance_no_nets_auto_allocate(self, mock_rpc_alloc):
- # Tests that we fail when no networks are allocated and auto-allocation
- # was requested.
-
- def fake_rpc_allocate(context, *args, **kwargs):
- # assert that requested_networks is nulled out
- self.assertIn('requested_networks', kwargs)
- self.assertIsNone(kwargs['requested_networks'])
- return []
-
- mock_rpc_alloc.side_effect = fake_rpc_allocate
- instance = fake_instance.fake_instance_obj(self.context)
- self.assertRaises(exception.UnableToAutoAllocateNetwork,
- self.network_api.allocate_for_instance,
- self.context, instance, mock.sentinel.vpn,
- [(net_req_obj.NETWORK_ID_AUTO, None)])
- self.assertEqual(1, mock_rpc_alloc.call_count)
-
- @mock.patch('nova.network.rpcapi.NetworkAPI.deallocate_for_instance')
- def test_deallocate_for_instance_auto_allocate(self, mock_rpc_dealloc):
- # Tests that we pass requested_networks=None to the RPC API when
- # we're auto-allocating.
- instance = fake_instance.fake_instance_obj(self.context)
- req_net = objects.NetworkRequest(
- network_id=net_req_obj.NETWORK_ID_AUTO)
- requested_networks = objects.NetworkRequestList(objects=[req_net])
- self.network_api.deallocate_for_instance(
- self.context, instance, requested_networks)
- mock_rpc_dealloc.assert_called_once_with(self.context,
- instance=instance,
- requested_networks=None)
-
- def test_add_fixed_ip_to_instance_refresh_cache(self):
- instance = fake_instance.fake_instance_obj(self.context)
- network_id = 'fake-network-id'
- self._test_refresh_cache('add_fixed_ip_to_instance', self.context,
- instance, network_id)
-
- def test_remove_fixed_ip_from_instance_refresh_cache(self):
- instance = fake_instance.fake_instance_obj(self.context)
- address = 'fake-address'
- self._test_refresh_cache('remove_fixed_ip_from_instance', self.context,
- instance, address)
-
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- def test_get_fixed_ip_by_address(self, fip_get):
- fip_get.return_value = test_fixed_ip.fake_fixed_ip
- fip = self.network_api.get_fixed_ip_by_address(self.context,
- 'fake-addr')
- self.assertIsInstance(fip, objects.FixedIP)
-
- @mock.patch('nova.objects.FixedIP.get_by_id')
- def test_get_fixed_ip(self, mock_get_by_id):
- mock_get_by_id.return_value = mock.sentinel.fixed_ip
- self.assertEqual(mock.sentinel.fixed_ip,
- self.network_api.get_fixed_ip(self.context,
- mock.sentinel.id))
- mock_get_by_id.assert_called_once_with(self.context, mock.sentinel.id)
-
- @mock.patch('nova.objects.FixedIP.get_by_floating_address')
- def test_get_instance_by_floating_address(self, mock_get_by_floating):
- mock_get_by_floating.return_value = objects.FixedIP(
- instance_uuid = uuids.instance)
- self.assertEqual(uuids.instance,
- self.network_api.get_instance_id_by_floating_address(
- self.context, mock.sentinel.floating))
- mock_get_by_floating.assert_called_once_with(self.context,
- mock.sentinel.floating)
-
- @mock.patch('nova.objects.FixedIP.get_by_floating_address')
- def test_get_instance_by_floating_address_none(self, mock_get_by_floating):
- mock_get_by_floating.return_value = None
- self.assertIsNone(
- self.network_api.get_instance_id_by_floating_address(
- self.context, mock.sentinel.floating))
- mock_get_by_floating.assert_called_once_with(self.context,
- mock.sentinel.floating)
-
- @mock.patch('nova.network.api.API.migrate_instance_start')
- def test_cleanup_instance_network_on_host(self, fake_migrate_start):
- instance = fake_instance.fake_instance_obj(self.context)
- self.network_api.cleanup_instance_network_on_host(
- self.context, instance, 'fake_compute_source')
- fake_migrate_start.assert_called_once_with(
- self.context, instance,
- {'source_compute': 'fake_compute_source', 'dest_compute': None})
-
- @mock.patch('nova.network.api.API.migrate_instance_finish')
- def test_setup_instance_network_on_host(self, fake_migrate_finish):
- instance = fake_instance.fake_instance_obj(self.context)
- self.network_api.setup_instance_network_on_host(
- self.context, instance, 'fake_compute_source')
- fake_migrate_finish.assert_called_once_with(
- self.context, instance,
- {'source_compute': None, 'dest_compute': 'fake_compute_source'},
- None)
-
- @mock.patch('oslo_concurrency.lockutils.lock')
- @mock.patch.object(api.API, '_get_instance_nw_info')
- @mock.patch('nova.network.base_api.update_instance_cache_with_nw_info')
- def test_get_instance_nw_info(self, mock_update, mock_get, mock_lock):
- fake_result = mock.sentinel.get_nw_info_result
- mock_get.return_value = fake_result
- instance = fake_instance.fake_instance_obj(self.context)
- result = self.network_api.get_instance_nw_info(self.context, instance)
- mock_get.assert_called_once_with(self.context, instance)
- mock_update.assert_called_once_with(self.network_api, self.context,
- instance, nw_info=fake_result)
- self.assertEqual(fake_result, result)
-
-
-@mock.patch('nova.network.api.API')
-@mock.patch('nova.db.api.instance_info_cache_update')
-class TestUpdateInstanceCache(test.NoDBTestCase):
- def setUp(self):
- super(TestUpdateInstanceCache, self).setUp()
- self.context = context.get_admin_context()
- self.instance = objects.Instance(uuid=FAKE_UUID, deleted=False)
- vifs = [network_model.VIF(id='super_vif')]
- self.nw_info = network_model.NetworkInfo(vifs)
- self.nw_json = fields.NetworkModel.to_primitive(self, 'network_info',
- self.nw_info)
-
- def test_update_nw_info_none(self, db_mock, api_mock):
- api_mock._get_instance_nw_info.return_value = self.nw_info
- info_cache = copy.deepcopy(fake_info_cache)
- info_cache.update({'network_info': self.nw_json})
- db_mock.return_value = info_cache
- base_api.update_instance_cache_with_nw_info(api_mock, self.context,
- self.instance, None)
- api_mock._get_instance_nw_info.assert_called_once_with(self.context,
- self.instance)
- db_mock.assert_called_once_with(self.context, self.instance.uuid,
- {'network_info': self.nw_json})
- self.assertEqual(self.nw_info, self.instance.info_cache.network_info)
-
- def test_update_nw_info_none_instance_deleted(self, db_mock, api_mock):
- instance = objects.Instance(uuid=FAKE_UUID, deleted=True)
- base_api.update_instance_cache_with_nw_info(
- api_mock, self.context, instance)
- self.assertFalse(api_mock.called)
-
- def test_update_nw_info_one_network(self, db_mock, api_mock):
- info_cache = copy.deepcopy(fake_info_cache)
- info_cache.update({'network_info': self.nw_json})
- db_mock.return_value = info_cache
- base_api.update_instance_cache_with_nw_info(api_mock, self.context,
- self.instance, self.nw_info)
- self.assertFalse(api_mock._get_instance_nw_info.called)
- db_mock.assert_called_once_with(self.context, self.instance.uuid,
- {'network_info': self.nw_json})
- self.assertEqual(self.nw_info, self.instance.info_cache.network_info)
-
- def test_update_nw_info_empty_list(self, db_mock, api_mock):
- new_nw_info = network_model.NetworkInfo([])
- db_mock.return_value = fake_info_cache
- base_api.update_instance_cache_with_nw_info(api_mock, self.context,
- self.instance, new_nw_info)
- self.assertFalse(api_mock._get_instance_nw_info.called)
- db_mock.assert_called_once_with(self.context, self.instance.uuid,
- {'network_info': '[]'})
- self.assertEqual(new_nw_info, self.instance.info_cache.network_info)
-
- def test_decorator_return_object(self, db_mock, api_mock):
- db_mock.return_value = fake_info_cache
-
- @base_api.refresh_cache
- def func(self, context, instance):
- return network_model.NetworkInfo([])
- func(api_mock, self.context, self.instance)
- self.assertFalse(api_mock._get_instance_nw_info.called)
- db_mock.assert_called_once_with(self.context, self.instance.uuid,
- {'network_info': '[]'})
-
- def test_decorator_return_none(self, db_mock, api_mock):
- db_mock.return_value = fake_info_cache
-
- @base_api.refresh_cache
- def func(self, context, instance):
- pass
- api_mock._get_instance_nw_info.return_value = self.nw_info
- func(api_mock, self.context, self.instance)
- api_mock._get_instance_nw_info.assert_called_once_with(self.context,
- self.instance)
- db_mock.assert_called_once_with(self.context, self.instance.uuid,
- {'network_info': self.nw_json})
-
-
-class NetworkHooksTestCase(test.BaseHookTestCase):
- def test_instance_network_info_hook(self):
- info_func = base_api.update_instance_cache_with_nw_info
- self.assert_has_hook('instance_network_info', info_func)
diff --git a/nova/tests/unit/network/test_l3.py b/nova/tests/unit/network/test_l3.py
deleted file mode 100644
index 9df8f49e78..0000000000
--- a/nova/tests/unit/network/test_l3.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2015 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from nova.network import l3
-from nova import test
-
-
-class L3DriverTestCase(test.NoDBTestCase):
-
- def test_linuxnetl3_driver_signatures(self):
- self.assertPublicAPISignatures(l3.L3Driver, l3.LinuxNetL3)
-
- def test_nulll3_driver_signatures(self):
- self.assertPublicAPISignatures(l3.L3Driver, l3.NullL3)
diff --git a/nova/tests/unit/network/test_linux_net.py b/nova/tests/unit/network/test_linux_net.py
deleted file mode 100644
index 5aae8281b5..0000000000
--- a/nova/tests/unit/network/test_linux_net.py
+++ /dev/null
@@ -1,1417 +0,0 @@
-# Copyright 2011 NTT
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import calendar
-import datetime
-import os
-
-import mock
-import netifaces
-from oslo_concurrency import processutils
-from oslo_serialization import jsonutils
-from oslo_utils import fileutils
-from oslo_utils.fixture import uuidsentinel as uuids
-from oslo_utils import timeutils
-
-import nova.conf
-from nova import context
-from nova.db import api as db
-from nova import exception
-from nova.network import driver
-from nova.network import linux_net
-from nova import objects
-from nova import test
-
-
-CONF = nova.conf.CONF
-
-instances = {uuids.instance_1:
- {'id': 0,
- 'uuid': uuids.instance_1,
- 'host': 'fake_instance00',
- 'created_at': datetime.datetime(1955, 11, 5, 0, 0, 0),
- 'updated_at': datetime.datetime(1985, 10, 26, 1, 35, 0),
- 'hostname': 'fake_instance00'},
- uuids.instance_2:
- {'id': 1,
- 'uuid': uuids.instance_2,
- 'host': 'fake_instance01',
- 'created_at': datetime.datetime(1955, 11, 5, 0, 0, 0),
- 'updated_at': datetime.datetime(1985, 10, 26, 1, 35, 0),
- 'hostname': 'fake_instance01'},
- uuids.instance_3:
- {'id': 2,
- 'uuid': uuids.instance_3,
- 'host': 'fake_instance02',
- 'created_at': datetime.datetime(1955, 11, 5, 0, 0, 0),
- 'updated_at': datetime.datetime(1985, 10, 26, 1, 35, 0),
- 'hostname': 'really_long_fake_instance02_to_test_hostname_'
- 'truncation_when_too_long'}}
-
-
-addresses = [{"address": "10.0.0.1"},
- {"address": "10.0.0.2"},
- {"address": "10.0.0.3"},
- {"address": "10.0.0.4"},
- {"address": "10.0.0.5"},
- {"address": "10.0.0.6"}]
-
-
-networks = [{'id': 0,
- 'uuid': "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
- 'label': 'test0',
- 'injected': False,
- 'multi_host': False,
- 'cidr': '192.168.0.0/24',
- 'cidr_v6': '2001:db8::/64',
- 'gateway_v6': '2001:db8::1',
- 'netmask_v6': '64',
- 'netmask': '255.255.255.0',
- 'bridge': 'fa0',
- 'bridge_interface': 'fake_fa0',
- 'gateway': '192.168.0.1',
- 'broadcast': '192.168.0.255',
- 'dns1': '192.168.0.1',
- 'dns2': '192.168.0.2',
- 'dhcp_server': '192.168.0.1',
- 'dhcp_start': '192.168.100.1',
- 'vlan': None,
- 'host': None,
- 'project_id': 'fake_project',
- 'vpn_public_address': '192.168.0.2',
- 'mtu': None,
- 'enable_dhcp': True,
- 'share_address': False},
- {'id': 1,
- 'uuid': "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
- 'label': 'test1',
- 'injected': False,
- 'multi_host': True,
- 'cidr': '192.168.1.0/24',
- 'cidr_v6': '2001:db9::/64',
- 'gateway_v6': '2001:db9::1',
- 'netmask_v6': '64',
- 'netmask': '255.255.255.0',
- 'bridge': 'fa1',
- 'bridge_interface': 'fake_fa1',
- 'gateway': '192.168.1.1',
- 'broadcast': '192.168.1.255',
- 'dns1': '192.168.0.1',
- 'dns2': '192.168.0.2',
- 'dhcp_server': '192.168.1.1',
- 'dhcp_start': '192.168.100.1',
- 'vlan': None,
- 'host': None,
- 'project_id': 'fake_project',
- 'vpn_public_address': '192.168.1.2',
- 'mtu': None,
- 'enable_dhcp': True,
- 'share_address': False}]
-
-
-fixed_ips = [{'id': 0,
- 'network_id': 0,
- 'address': '192.168.0.100',
- 'instance_id': 0,
- 'allocated': True,
- 'leased': True,
- 'virtual_interface_id': 0,
- 'default_route': True,
- 'instance_uuid': uuids.instance_1,
- 'floating_ips': []},
- {'id': 1,
- 'network_id': 1,
- 'address': '192.168.1.100',
- 'instance_id': 0,
- 'allocated': True,
- 'leased': True,
- 'virtual_interface_id': 1,
- 'default_route': False,
- 'instance_uuid': uuids.instance_1,
- 'floating_ips': []},
- {'id': 2,
- 'network_id': 1,
- 'address': '192.168.0.101',
- 'instance_id': 1,
- 'allocated': True,
- 'leased': True,
- 'virtual_interface_id': 2,
- 'default_route': True,
- 'instance_uuid': uuids.instance_2,
- 'floating_ips': []},
- {'id': 3,
- 'network_id': 0,
- 'address': '192.168.1.101',
- 'instance_id': 1,
- 'allocated': True,
- 'leased': True,
- 'virtual_interface_id': 3,
- 'default_route': False,
- 'instance_uuid': uuids.instance_2,
- 'floating_ips': []},
- {'id': 4,
- 'network_id': 0,
- 'address': '192.168.0.102',
- 'instance_id': 0,
- 'allocated': True,
- 'leased': False,
- 'virtual_interface_id': 4,
- 'default_route': False,
- 'instance_uuid': uuids.instance_1,
- 'floating_ips': []},
- {'id': 5,
- 'network_id': 1,
- 'address': '192.168.1.102',
- 'instance_id': 1,
- 'allocated': True,
- 'leased': False,
- 'virtual_interface_id': 5,
- 'default_route': False,
- 'instance_uuid': uuids.instance_2,
- 'floating_ips': []},
- {'id': 6,
- 'network_id': 1,
- 'address': '192.168.1.103',
- 'instance_id': 1,
- 'allocated': False,
- 'leased': True,
- 'virtual_interface_id': 6,
- 'default_route': False,
- 'instance_uuid': uuids.instance_2,
- 'floating_ips': []},
- {'id': 7,
- 'network_id': 2,
- 'address': '192.168.2.100',
- 'instance_id': 2,
- 'allocated': True,
- 'leased': False,
- 'virtual_interface_id': 7,
- 'default_route': False,
- 'instance_uuid': uuids.instance_3,
- 'floating_ips': []}]
-
-
-vifs = [{'id': 0,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:00',
- 'uuid': '00000000-0000-0000-0000-0000000000000000',
- 'network_id': 0,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000000'},
- {'id': 1,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:01',
- 'uuid': '00000000-0000-0000-0000-0000000000000001',
- 'network_id': 1,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000000'},
- {'id': 2,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:02',
- 'uuid': '00000000-0000-0000-0000-0000000000000002',
- 'network_id': 1,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000001'},
- {'id': 3,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:03',
- 'uuid': '00000000-0000-0000-0000-0000000000000003',
- 'network_id': 0,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000001'},
- {'id': 4,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:04',
- 'uuid': '00000000-0000-0000-0000-0000000000000004',
- 'network_id': 0,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000000'},
- {'id': 5,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:05',
- 'uuid': '00000000-0000-0000-0000-0000000000000005',
- 'network_id': 1,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000001'},
- {'id': 6,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:06',
- 'uuid': '00000000-0000-0000-0000-0000000000000006',
- 'network_id': 1,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000001'},
- {'id': 7,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:07',
- 'uuid': '00000000-0000-0000-0000-0000000000000007',
- 'network_id': 2,
- 'instance_uuid': '00000000-0000-0000-0000-0000000000000002'}]
-
-
-def get_associated(context, network_id, host=None, address=None):
- result = []
- for datum in fixed_ips:
- if (datum['network_id'] == network_id and
- datum['instance_uuid'] is not None and
- datum['virtual_interface_id'] is not None):
- instance = instances[datum['instance_uuid']]
- if host and host != instance['host']:
- continue
- if address and address != datum['address']:
- continue
- cleaned = {}
- cleaned['address'] = datum['address']
- cleaned['instance_uuid'] = datum['instance_uuid']
- cleaned['network_id'] = datum['network_id']
- cleaned['vif_id'] = datum['virtual_interface_id']
- vif = vifs[datum['virtual_interface_id']]
- cleaned['vif_address'] = vif['address']
- cleaned['instance_hostname'] = instance['hostname']
- cleaned['instance_updated'] = instance['updated_at']
- cleaned['instance_created'] = instance['created_at']
- cleaned['allocated'] = datum['allocated']
- cleaned['leased'] = datum['leased']
- cleaned['default_route'] = datum['default_route']
- result.append(cleaned)
- return result
-
-
-class LinuxNetworkUtilsTestCase(test.NoDBTestCase):
- def test_is_pid_cmdline_correct(self):
- # Negative general case
- fake_open = mock.mock_open(read_data='no-such-process')
- with mock.patch.object(linux_net, 'open', fake_open, create=True):
- self.assertFalse(linux_net.is_pid_cmdline_correct(1, "foo"),
- "foo should not be in 'no-such-process'")
-
- # Negative case that would be a thing we would want to skip
- fake_open = mock.mock_open(
- read_data=('/usr/sbin/dnsmasq '
- '--conf-file=/var/run/NetworkManager/dnsmasq.conf'))
- with mock.patch.object(linux_net, 'open', fake_open, create=True):
- self.assertFalse(
- linux_net.is_pid_cmdline_correct(1, "nova-br100.conf"),
- "nova-br100.conf should not have been found")
-
- # Positive matching case
- fake_open = mock.mock_open(
- read_data=('/usr/sbin/dnsmasq '
- '--dhcp-hostsfile='
- '/opt/stack/data/nova/networks/nova-br100.conf'))
- with mock.patch.object(linux_net, 'open', fake_open, create=True):
- self.assertTrue(
- linux_net.is_pid_cmdline_correct(1, "nova-br100.conf"),
- 'nova-br100.conf should have been found')
-
- # Negative case. This would match except we throw an IOError/OSError
- # because the file couldn't be read or opened, this should then fail.
- for err in (IOError, OSError):
- fake_open = mock.mock_open(
- read_data=('/usr/sbin/dnsmasq '
- '--dhcp-hostsfile='
- '/opt/stack/data/nova/networks/nova-br100.conf'))
- fake_open.side_effect = err
- with mock.patch.object(linux_net, 'open', fake_open, create=True):
- self.assertFalse(
- linux_net.is_pid_cmdline_correct(1, "nova-br100.conf"),
- 'nova-br100.conf should not have been found')
-
-
-class LinuxNetworkTestCase(test.NoDBTestCase):
-
- REQUIRES_LOCKING = True
-
- def setUp(self):
- super(LinuxNetworkTestCase, self).setUp()
- self.driver = driver.load_network_driver()
- self.driver.db = db
- self.context = context.RequestContext('testuser', 'testproject',
- is_admin=True)
-
- def get_vifs(_context, instance_uuid, use_slave):
- return [vif for vif in vifs if vif['instance_uuid'] ==
- instance_uuid]
-
- def get_instance(_context, instance_id):
- return instances[instance_id]
-
- self.stub_out('nova.db.api.virtual_interface_get_by_instance',
- get_vifs)
- self.stub_out('nova.db.api.instance_get', get_instance)
- self.stub_out('nova.db.api.network_get_associated_fixed_ips',
- get_associated)
-
- @mock.patch.object(linux_net.iptables_manager.ipv4['nat'], 'add_rule')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def _test_add_snat_rule(self, expected, is_external,
- mock_iptables_set_rules, mock_iptables_get_rules,
- mock_add_rule):
-
- def verify_add_rule(chain, rule):
- self.assertEqual('snat', chain)
- self.assertEqual(expected, rule)
- self.called = True
-
- mock_add_rule.side_effect = verify_add_rule
-
- self.called = False
- linux_net.add_snat_rule('10.0.0.0/24', is_external)
- if expected:
- mock_add_rule.assert_called_once_with('snat', expected)
- self.assertTrue(self.called)
-
- def test_add_snat_rule_no_ext(self):
- self.flags(routing_source_ip='10.10.10.1')
- expected = ('-s 10.0.0.0/24 -d 0.0.0.0/0 '
- '-j SNAT --to-source 10.10.10.1 -o eth0')
- self._test_add_snat_rule(expected, False)
-
- def test_add_snat_rule_ext(self):
- self.flags(routing_source_ip='10.10.10.1')
- expected = ()
- self._test_add_snat_rule(expected, True)
-
- def test_add_snat_rule_snat_range_no_ext(self):
- self.flags(routing_source_ip='10.10.10.1',
- force_snat_range=['10.10.10.0/24'])
- expected = ('-s 10.0.0.0/24 -d 0.0.0.0/0 '
- '-j SNAT --to-source 10.10.10.1 -o eth0')
- self._test_add_snat_rule(expected, False)
-
- def test_add_snat_rule_snat_range_ext(self):
- self.flags(routing_source_ip='10.10.10.1',
- force_snat_range=['10.10.10.0/24'])
- expected = ('-s 10.0.0.0/24 -d 10.10.10.0/24 '
- '-j SNAT --to-source 10.10.10.1')
- self._test_add_snat_rule(expected, True)
-
- @mock.patch.object(fileutils, 'ensure_tree')
- @mock.patch.object(os, 'chmod')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.restart_dnsmasq')
- def test_update_dhcp_for_nw00(self, mock_restart_dnsmasq,
- mock_iptables_set_rules,
- mock_iptables_get_rules, mock_chmod,
- mock_ensure_tree):
- with mock.patch.object(self.driver, 'write_to_file') \
- as mock_write_to_file:
- self.flags(use_single_default_gateway=True)
-
- self.driver.update_dhcp(self.context, "eth0", networks[0])
-
- self.assertEqual(mock_write_to_file.call_count, 2)
- self.assertEqual(mock_ensure_tree.call_count, 7)
- self.assertEqual(mock_chmod.call_count, 2)
- self.assertEqual(mock_restart_dnsmasq.call_count, 1)
-
- @mock.patch.object(fileutils, 'ensure_tree')
- @mock.patch.object(os, 'chmod')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.restart_dnsmasq')
- def test_update_dhcp_for_nw01(self, mock_restart_dnsmasq,
- mock_iptables_set_rules,
- mock_iptables_get_rules, mock_chmod,
- mock_ensure_tree):
- with mock.patch.object(self.driver, 'write_to_file') \
- as mock_write_to_file:
- self.flags(use_single_default_gateway=True)
-
- self.driver.update_dhcp(self.context, "eth0", networks[0])
-
- self.assertEqual(mock_write_to_file.call_count, 2)
- self.assertEqual(mock_ensure_tree.call_count, 7)
- self.assertEqual(mock_chmod.call_count, 2)
- self.assertEqual(mock_restart_dnsmasq.call_count, 1)
-
- def _get_fixedips(self, network, host=None):
- return objects.FixedIPList.get_by_network(self.context,
- network,
- host=host)
-
- def test_get_dhcp_hosts_for_nw00(self):
- self.flags(use_single_default_gateway=True)
-
- expected = (
- "DE:AD:BE:EF:00:00,fake_instance00.novalocal,"
- "192.168.0.100,net:NW-0\n"
- "DE:AD:BE:EF:00:03,fake_instance01.novalocal,"
- "192.168.1.101,net:NW-3\n"
- "DE:AD:BE:EF:00:04,fake_instance00.novalocal,"
- "192.168.0.102,net:NW-4"
- )
- fixedips = self._get_fixedips(networks[0])
- actual_hosts = self.driver.get_dhcp_hosts(self.context, networks[0],
- fixedips)
-
- self.assertEqual(expected, actual_hosts)
-
- def test_get_dhcp_hosts_for_nw01(self):
- self.flags(use_single_default_gateway=True)
-
- expected = (
- "DE:AD:BE:EF:00:02,fake_instance01.novalocal,"
- "192.168.0.101,net:NW-2\n"
- "DE:AD:BE:EF:00:05,fake_instance01.novalocal,"
- "192.168.1.102,net:NW-5"
- )
- fixedips = self._get_fixedips(networks[1], host='fake_instance01')
- actual_hosts = self.driver.get_dhcp_hosts(self.context, networks[1],
- fixedips)
- self.assertEqual(expected, actual_hosts)
-
- def test_get_dns_hosts_for_nw00(self):
- expected = (
- "192.168.0.100\tfake_instance00.novalocal\n"
- "192.168.1.101\tfake_instance01.novalocal\n"
- "192.168.0.102\tfake_instance00.novalocal"
- )
- actual_hosts = self.driver.get_dns_hosts(self.context, networks[0])
- self.assertEqual(expected, actual_hosts)
-
- def test_get_dns_hosts_for_nw01(self):
- expected = (
- "192.168.1.100\tfake_instance00.novalocal\n"
- "192.168.0.101\tfake_instance01.novalocal\n"
- "192.168.1.102\tfake_instance01.novalocal"
- )
- actual_hosts = self.driver.get_dns_hosts(self.context, networks[1])
- self.assertEqual(expected, actual_hosts)
-
- def test_get_dhcp_opts_for_nw00(self):
- self.flags(use_single_default_gateway=True)
- expected_opts = 'NW-0,3,192.168.0.1\nNW-3,3\nNW-4,3'
- fixedips = self._get_fixedips(networks[0])
- actual_opts = self.driver.get_dhcp_opts(self.context, networks[0],
- fixedips)
-
- self.assertEqual(expected_opts, actual_opts)
-
- def test_get_dhcp_opts_for_nw00_no_single_default_gateway(self):
- self.flags(use_single_default_gateway=False)
- expected_opts = '3,192.168.0.1'
- fixedips = self._get_fixedips(networks[0])
- actual_opts = self.driver.get_dhcp_opts(self.context, networks[0],
- fixedips)
-
- self.assertEqual(expected_opts, actual_opts)
-
- def test_get_dhcp_opts_for_nw01(self):
- self.flags(use_single_default_gateway=True)
- expected_opts = "NW-2,3,192.168.1.1\nNW-5,3"
- fixedips = self._get_fixedips(networks[1], 'fake_instance01')
- actual_opts = self.driver.get_dhcp_opts(self.context, networks[1],
- fixedips)
-
- self.assertEqual(expected_opts, actual_opts)
-
- def test_get_dhcp_leases_for_nw00(self):
- timestamp = timeutils.utcnow()
- seconds_since_epoch = calendar.timegm(timestamp.utctimetuple())
-
- leases = self.driver.get_dhcp_leases(self.context, networks[0])
- leases = leases.split('\n')
- for lease in leases:
- lease = lease.split(' ')
- data = get_associated(self.context, 0, address=lease[2])[0]
- self.assertTrue(data['allocated'])
- self.assertTrue(data['leased'])
- self.assertGreater(int(lease[0]), seconds_since_epoch)
- self.assertEqual(data['vif_address'], lease[1])
- self.assertEqual(data['address'], lease[2])
- self.assertEqual(data['instance_hostname'], lease[3])
- self.assertEqual('*', lease[4])
-
- def test_get_dhcp_leases_for_nw01(self):
- self.flags(host='fake_instance01')
- timestamp = timeutils.utcnow()
- seconds_since_epoch = calendar.timegm(timestamp.utctimetuple())
-
- leases = self.driver.get_dhcp_leases(self.context, networks[1])
- leases = leases.split('\n')
- for lease in leases:
- lease = lease.split(' ')
- data = get_associated(self.context, 1, address=lease[2])[0]
- self.assertTrue(data['leased'])
- self.assertGreater(int(lease[0]), seconds_since_epoch)
- self.assertEqual(data['vif_address'], lease[1])
- self.assertEqual(data['address'], lease[2])
- self.assertEqual(data['instance_hostname'], lease[3])
- self.assertEqual('*', lease[4])
-
- def test_dhcp_opts_not_default_gateway_network(self):
- expected = "NW-0,3"
- fixedip = objects.FixedIPList.get_by_network(self.context,
- {'id': 0})[0]
- actual = self.driver._host_dhcp_opts(fixedip.virtual_interface_id)
- self.assertEqual(expected, actual)
-
- def test_host_dhcp_without_default_gateway_network(self):
- expected = ','.join(['DE:AD:BE:EF:00:00',
- 'fake_instance00.novalocal',
- '192.168.0.100'])
- fixedip = objects.FixedIPList.get_by_network(self.context,
- {'id': 0})[0]
- actual = self.driver._host_dhcp(fixedip)
- self.assertEqual(expected, actual)
-
- def test_host_dhcp_truncated_hostname(self):
- expected = ','.join(['DE:AD:BE:EF:00:07',
- 're-ng_fake_instance02_to_test_hostname_'
- 'truncation_when_too_long.novalocal',
- '192.168.2.100'])
- fixedip = objects.FixedIPList.get_by_network(self.context,
- {'id': 2})[0]
- actual = self.driver._host_dhcp(fixedip)
- self.assertEqual(expected, actual)
-
- def test_host_dns_without_default_gateway_network(self):
- expected = "192.168.0.100\tfake_instance00.novalocal"
- fixedip = objects.FixedIPList.get_by_network(self.context,
- {'id': 0})[0]
- actual = self.driver._host_dns(fixedip)
- self.assertEqual(expected, actual)
-
- @mock.patch.object(linux_net.iptables_manager.ipv4['filter'], 'add_rule')
- @mock.patch('nova.privsep.linux_net.add_bridge',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.routes_show',
- return_value=('fake', 0))
- @mock.patch('nova.privsep.linux_net.lookup_ip', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.bridge_setfd')
- @mock.patch('nova.privsep.linux_net.bridge_disable_stp')
- @mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', ''))
- def test_linux_bridge_driver_plug(
- self, mock_bridge_add_interface, mock_bridge_disable_stp,
- mock_bridge_setfd, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_lookup_ip, mock_routes_show,
- mock_enabled, mock_add_bridge, mock_add_rule):
- """Makes sure plug doesn't drop FORWARD by default.
-
- Ensures bug 890195 doesn't reappear.
- """
-
- def verify_add_rule(chain, rule):
- self.assertEqual('FORWARD', chain)
- self.assertIn('ACCEPT', rule)
-
- mock_add_rule.side_effect = verify_add_rule
-
- driver = linux_net.LinuxBridgeInterfaceDriver()
- driver.plug({"bridge": "br100", "bridge_interface": "eth0",
- "share_address": False}, "fakemac")
- self.assertEqual(2, mock_add_rule.call_count)
-
- @mock.patch('nova.privsep.linux_net.device_exists',
- return_value=False)
- @mock.patch('nova.privsep.linux_net.ovs_plug',
- side_effect=exception.OVSConfigurationFailure('foo'))
- def test_linux_ovs_driver_plug_exception(self, mock_plug,
- mock_device_exists):
- self.flags(fake_network=False)
-
- driver = linux_net.LinuxOVSInterfaceDriver()
-
- self.assertRaises(exception.OVSConfigurationFailure,
- driver.plug, {'uuid': 'fake_network_uuid'},
- 'fake_mac')
- mock_plug.assert_called_once()
- mock_device_exists.assert_called_once()
-
- @mock.patch.object(linux_net.LinuxBridgeInterfaceDriver,
- 'ensure_vlan_bridge')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def test_vlan_override(self, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_ensure_vlan_bridge):
- """Makes sure vlan_interface flag overrides network bridge_interface.
-
- Allows heterogeneous networks a la bug 833426
- """
-
- driver = linux_net.LinuxBridgeInterfaceDriver()
-
- info = {}
-
- def test_ensure(vlan, bridge, interface, network, mac_address, mtu):
- info['passed_interface'] = interface
-
- mock_ensure_vlan_bridge.side_effect = test_ensure
-
- network = {
- "bridge": "br100",
- "bridge_interface": "base_interface",
- "share_address": False,
- "vlan": "fake"
- }
- self.flags(vlan_interface="")
- driver.plug(network, "fakemac")
- self.assertEqual("base_interface", info['passed_interface'])
- self.flags(vlan_interface="override_interface")
- driver.plug(network, "fakemac")
- self.assertEqual("override_interface", info['passed_interface'])
- driver.plug(network, "fakemac")
- self.assertEqual(3, mock_ensure_vlan_bridge.call_count)
-
- @mock.patch.object(linux_net.LinuxBridgeInterfaceDriver, 'ensure_bridge')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def test_flat_override(self, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_ensure_bridge):
- """Makes sure flat_interface flag overrides network bridge_interface.
-
- Allows heterogeneous networks a la bug 833426
- """
-
- driver = linux_net.LinuxBridgeInterfaceDriver()
-
- info = {}
-
- def test_ensure(bridge, interface, network, gateway):
- info['passed_interface'] = interface
-
- mock_ensure_bridge.side_effect = test_ensure
-
- network = {
- "bridge": "br100",
- "bridge_interface": "base_interface",
- "share_address": False,
- }
- driver.plug(network, "fakemac")
- self.assertEqual("base_interface", info['passed_interface'])
- self.flags(flat_interface="override_interface")
- driver.plug(network, "fakemac")
- self.assertEqual("override_interface", info['passed_interface'])
- self.assertEqual(2, mock_ensure_bridge.call_count)
-
- @mock.patch.object(linux_net, '_dnsmasq_pid_for')
- @mock.patch.object(linux_net, 'write_to_file')
- @mock.patch('os.chmod')
- @mock.patch.object(linux_net, '_add_dhcp_mangle_rule')
- @mock.patch('oslo_concurrency.processutils.execute')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.restart_dnsmasq',
- side_effect=nova.privsep.linux_net._restart_dnsmasq_inner)
- def _test_dnsmasq_execute(self, mock_restart_dnsmasq,
- mock_iptables_set_rules,
- mock_iptables_get_rules, mock_execute,
- mock_add_dhcp_mangle_rule,
- mock_chmod, mock_write_to_file,
- mock_dnsmasq_pid_for, extra_expected=None):
- network_ref = {'id': 'fake',
- 'label': 'fake',
- 'gateway': '10.0.0.1',
- 'multi_host': False,
- 'cidr': '10.0.0.0/24',
- 'netmask': '255.255.255.0',
- 'dns1': '8.8.4.4',
- 'dhcp_start': '1.0.0.2',
- 'dhcp_server': '10.0.0.1',
- 'share_address': False}
-
- def fake_execute(*args, **kwargs):
- executes.append(args)
- return "", ""
-
- def fake_add_dhcp_mangle_rule(*args, **kwargs):
- executes.append(args)
-
- mock_execute.side_effect = fake_execute
- mock_add_dhcp_mangle_rule.side_effect = fake_add_dhcp_mangle_rule
-
- dev = 'br100'
-
- default_domain = CONF.api.dhcp_domain
- for domain in ('', default_domain):
- executes = []
- self.flags(dhcp_domain=domain, group='api')
- fixedips = self._get_fixedips(network_ref)
- linux_net.restart_dhcp(self.context, dev, network_ref, fixedips)
- expected = ['env',
- 'CONFIG_FILE=%s' % jsonutils.dumps(CONF.dhcpbridge_flagfile),
- 'NETWORK_ID=fake',
- 'dnsmasq',
- '--strict-order',
- '--bind-interfaces',
- '--conf-file=%s' % CONF.dnsmasq_config_file,
- '--pid-file=%s' % linux_net._dhcp_file(dev, 'pid'),
- '--dhcp-optsfile=%s' % linux_net._dhcp_file(dev, 'opts'),
- '--listen-address=%s' % network_ref['dhcp_server'],
- '--except-interface=lo',
- "--dhcp-range=set:%s,%s,static,%s,%ss" % (network_ref['label'],
- network_ref['dhcp_start'],
- network_ref['netmask'],
- CONF.dhcp_lease_time),
- '--dhcp-lease-max=256',
- '--dhcp-hostsfile=%s' % linux_net._dhcp_file(dev, 'conf'),
- '--dhcp-script=%s' % CONF.dhcpbridge,
- '--no-hosts',
- '--leasefile-ro']
-
- if CONF.api.dhcp_domain:
- expected.append('--domain=%s' % CONF.api.dhcp_domain)
-
- if extra_expected:
- expected += extra_expected
- self.assertEqual([(dev,), tuple(expected)], executes)
- self.assertEqual(2, mock_execute.call_count)
- self.assertEqual(2, mock_add_dhcp_mangle_rule.call_count)
- self.assertEqual(4, mock_chmod.call_count)
- self.assertEqual(2, mock_write_to_file.call_count)
- self.assertEqual(2, mock_dnsmasq_pid_for.call_count)
-
- def test_dnsmasq_execute(self):
- self._test_dnsmasq_execute()
-
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def test_dnsmasq_execute_dns_servers(self, mock_iptables_set_rules,
- mock_iptables_get_rules):
- self.flags(dns_server=['1.1.1.1', '2.2.2.2'])
- expected = [
- '--no-resolv',
- '--server=1.1.1.1',
- '--server=2.2.2.2',
- ]
- self._test_dnsmasq_execute(extra_expected=expected)
-
- def test_dnsmasq_execute_use_network_dns_servers(self):
- self.flags(use_network_dns_servers=True)
- expected = [
- '--no-resolv',
- '--server=8.8.4.4',
- ]
- self._test_dnsmasq_execute(extra_expected=expected)
-
- @mock.patch('nova.privsep.linux_net.modify_ebtables')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def test_isolated_host(self, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_modify_ebtables):
- self.flags(fake_network=False,
- share_dhcp_address=True)
- driver = linux_net.LinuxBridgeInterfaceDriver()
-
- def fake_ensure(bridge, interface, network, gateway):
- return bridge
-
- self.stub_out('nova.network.linux_net.iptables_manager',
- linux_net.IptablesManager())
- self.stub_out('nova.network.linux_net.binary_name', 'test')
- self.stub_out(
- 'nova.network.linux_net.LinuxBridgeInterfaceDriver.ensure_bridge',
- fake_ensure)
-
- iface = 'eth0'
- dhcp = '192.168.1.1'
- network = {'dhcp_server': dhcp,
- 'share_address': False,
- 'bridge': 'br100',
- 'bridge_interface': iface}
- driver.plug(network, 'fakemac')
-
- mock_iptables_get_rules.assert_has_calls([
- mock.call(ipv4=True),
- mock.call(ipv4=False)])
- mock_iptables_set_rules.assert_has_calls([
- mock.call(mock.ANY, ipv4=True),
- mock.call(mock.ANY, ipv4=False)])
- mock_modify_ebtables.assert_has_calls([
- mock.call('filter',
- ['INPUT', '-p', 'ARP', '-i', iface, '--arp-ip-dst',
- dhcp, '-j', 'DROP'],
- insert_rule=False),
- mock.call('filter',
- ['INPUT', '-p', 'ARP', '-i', iface, '--arp-ip-dst',
- dhcp, '-j', 'DROP'],
- insert_rule=True),
- mock.call('filter',
- ['OUTPUT', '-p', 'ARP', '-o', iface, '--arp-ip-src',
- dhcp, '-j', 'DROP'],
- insert_rule=False),
- mock.call('filter',
- ['OUTPUT', '-p', 'ARP', '-o', iface, '--arp-ip-src',
- dhcp, '-j', 'DROP'],
- insert_rule=True),
- mock.call('filter',
- ['FORWARD', '-p', 'IPv4', '-i', iface, '--ip-protocol',
- 'udp', '--ip-destination-port', '67:68', '-j', 'DROP'],
- insert_rule=False),
- mock.call('filter',
- ['FORWARD', '-p', 'IPv4', '-i', iface, '--ip-protocol',
- 'udp', '--ip-destination-port', '67:68', '-j', 'DROP'],
- insert_rule=True),
- mock.call('filter',
- ['FORWARD', '-p', 'IPv4', '-o', iface, '--ip-protocol',
- 'udp', '--ip-destination-port', '67:68', '-j', 'DROP'],
- insert_rule=False),
- mock.call('filter',
- ['FORWARD', '-p', 'IPv4', '-o', iface, '--ip-protocol',
- 'udp', '--ip-destination-port', '67:68', '-j', 'DROP'],
- insert_rule=True)])
-
- mock_modify_ebtables.reset_mock()
-
- def fake_remove(bridge, gateway):
- return
-
- self.stub_out(
- 'nova.network.linux_net.LinuxBridgeInterfaceDriver.remove_bridge',
- fake_remove)
-
- driver.unplug(network)
- mock_modify_ebtables.assert_has_calls([
- mock.call('filter',
- ['INPUT', '-p', 'ARP', '-i', iface, '--arp-ip-dst',
- dhcp, '-j', 'DROP'],
- insert_rule=False),
- mock.call('filter',
- ['OUTPUT', '-p', 'ARP', '-o', iface, '--arp-ip-src',
- dhcp, '-j', 'DROP'],
- insert_rule=False),
- mock.call('filter',
- ['FORWARD', '-p', 'IPv4', '-i', iface, '--ip-protocol',
- 'udp', '--ip-destination-port', '67:68', '-j', 'DROP'],
- insert_rule=False),
- mock.call('filter',
- ['FORWARD', '-p', 'IPv4', '-o', iface, '--ip-protocol',
- 'udp', '--ip-destination-port', '67:68', '-j', 'DROP'],
- insert_rule=False)])
-
- @mock.patch('nova.privsep.linux_net.routes_show')
- @mock.patch('nova.privsep.linux_net.route_delete')
- @mock.patch('nova.privsep.linux_net.route_add_deprecated')
- @mock.patch('nova.privsep.linux_net.lookup_ip')
- @mock.patch('nova.privsep.linux_net.change_ip')
- @mock.patch('nova.privsep.linux_net.address_command_deprecated')
- def _test_initialize_gateway(self, existing,
- mock_address_command, mock_change_ip,
- mock_lookup_ip, mock_route_add,
- mock_route_delete, mock_routes,
- routes='',
- routes_show_called=True, deleted_routes=None,
- added_routes=None, changed_interfaces=None,
- address_commands=None):
- self.flags(fake_network=False)
- mock_lookup_ip.return_value = (existing, '')
-
- mock_routes.return_value = (routes, '')
- mock_lookup_ip.return_value = (existing, '')
-
- network = {'dhcp_server': '192.168.1.1',
- 'cidr': '192.168.1.0/24',
- 'broadcast': '192.168.1.255',
- 'cidr_v6': '2001:db8::/64'}
- self.driver.initialize_gateway_device('eth0', network)
- self.assertTrue(mock_lookup_ip.called)
-
- if routes_show_called:
- mock_routes.assert_called_once_with('eth0')
- if deleted_routes:
- mock_route_delete.assert_has_calls(deleted_routes)
- if added_routes:
- mock_route_add.assert_has_calls(added_routes)
- if changed_interfaces:
- mock_change_ip.assert_has_calls(changed_interfaces)
- if address_commands:
- mock_address_command.assert_has_calls(address_commands)
-
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=True)
- def test_initialize_gateway_moves_wrong_ip(self, mock_forwarding_check):
- existing = ("2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> "
- " mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n"
- " link/ether de:ad:be:ef:be:ef brd ff:ff:ff:ff:ff:ff\n"
- " inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
- " inet6 dead::beef:dead:beef:dead/64 scope link\n"
- " valid_lft forever preferred_lft forever\n")
- self._test_initialize_gateway(
- existing,
- changed_interfaces=[mock.call('eth0', '2001:db8::/64')],
- address_commands=[
- mock.call('eth0', 'del', ['192.168.0.1/24', 'brd',
- '192.168.0.255',
- 'scope', 'global']),
- mock.call('eth0', 'add', ['192.168.1.1/24', 'brd',
- '192.168.1.255']),
- mock.call('eth0', 'add', ['192.168.0.1/24', 'brd',
- '192.168.0.255',
- 'scope', 'global'])]
- )
-
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=True)
- def test_initialize_gateway_ip_with_dynamic_flag(self,
- mock_forwarding_check):
- existing = ("2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> "
- " mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n"
- " link/ether de:ad:be:ef:be:ef brd ff:ff:ff:ff:ff:ff\n"
- " inet 192.168.0.1/24 brd 192.168.0.255 scope global "
- "dynamic eth0\n"
- " inet6 dead::beef:dead:beef:dead/64 scope link\n"
- " valid_lft forever preferred_lft forever\n")
- self._test_initialize_gateway(
- existing,
- changed_interfaces=[mock.call('eth0', '2001:db8::/64')],
- address_commands=[
- mock.call('eth0', 'del',
- ['192.168.0.1/24', 'brd', '192.168.0.255',
- 'scope', 'global']),
- mock.call('eth0', 'add',
- ['192.168.1.1/24', 'brd', '192.168.1.255']),
- mock.call('eth0', 'add',
- ['192.168.0.1/24', 'brd', '192.168.0.255',
- 'scope', 'global'])]
- )
-
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=True)
- def test_initialize_gateway_resets_route(self, mock_forwarding_check):
- routes = ("default via 192.168.0.1 dev eth0\n"
- "192.168.100.0/24 via 192.168.0.254 dev eth0 proto static\n")
- existing = ("2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> "
- " mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n"
- " link/ether de:ad:be:ef:be:ef brd ff:ff:ff:ff:ff:ff\n"
- " inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
- " inet6 dead::beef:dead:beef:dead/64 scope link\n"
- " valid_lft forever preferred_lft forever\n")
- self._test_initialize_gateway(
- existing, routes=routes,
- deleted_routes=[mock.call('eth0', 'default'),
- mock.call('eth0', '192.168.100.0/24')],
- added_routes=[mock.call(['default', 'via', '192.168.0.1',
- 'dev', 'eth0']),
- mock.call(['192.168.100.0/24', 'via',
- '192.168.0.254',
- 'dev', 'eth0', 'proto', 'static'])],
- changed_interfaces=[mock.call('eth0', '2001:db8::/64')],
- address_commands=[
- mock.call('eth0', 'del',
- ['192.168.0.1/24', 'brd', '192.168.0.255',
- 'scope', 'global']),
- mock.call('eth0', 'add',
- ['192.168.1.1/24', 'brd', '192.168.1.255']),
- mock.call('eth0', 'add',
- ['192.168.0.1/24', 'brd', '192.168.0.255',
- 'scope', 'global'])]
- )
-
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=True)
- def test_initialize_gateway_no_move_right_ip(self, mock_forwarding_check):
- existing = ("2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> "
- " mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n"
- " link/ether de:ad:be:ef:be:ef brd ff:ff:ff:ff:ff:ff\n"
- " inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0\n"
- " inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0\n"
- " inet6 dead::beef:dead:beef:dead/64 scope link\n"
- " valid_lft forever preferred_lft forever\n")
- self._test_initialize_gateway(
- existing, routes_show_called=False,
- changed_interfaces=[mock.call('eth0', '2001:db8::/64')])
- mock_forwarding_check.assert_called()
-
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=True)
- def test_initialize_gateway_add_if_blank(self, mock_forwarding_check):
- existing = ("2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> "
- " mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n"
- " link/ether de:ad:be:ef:be:ef brd ff:ff:ff:ff:ff:ff\n"
- " inet6 dead::beef:dead:beef:dead/64 scope link\n"
- " valid_lft forever preferred_lft forever\n")
- self._test_initialize_gateway(
- existing,
- changed_interfaces=[mock.call('eth0', '2001:db8::/64')],
- address_commands=[
- mock.call('eth0', 'add',
- ['192.168.1.1/24', 'brd', '192.168.1.255'])]
- )
-
- @mock.patch.object(linux_net, 'ensure_ebtables_rules')
- @mock.patch.object(linux_net.iptables_manager, 'apply')
- def test_ensure_floating_no_duplicate_forwards(self, mock_apply,
- mock_ensure_ebtables_rules):
- ln = linux_net
-
- mock_apply.side_effect = lambda: None
- mock_ensure_ebtables_rules.side_effect = lambda *a, **kw: None
-
- net = {'bridge': 'br100', 'cidr': '10.0.0.0/24'}
- ln.ensure_floating_forward('10.10.10.10', '10.0.0.1', 'eth0', net)
- ln.ensure_floating_forward('10.10.10.11', '10.0.0.10', 'eth0', net)
- two_forward_rules = len(linux_net.iptables_manager.ipv4['nat'].rules)
- ln.ensure_floating_forward('10.10.10.10', '10.0.0.3', 'eth0', net)
- dup_forward_rules = len(linux_net.iptables_manager.ipv4['nat'].rules)
- self.assertEqual(two_forward_rules, dup_forward_rules)
- self.assertEqual(3, mock_apply.call_count)
- self.assertEqual(3, mock_ensure_ebtables_rules.call_count)
-
- def test_apply_ran(self):
- manager = linux_net.IptablesManager()
- manager.iptables_apply_deferred = False
- with mock.patch.object(manager, '_apply') as mock_apply:
- empty_ret = manager.apply()
- mock_apply.assert_called_once()
- self.assertIsNone(empty_ret)
-
- def test_apply_not_run(self):
- manager = linux_net.IptablesManager()
- manager.iptables_apply_deferred = True
- with mock.patch.object(manager, '_apply') as mock_apply:
- manager.apply()
- mock_apply.assert_not_called()
-
- def test_deferred_unset_apply_ran(self):
- manager = linux_net.IptablesManager()
- manager.iptables_apply_deferred = True
- with mock.patch.object(manager, '_apply') as mock_apply:
- manager.defer_apply_off()
- mock_apply.assert_called_once()
- self.assertFalse(manager.iptables_apply_deferred)
-
- @mock.patch.object(linux_net.iptables_manager.ipv4['filter'], 'add_rule')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def _test_add_metadata_accept_rule(self, expected, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_add_rule):
- def verify_add_rule(chain, rule):
- self.assertEqual('INPUT', chain)
- self.assertEqual(expected, rule)
-
- mock_add_rule.side_effect = verify_add_rule
- linux_net.metadata_accept()
- mock_add_rule.assert_called_once()
-
- @mock.patch.object(linux_net.iptables_manager.ipv6['filter'], 'add_rule')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def _test_add_metadata_accept_ipv6_rule(self, expected,
- mock_iptables_set_rules,
- mock_iptables_get_rules,
- mock_add_rule):
- def verify_add_rule(chain, rule):
- self.assertEqual('INPUT', chain)
- self.assertEqual(expected, rule)
-
- mock_add_rule.side_effect = verify_add_rule
- linux_net.metadata_accept()
- mock_add_rule.assert_called_once()
-
- def test_metadata_accept(self):
- self.flags(metadata_port='8775')
- self.flags(metadata_host='10.10.10.1')
- expected = ('-p tcp -m tcp --dport 8775 '
- '-d 10.10.10.1 -j ACCEPT')
- self._test_add_metadata_accept_rule(expected)
-
- def test_metadata_accept_ipv6(self):
- self.flags(metadata_port='8775')
- self.flags(metadata_host='2600::')
- expected = ('-p tcp -m tcp --dport 8775 '
- '-d 2600:: -j ACCEPT')
- self._test_add_metadata_accept_ipv6_rule(expected)
-
- def test_metadata_accept_localhost(self):
- self.flags(metadata_port='8775')
- self.flags(metadata_host='127.0.0.1')
- expected = ('-p tcp -m tcp --dport 8775 '
- '-m addrtype --dst-type LOCAL -j ACCEPT')
- self._test_add_metadata_accept_rule(expected)
-
- def test_metadata_accept_ipv6_localhost(self):
- self.flags(metadata_port='8775')
- self.flags(metadata_host='::1')
- expected = ('-p tcp -m tcp --dport 8775 '
- '-m addrtype --dst-type LOCAL -j ACCEPT')
- self._test_add_metadata_accept_ipv6_rule(expected)
-
- @mock.patch.object(linux_net.iptables_manager.ipv4['nat'], 'add_rule')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def _test_add_metadata_forward_rule(self, expected,
- mock_iptables_set_rules,
- mock_iptables_get_rules,
- mock_add_rule):
- def verify_add_rule(chain, rule):
- self.assertEqual('PREROUTING', chain)
- self.assertEqual(expected, rule)
-
- mock_add_rule.side_effect = verify_add_rule
- linux_net.metadata_forward()
- mock_add_rule.assert_called_once()
-
- def test_metadata_forward(self):
- self.flags(metadata_port='8775')
- self.flags(metadata_host='10.10.10.1')
- expected = ('-s 0.0.0.0/0 -d 169.254.169.254/32 -p tcp -m tcp '
- '--dport 80 -j DNAT --to-destination 10.10.10.1:8775')
- self._test_add_metadata_forward_rule(expected)
-
- def test_metadata_forward_localhost(self):
- self.flags(metadata_port='8775')
- self.flags(metadata_host='127.0.0.1')
- expected = ('-s 0.0.0.0/0 -d 169.254.169.254/32 -p tcp -m tcp '
- '--dport 80 -j REDIRECT --to-ports 8775')
- self._test_add_metadata_forward_rule(expected)
-
- def test_ensure_bridge_brings_up_interface(self):
- # We have to bypass the CONF.fake_network check so that netifaces
- # is actually called.
- self.flags(fake_network=False)
- fake_mac = 'aa:bb:cc:00:11:22'
- fake_ifaces = {
- netifaces.AF_LINK: [{'addr': fake_mac}]
- }
- with test.nested(
- mock.patch('nova.privsep.linux_net.lookup_ip',
- return_value=('', '')),
- mock.patch('nova.privsep.linux_net.device_exists',
- return_value=True),
- mock.patch('nova.privsep.linux_net.set_device_enabled'),
- mock.patch('nova.privsep.linux_net.set_device_macaddr'),
- mock.patch('nova.privsep.linux_net.routes_show',
- return_value=('fake', '')),
- mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', '')),
- mock.patch.object(netifaces, 'ifaddresses')
- ) as (lookup_ip, device_exists, device_enabled, set_device_macaddr,
- routes_show, add_interface, ifaddresses):
- ifaddresses.return_value = fake_ifaces
- driver = linux_net.LinuxBridgeInterfaceDriver()
- driver.ensure_bridge('bridge', 'eth0')
- device_exists.assert_has_calls(
- [mock.call('bridge')])
- add_interface.assert_has_calls(
- [mock.call('bridge', 'eth0')])
- ifaddresses.assert_called_once_with('eth0')
- device_enabled.assert_called_once_with('eth0')
- set_device_macaddr.assert_called_once_with('bridge', fake_mac)
- lookup_ip.assert_called_once_with('eth0')
-
- def test_ensure_bridge_brclt_addif_exception(self):
- with test.nested(
- mock.patch('nova.privsep.linux_net.device_exists',
- return_value=True),
- mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', 'some error happens'))
- ) as (device_exists, _):
- driver = linux_net.LinuxBridgeInterfaceDriver()
- self.assertRaises(exception.NovaException,
- driver.ensure_bridge, 'bridge', 'eth0')
- device_exists.assert_called_once_with('bridge')
-
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.bridge_setfd')
- @mock.patch('nova.privsep.linux_net.bridge_disable_stp')
- def test_ensure_bridge_brclt_addbr_neutron_race(
- self, mock_bridge_disable_stp, mock_bridge_setfd, mock_enabled):
- def fake_execute(*cmd, **kwargs):
- if ('brctl', 'addbr', 'brq1234567-89') == cmd:
- return ('', "device brq1234567-89 already exists; "
- "can't create bridge with the same name\n")
- else:
- return ('', '')
-
- with test.nested(
- mock.patch('nova.privsep.linux_net.device_exists',
- return_value=False),
- mock.patch('nova.privsep.linux_net.add_bridge', fake_execute)
- ) as (device_exists, _):
- driver = linux_net.LinuxBridgeInterfaceDriver()
- driver.ensure_bridge('brq1234567-89', '')
- device_exists.assert_called_once_with('brq1234567-89')
-
- @mock.patch('nova.privsep.linux_net.modify_ebtables',
- return_value=('', ''))
- def test_exec_ebtables_success(self, mock_modify_ebtables):
- self.driver._exec_ebtables('fake', 'fake')
- mock_modify_ebtables.assert_called()
-
- @mock.patch('nova.privsep.linux_net.modify_ebtables',
- side_effect=processutils.ProcessExecutionError(
- 'error',
- stderr=(u'Unable to update the kernel. Two possible '
- 'causes:\n1. Multiple ebtables programs were '
- 'executing simultaneously. The ebtables\n '
- 'userspace tool doesn\'t by default support '
- 'multiple ebtables programs running\n '
- 'concurrently. The ebtables option --concurrent '
- 'or a tool like flock can be\n used to support '
- 'concurrent scripts that update the ebtables '
- 'kernel tables.\n2. The kernel doesn\'t support '
- 'a certain ebtables extension, consider\n '
- 'recompiling your kernel or insmod the '
- 'extension.\n.\n')))
- @mock.patch('time.sleep')
- def test_exec_ebtables_fail_all(self, mock_sleep, mock_modify_ebtables):
- self.flags(ebtables_exec_attempts=5)
- self.assertRaises(processutils.ProcessExecutionError,
- self.driver._exec_ebtables, 'fake', 'fake')
- self.assertEqual(5, mock_modify_ebtables.call_count)
-
- @mock.patch('nova.privsep.linux_net.modify_ebtables',
- side_effect=processutils.ProcessExecutionError(
- 'error',
- stderr=(u'Sorry, rule does not exist')))
- @mock.patch('time.sleep')
- def test_exec_ebtables_fail_no_retry(self, mock_sleep,
- mock_modify_ebtables):
- self.assertRaises(processutils.ProcessExecutionError,
- self.driver._exec_ebtables, 'fake', 'fake')
- mock_modify_ebtables.assert_called()
-
- @mock.patch('nova.privsep.linux_net.modify_ebtables',
- side_effect=[
- processutils.ProcessExecutionError(
- 'error',
- stderr=(u'Unable to update the kernel. Two possible '
- 'causes:\n1. Multiple ebtables programs were '
- 'executing simultaneously. The ebtables\n '
- 'userspace tool doesn\'t by default support '
- 'multiple ebtables programs running\n '
- 'concurrently. The ebtables option '
- '--concurrent or a tool like flock can be\n '
- 'used to support concurrent scripts that '
- 'update the ebtables kernel tables.\n2. The '
- 'kernel doesn\'t support a certain ebtables '
- 'extension, consider\n recompiling your '
- 'kernel or insmod the extension.\n.\n')),
- ('', '')])
- @mock.patch('time.sleep')
- def test_exec_ebtables_fail_once(self, mock_sleep, mock_modify_ebtables):
- self.driver._exec_ebtables('fake', 'fake')
- self.assertEqual(2, mock_modify_ebtables.call_count)
-
- @mock.patch('os.path.exists', return_value=True)
- @mock.patch('nova.privsep.linux_net.set_device_disabled')
- @mock.patch('nova.privsep.linux_net.delete_bridge')
- def test_remove_bridge(self, mock_delete, mock_disabled, mock_exists):
- linux_net.LinuxBridgeInterfaceDriver.remove_bridge('fake-bridge')
-
- self.assertIn(mock.call('/sys/class/net/fake-bridge'),
- mock_exists.mock_calls)
- mock_disabled.assert_called_once_with('fake-bridge')
- mock_delete.assert_called_once_with('fake-bridge')
-
- @mock.patch('nova.privsep.linux_net.device_exists', return_value=False)
- @mock.patch('nova.privsep.linux_net.set_device_mtu')
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.set_device_macaddr')
- @mock.patch('nova.privsep.linux_net.add_vlan')
- def test_ensure_vlan(self, mock_add_vlan, mock_set_macaddr,
- mock_set_enabled, mock_set_device_mtu,
- mock_device_exists):
- interface = linux_net.LinuxBridgeInterfaceDriver.ensure_vlan(
- 1, 'eth0', 'MAC', 'MTU', "vlan_name")
- self.assertEqual("vlan_name", interface)
- mock_device_exists.assert_called_once_with('vlan_name')
-
- mock_add_vlan.assert_called_once_with('eth0', 'vlan_name', 1)
- mock_set_device_mtu.assert_called_once_with('vlan_name', 'MTU')
- mock_set_enabled.assert_called_once_with('vlan_name')
- mock_set_macaddr.assert_called_once_with('vlan_name', 'MAC')
-
- @mock.patch('nova.privsep.linux_net.device_exists', return_value=True)
- @mock.patch('nova.privsep.linux_net.set_device_mtu')
- def test_ensure_vlan_device_exists(self, mock_set_device_mtu,
- mock_device_exists):
- interface = linux_net.LinuxBridgeInterfaceDriver.ensure_vlan(1, 'eth0')
- self.assertEqual("vlan1", interface)
- mock_device_exists.assert_called_once_with('vlan1')
- mock_set_device_mtu.assert_called_once_with('vlan1', None)
-
- @mock.patch('os.path.exists', return_value=True)
- @mock.patch('nova.privsep.linux_net.set_device_disabled',
- side_effect=processutils.ProcessExecutionError())
- def test_remove_bridge_negative(self, mock_device_disabled, mock_exists):
- self.assertRaises(processutils.ProcessExecutionError,
- linux_net.LinuxBridgeInterfaceDriver.remove_bridge,
- 'fake-bridge')
-
- @mock.patch('nova.pci.utils.get_vf_num_by_pci_address')
- @mock.patch('nova.pci.utils.get_ifname_by_pci_address')
- @mock.patch('nova.privsep.linux_net.set_device_trust',
- side_effect=nova.privsep.linux_net._set_device_trust_inner)
- @mock.patch('oslo_concurrency.processutils.execute')
- def test_set_vf_trusted_on(self, mexecute, mtrust, mget_ifname,
- mget_vfnum):
- mget_ifname.return_value = 'eth0'
- mget_vfnum.return_value = 2
- linux_net.set_vf_trusted('PCI_ADDR', True)
- mexecute.assert_called_once_with(
- 'ip', 'link', 'set', 'eth0', 'vf', 2, 'trust', 'on',
- check_exit_code=[0, 2, 254])
-
- @mock.patch('nova.pci.utils.get_vf_num_by_pci_address')
- @mock.patch('nova.pci.utils.get_ifname_by_pci_address')
- @mock.patch('nova.privsep.linux_net.set_device_trust',
- side_effect=nova.privsep.linux_net._set_device_trust_inner)
- @mock.patch('oslo_concurrency.processutils.execute')
- def test_set_vf_trusted_off(self, mexecute, mtrust, mget_ifname,
- mget_vfnum):
- mget_ifname.return_value = 'eth0'
- mget_vfnum.return_value = 2
- linux_net.set_vf_trusted('PCI_ADDR', False)
- mexecute.assert_called_once_with(
- 'ip', 'link', 'set', 'eth0', 'vf', 2, 'trust', 'off',
- check_exit_code=[0, 2, 254])
diff --git a/nova/tests/unit/network/test_manager.py b/nova/tests/unit/network/test_manager.py
deleted file mode 100644
index eb498ac508..0000000000
--- a/nova/tests/unit/network/test_manager.py
+++ /dev/null
@@ -1,3823 +0,0 @@
-# Copyright 2011 Rackspace
-# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import fixtures
-import mock
-from mox3 import mox
-import netaddr
-from oslo_concurrency import processutils
-from oslo_config import cfg
-from oslo_db import exception as db_exc
-from oslo_log import log as logging
-import oslo_messaging as messaging
-from oslo_utils.fixture import uuidsentinel as uuids
-from oslo_utils import importutils
-from oslo_utils import netutils
-import six
-import testtools
-
-from nova import context
-from nova.db import api as db
-from nova.db.sqlalchemy import models
-from nova import exception
-from nova import ipv6
-from nova.network import floating_ips
-from nova.network import linux_net
-from nova.network import manager as network_manager
-from nova.network import rpcapi as network_rpcapi
-from nova import objects
-from nova.objects import network as network_obj
-from nova.objects import virtual_interface as vif_obj
-from nova import test
-from nova.tests.unit.api.openstack import fakes
-from nova.tests.unit import fake_instance
-from nova.tests.unit import fake_ldap
-from nova.tests.unit import fake_network
-from nova.tests.unit.objects import test_fixed_ip
-from nova.tests.unit.objects import test_floating_ip
-from nova.tests.unit.objects import test_network
-from nova.tests.unit.objects import test_service
-from nova import utils
-
-
-CONF = cfg.CONF
-LOG = logging.getLogger(__name__)
-
-
-HOST = "testhost"
-FAKEUUID = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
-
-
-fake_inst = fake_instance.fake_db_instance
-
-
-networks = [{'id': 0,
- 'uuid': FAKEUUID,
- 'label': 'test0',
- 'injected': False,
- 'multi_host': False,
- 'cidr': '192.168.0.0/24',
- 'cidr_v6': '2001:db8::/64',
- 'gateway_v6': '2001:db8::1',
- 'netmask_v6': '64',
- 'netmask': '255.255.255.0',
- 'bridge': 'fa0',
- 'bridge_interface': 'fake_fa0',
- 'gateway': '192.168.0.1',
- 'dhcp_server': '192.168.0.1',
- 'broadcast': '192.168.0.255',
- 'dns1': '192.168.0.1',
- 'dns2': '192.168.0.2',
- 'vlan': None,
- 'host': HOST,
- 'project_id': fakes.FAKE_PROJECT_ID,
- 'vpn_public_address': '192.168.0.2',
- 'vpn_public_port': '22',
- 'vpn_private_address': '10.0.0.2'},
- {'id': 1,
- 'uuid': 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- 'label': 'test1',
- 'injected': False,
- 'multi_host': False,
- 'cidr': '192.168.1.0/24',
- 'cidr_v6': '2001:db9::/64',
- 'gateway_v6': '2001:db9::1',
- 'netmask_v6': '64',
- 'netmask': '255.255.255.0',
- 'bridge': 'fa1',
- 'bridge_interface': 'fake_fa1',
- 'gateway': '192.168.1.1',
- 'dhcp_server': '192.168.1.1',
- 'broadcast': '192.168.1.255',
- 'dns1': '192.168.0.1',
- 'dns2': '192.168.0.2',
- 'vlan': None,
- 'host': HOST,
- 'project_id': fakes.FAKE_PROJECT_ID,
- 'vpn_public_address': '192.168.1.2',
- 'vpn_public_port': '22',
- 'vpn_private_address': '10.0.0.2'}]
-
-fixed_ips = [{'id': 0,
- 'network_id': 0,
- 'address': '192.168.0.100',
- 'instance_uuid': 0,
- 'allocated': False,
- 'virtual_interface_id': 0,
- 'floating_ips': []},
- {'id': 0,
- 'network_id': 1,
- 'address': '192.168.1.100',
- 'instance_uuid': 0,
- 'allocated': False,
- 'virtual_interface_id': 0,
- 'floating_ips': []},
- {'id': 0,
- 'network_id': 1,
- 'address': '2001:db9:0:1::10',
- 'instance_uuid': 0,
- 'allocated': False,
- 'virtual_interface_id': 0,
- 'floating_ips': []}]
-
-
-flavor = {'id': 0,
- 'rxtx_cap': 3}
-
-
-floating_ip_fields = {'id': 0,
- 'address': '192.168.10.100',
- 'pool': 'nova',
- 'interface': 'eth0',
- 'fixed_ip_id': 0,
- 'project_id': None,
- 'auto_assigned': False}
-
-vifs = [{'id': 0,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:00',
- 'uuid': uuids.vif1_uuid,
- 'network_id': 0,
- 'instance_uuid': uuids.instance,
- 'tag': 'fake-tag1'},
- {'id': 1,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:01',
- 'uuid': '00000000-0000-0000-0000-0000000000000001',
- 'network_id': 1,
- 'instance_uuid': uuids.instance,
- 'tag': 'fake-tag2'},
- {'id': 2,
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'address': 'DE:AD:BE:EF:00:02',
- 'uuid': '00000000-0000-0000-0000-0000000000000002',
- 'network_id': 2,
- 'instance_uuid': uuids.instance,
- 'tag': 'fake-tag3'}]
-
-
-class FlatNetworkTestCase(test.TestCase):
-
- REQUIRES_LOCKING = True
-
- def setUp(self):
- super(FlatNetworkTestCase, self).setUp()
- self.tempdir = self.useFixture(fixtures.TempDir()).path
- self.flags(log_dir=self.tempdir)
- self.network = network_manager.FlatManager(host=HOST)
- self.network.instance_dns_domain = ''
- self.network.db = db
- self.context = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- def test_validate_networks(self):
- self.mox.StubOutWithMock(db, 'fixed_ip_get_by_address')
-
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- '192.168.1.100'),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
- '192.168.0.100')]
-
- ip = dict(test_fixed_ip.fake_fixed_ip, **fixed_ips[1])
- ip['network'] = dict(test_network.fake_network,
- **networks[1])
- ip['instance_uuid'] = None
- db.fixed_ip_get_by_address(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=mox.IgnoreArg()
- ).AndReturn(ip)
- ip = dict(test_fixed_ip.fake_fixed_ip, **fixed_ips[0])
- ip['network'] = dict(test_network.fake_network,
- **networks[0])
- ip['instance_uuid'] = None
- db.fixed_ip_get_by_address(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=mox.IgnoreArg()
- ).AndReturn(ip)
-
- self.mox.ReplayAll()
- self.network.validate_networks(self.context, requested_networks)
-
- def test_validate_networks_valid_fixed_ipv6(self):
- self.mox.StubOutWithMock(db, 'fixed_ip_get_by_address')
-
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- '2001:db9:0:1::10')]
-
- ip = dict(test_fixed_ip.fake_fixed_ip, **fixed_ips[2])
- ip['network'] = dict(test_network.fake_network,
- **networks[1])
- ip['instance_uuid'] = None
- db.fixed_ip_get_by_address(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=mox.IgnoreArg()
- ).AndReturn(ip)
-
- self.mox.ReplayAll()
- self.network.validate_networks(self.context, requested_networks)
-
- def test_validate_reserved(self):
- context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
- nets = self.network.create_networks(context_admin, 'fake',
- '192.168.0.0/24', False, 1,
- 256, None, None, None, None, None)
- self.assertEqual(1, len(nets))
- network = nets[0]
- self.assertEqual(4, db.network_count_reserved_ips(context_admin,
- network['id']))
-
- def test_validate_reserved_start_end(self):
- context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
- nets = self.network.create_networks(context_admin, 'fake',
- '192.168.0.0/24', False, 1,
- 256, dhcp_server='192.168.0.11',
- allowed_start='192.168.0.10',
- allowed_end='192.168.0.245')
- self.assertEqual(1, len(nets))
- network = nets[0]
- # gateway defaults to beginning of allowed_start
- self.assertEqual('192.168.0.10', network['gateway'])
- # vpn_server doesn't conflict with dhcp_start
- self.assertEqual('192.168.0.12', network['vpn_private_address'])
- # dhcp_start doesn't conflict with dhcp_server
- self.assertEqual('192.168.0.13', network['dhcp_start'])
- # NOTE(vish): 10 from the beginning, 10 from the end, and
- # 1 for the gateway, 1 for the dhcp server,
- # 1 for the vpn server
- self.assertEqual(23, db.network_count_reserved_ips(context_admin,
- network['id']))
-
- def test_validate_reserved_start_out_of_range(self):
- context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
- self.assertRaises(exception.AddressOutOfRange,
- self.network.create_networks,
- context_admin, 'fake', '192.168.0.0/24', False,
- 1, 256, allowed_start='192.168.1.10')
-
- def test_validate_reserved_end_invalid(self):
- context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
- self.assertRaises(exception.InvalidAddress,
- self.network.create_networks,
- context_admin, 'fake', '192.168.0.0/24', False,
- 1, 256, allowed_end='invalid')
-
- def test_validate_cidr_invalid(self):
- context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
- self.assertRaises(exception.InvalidCidr,
- self.network.create_networks,
- context_admin, 'fake', 'invalid', False,
- 1, 256)
-
- def test_validate_non_int_size(self):
- context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
- self.assertRaises(exception.InvalidIntValue,
- self.network.create_networks,
- context_admin, 'fake', '192.168.0.0/24', False,
- 1, 'invalid')
-
- def test_validate_networks_none_requested_networks(self):
- self.network.validate_networks(self.context, None)
-
- def test_validate_networks_empty_requested_networks(self):
- requested_networks = []
- self.mox.ReplayAll()
-
- self.network.validate_networks(self.context, requested_networks)
-
- def test_validate_networks_invalid_fixed_ip(self):
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- '192.168.1.100.1'),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
- '192.168.0.100.1')]
- self.mox.ReplayAll()
-
- self.assertRaises(exception.FixedIpInvalid,
- self.network.validate_networks, self.context,
- requested_networks)
-
- def test_validate_networks_empty_fixed_ip(self):
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- ''),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
- '')]
- self.mox.ReplayAll()
-
- self.assertRaises(exception.FixedIpInvalid,
- self.network.validate_networks,
- self.context, requested_networks)
-
- def test_validate_networks_none_fixed_ip(self):
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- None),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
- None)]
- self.mox.ReplayAll()
-
- self.network.validate_networks(self.context, requested_networks)
-
- @mock.patch('nova.objects.fixed_ip.FixedIPList.get_by_instance_uuid')
- def test_get_instance_nw_info(self, get):
-
- def make_ip(index):
- vif = objects.VirtualInterface(uuid=uuids.vif1_uuid, address=index)
- network = objects.Network(uuid=uuids.network_1,
- bridge=index,
- label=index,
- project_id=fakes.FAKE_PROJECT_ID,
- injected=False,
- netmask='255.255.255.0',
- dns1=None,
- dns2=None,
- cidr_v6=None,
- gateway_v6=None,
- broadcast_v6=None,
- netmask_v6=None,
- rxtx_base=None,
- gateway='192.168.%s.1' % index,
- dhcp_server='192.168.%s.1' % index,
- broadcast='192.168.%s.255' % index,
- cidr='192.168.%s.0/24' % index)
- return objects.FixedIP(virtual_interface=vif,
- network=network,
- floating_ips=objects.FloatingIPList(),
- address='192.168.%s.2' % index)
- objs = [make_ip(index) for index in ('3', '1', '2')]
- get.return_value = objects.FixedIPList(objects=objs)
- nw_info = self.network.get_instance_nw_info(self.context, None,
- None, None)
- for i, vif in enumerate(nw_info):
- self.assertEqual(objs[i].network.bridge, vif['network']['bridge'])
-
- @mock.patch.object(objects.Network, 'get_by_id')
- def test_add_fixed_ip_instance_using_id_without_vpn(self, get_by_id):
- # Allocate a fixed ip from a network and assign it to an instance.
- # Network is given by network id.
-
- network_id = networks[0]['id']
-
- with mock.patch.object(self.network,
- 'allocate_fixed_ip') as allocate_fixed_ip:
- self.network.add_fixed_ip_to_instance(self.context, FAKEUUID, HOST,
- network_id)
-
- # Assert that we fetched the network by id, not uuid
- get_by_id.assert_called_once_with(self.context,
- network_id, project_only='allow_none')
-
- # Assert that we called allocate_fixed_ip for the given network and
- # instance. We should not have requested a specific address from the
- # network.
- allocate_fixed_ip.assert_called_once_with(self.context, FAKEUUID,
- get_by_id.return_value,
- address=None)
-
- @mock.patch.object(objects.Network, 'get_by_uuid')
- def test_add_fixed_ip_instance_using_uuid_without_vpn(self, get_by_uuid):
- # Allocate a fixed ip from a network and assign it to an instance.
- # Network is given by network uuid.
-
- network_uuid = networks[0]['uuid']
-
- with mock.patch.object(self.network,
- 'allocate_fixed_ip') as allocate_fixed_ip,\
- mock.patch.object(self.context, 'elevated',
- return_value=mock.sentinel.elevated):
- self.network.add_fixed_ip_to_instance(self.context, FAKEUUID, HOST,
- network_uuid)
-
- # Assert that we fetched the network by uuid, not id, and with elevated
- # context
- get_by_uuid.assert_called_once_with(mock.sentinel.elevated,
- network_uuid)
-
- # Assert that we called allocate_fixed_ip for the given network and
- # instance. We should not have requested a specific address from the
- # network.
- allocate_fixed_ip.assert_called_once_with(self.context,
- FAKEUUID,
- get_by_uuid.return_value,
- address=None)
-
- def test_mini_dns_driver(self):
- zone1 = "example.org"
- zone2 = "example.com"
- driver = self.network.instance_dns_manager
- driver.create_entry("hostone", "10.0.0.1", "A", zone1)
- driver.create_entry("hosttwo", "10.0.0.2", "A", zone1)
- driver.create_entry("hostthree", "10.0.0.3", "A", zone1)
- driver.create_entry("hostfour", "10.0.0.4", "A", zone1)
- driver.create_entry("hostfive", "10.0.0.5", "A", zone2)
-
- driver.delete_entry("hostone", zone1)
- driver.modify_address("hostfour", "10.0.0.1", zone1)
- driver.modify_address("hostthree", "10.0.0.1", zone1)
- names = driver.get_entries_by_address("10.0.0.1", zone1)
- self.assertEqual(2, len(names))
- self.assertIn('hostthree', names)
- self.assertIn('hostfour', names)
-
- names = driver.get_entries_by_address("10.0.0.5", zone2)
- self.assertEqual(1, len(names))
- self.assertIn('hostfive', names)
-
- addresses = driver.get_entries_by_name("hosttwo", zone1)
- self.assertEqual(1, len(addresses))
- self.assertIn('10.0.0.2', addresses)
-
- self.assertRaises(exception.InvalidInput,
- driver.create_entry,
- "hostname",
- "10.10.10.10",
- "invalidtype",
- zone1)
-
- def test_mini_dns_driver_with_mixed_case(self):
- zone1 = "example.org"
- driver = self.network.instance_dns_manager
- driver.create_entry("HostTen", "10.0.0.10", "A", zone1)
- addresses = driver.get_entries_by_address("10.0.0.10", zone1)
- self.assertEqual(1, len(addresses))
- for n in addresses:
- driver.delete_entry(n, zone1)
- addresses = driver.get_entries_by_address("10.0.0.10", zone1)
- self.assertEqual(0, len(addresses))
-
- def test_allocate_fixed_ip_instance_dns(self):
- # Test DNS entries are created when allocating a fixed IP.
- # Allocate a fixed IP to an instance. Ensure that dns entries have been
- # created for the instance's name and uuid.
-
- network = network_obj.Network._from_db_object(
- self.context, network_obj.Network(), test_network.fake_network)
- network.save = mock.MagicMock()
-
- # Create a minimal instance object
- instance_params = {
- 'display_name': HOST,
- 'security_groups': []
- }
- instance = fake_instance.fake_instance_obj(
- context.RequestContext('ignore', 'ignore'),
- expected_attrs=instance_params.keys(), **instance_params)
- instance.save = mock.MagicMock()
-
- # We don't specify a specific address, so we should get a FixedIP
- # automatically allocated from the pool. Fix its value here.
- fip = objects.FixedIP(address='192.168.0.101')
- fip.save = mock.MagicMock()
-
- with mock.patch.object(objects.Instance, 'get_by_uuid',
- return_value=instance),\
- mock.patch.object(objects.FixedIP, 'associate_pool',
- return_value=fip):
- self.network.allocate_fixed_ip(self.context, FAKEUUID, network)
-
- instance_manager = self.network.instance_dns_manager
- expected_addresses = ['192.168.0.101']
-
- # Assert that we have a correct entry by instance display name
- addresses = instance_manager.get_entries_by_name(HOST,
- self.network.instance_dns_domain)
- self.assertEqual(expected_addresses, addresses)
-
- # Assert that we have a correct entry by instance uuid
- addresses = instance_manager.get_entries_by_name(FAKEUUID,
- self.network.instance_dns_domain)
- self.assertEqual(expected_addresses, addresses)
-
- def test_allocate_floating_ip(self):
- self.assertIsNone(self.network.allocate_floating_ip(self.context,
- 1, None))
-
- def test_deallocate_floating_ip(self):
- self.assertIsNone(self.network.deallocate_floating_ip(self.context,
- 1, None))
-
- def test_associate_floating_ip(self):
- self.assertIsNone(self.network.associate_floating_ip(self.context,
- None, None))
-
- def test_disassociate_floating_ip(self):
- self.assertIsNone(self.network.disassociate_floating_ip(self.context,
- None, None))
-
- def test_get_networks_by_uuids_ordering(self):
- self.mox.StubOutWithMock(db, 'network_get_all_by_uuids')
-
- requested_networks = ['bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa']
- db.network_get_all_by_uuids(mox.IgnoreArg(), mox.IgnoreArg(),
- mox.IgnoreArg()).AndReturn(
- [dict(test_network.fake_network, **net)
- for net in networks])
-
- self.mox.ReplayAll()
- res = self.network._get_networks_by_uuids(self.context,
- requested_networks)
-
- self.assertEqual(1, res[0]['id'])
- self.assertEqual(0, res[1]['id'])
-
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.quotas.Quotas.check_deltas')
- @mock.patch('nova.objects.quotas.ids_from_instance')
- def test_allocate_calculates_quota_auth(self, util_method, check,
- get_by_uuid):
- inst = objects.Instance()
- inst['uuid'] = uuids.instance
- get_by_uuid.return_value = inst
- check.side_effect = exception.OverQuota(overs='testing',
- quotas={'fixed_ips': 10},
- usages={'fixed_ips': 10})
- util_method.return_value = ('foo', 'bar')
- self.assertRaises(exception.FixedIpLimitExceeded,
- self.network.allocate_fixed_ip,
- self.context, 123, {'uuid': uuids.instance})
- util_method.assert_called_once_with(self.context, inst)
-
- @mock.patch('nova.objects.fixed_ip.FixedIP.disassociate')
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate_pool')
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.quotas.Quotas.check_deltas')
- @mock.patch('nova.objects.quotas.ids_from_instance')
- def test_allocate_over_quota_during_recheck(self, util_method, check,
- get_by_uuid, associate,
- disassociate):
- inst = objects.Instance()
- inst['uuid'] = uuids.instance
- get_by_uuid.return_value = inst
-
- # Simulate a race where the first check passes and the recheck fails.
- check.side_effect = [None, exception.OverQuota(
- overs='fixed_ips', quotas={'fixed_ips': 10},
- usages={'fixed_ips': 10})]
-
- util_method.return_value = ('foo', 'bar')
- address = netaddr.IPAddress('1.2.3.4')
- fip = objects.FixedIP(instance_uuid=inst.uuid,
- address=address,
- virtual_interface_id=1)
- associate.return_value = fip
-
- network = network_obj.Network._from_db_object(
- self.context, network_obj.Network(), test_network.fake_network)
- network.save = mock.MagicMock()
- self.assertRaises(exception.FixedIpLimitExceeded,
- self.network.allocate_fixed_ip,
- self.context, inst.uuid, network)
-
- self.assertEqual(2, check.call_count)
- call1 = mock.call(self.context, {'fixed_ips': 1}, 'foo')
- call2 = mock.call(self.context, {'fixed_ips': 0}, 'foo')
- check.assert_has_calls([call1, call2])
-
- # Verify we removed the fixed IP that was added after the first quota
- # check passed.
- disassociate.assert_called_once_with()
-
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate_pool')
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.quotas.Quotas.check_deltas')
- @mock.patch('nova.objects.quotas.ids_from_instance')
- def test_allocate_no_quota_recheck(self, util_method, check, get_by_uuid,
- associate):
- # Disable recheck_quota.
- self.flags(recheck_quota=False, group='quota')
-
- inst = objects.Instance()
- inst['uuid'] = uuids.instance
- inst['display_name'] = 'test'
- get_by_uuid.return_value = inst
-
- util_method.return_value = ('foo', 'bar')
- network = network_obj.Network._from_db_object(
- self.context, network_obj.Network(), test_network.fake_network)
- network.save = mock.MagicMock()
-
- @mock.patch.object(self.network, '_setup_network_on_host')
- @mock.patch.object(self.network, 'instance_dns_manager')
- @mock.patch.object(self.network,
- '_do_trigger_security_group_members_refresh_for_instance')
- def _test(trigger, dns, setup):
- self.network.allocate_fixed_ip(self.context, inst.uuid, network)
-
- _test()
-
- # check_deltas should have been called only once.
- check.assert_called_once_with(self.context, {'fixed_ips': 1}, 'foo')
-
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate')
- def test_allocate_fixed_ip_passes_string_address(self, mock_associate,
- mock_get):
- mock_associate.side_effect = test.TestingException
- instance = objects.Instance(context=self.context)
- instance.create()
- mock_get.return_value = instance
- self.assertRaises(test.TestingException,
- self.network.allocate_fixed_ip,
- self.context, instance.uuid,
- {'cidr': '24', 'id': 1, 'uuid': uuids.instance},
- address=netaddr.IPAddress('1.2.3.4'))
- mock_associate.assert_called_once_with(self.context,
- '1.2.3.4',
- instance.uuid,
- 1,
- vif_id=1)
-
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.virtual_interface.VirtualInterface'
- '.get_by_instance_and_network')
- @mock.patch('nova.objects.fixed_ip.FixedIP.disassociate')
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate')
- @mock.patch('nova.objects.fixed_ip.FixedIP.save')
- def test_allocate_fixed_ip_cleanup(self,
- mock_fixedip_save,
- mock_fixedip_associate,
- mock_fixedip_disassociate,
- mock_vif_get,
- mock_instance_get):
- address = netaddr.IPAddress('1.2.3.4')
-
- fip = objects.FixedIP(instance_uuid=uuids.instance,
- address=address,
- virtual_interface_id=1)
- mock_fixedip_associate.return_value = fip
-
- instance = objects.Instance(context=self.context)
- instance.create()
- mock_instance_get.return_value = instance
-
- mock_vif_get.return_value = vif_obj.VirtualInterface(
- instance_uuid=uuids.instance, id=1)
-
- with test.nested(
- mock.patch.object(self.network, '_setup_network_on_host'),
- mock.patch.object(self.network, 'instance_dns_manager'),
- mock.patch.object(self.network,
- '_do_trigger_security_group_members_refresh_for_instance')
- ) as (mock_setup_network, mock_dns_manager, mock_ignored):
- mock_setup_network.side_effect = test.TestingException
- self.assertRaises(test.TestingException,
- self.network.allocate_fixed_ip,
- self.context, instance.uuid,
- {'cidr': '24', 'id': 1,
- 'uuid': uuids.instance},
- address=address)
-
- mock_dns_manager.delete_entry.assert_has_calls([
- mock.call(instance.display_name, ''),
- mock.call(instance.uuid, '')
- ])
-
- mock_fixedip_disassociate.assert_called_once_with()
-
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.virtual_interface.VirtualInterface'
- '.get_by_instance_and_network')
- @mock.patch('nova.objects.fixed_ip.FixedIP.disassociate')
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate_pool')
- @mock.patch('nova.network.manager.NetworkManager._add_virtual_interface')
- def test_allocate_fixed_ip_create_new_vifs(self,
- mock_add,
- mock_fixedip_associate,
- mock_fixedip_disassociate,
- mock_vif_get,
- mock_instance_get):
- address = netaddr.IPAddress('1.2.3.4')
-
- fip = objects.FixedIP(instance_uuid=uuids.instance,
- address=address,
- virtual_interface_id=1000)
- net = {'cidr': '24', 'id': 1, 'uuid': uuids.instance}
- instance = objects.Instance(context=self.context)
- instance.create()
-
- vif = objects.VirtualInterface(context,
- id=1000,
- address='00:00:00:00:00:00',
- instance_uuid=instance.uuid,
- network_id=net['id'],
- uuid=uuids.instance)
- mock_fixedip_associate.return_value = fip
- mock_add.return_value = vif
- mock_instance_get.return_value = instance
- mock_vif_get.return_value = None
-
- with test.nested(
- mock.patch.object(self.network, '_setup_network_on_host'),
- mock.patch.object(self.network, 'instance_dns_manager'),
- mock.patch.object(self.network,
- '_do_trigger_security_group_members_refresh_for_instance')
- ) as (mock_setup_network, mock_dns_manager, mock_ignored):
- self.network.allocate_fixed_ip(self.context, instance['uuid'],
- net)
- mock_add.assert_called_once_with(self.context, instance['uuid'],
- net['id'])
- self.assertEqual(fip.virtual_interface_id, vif.id)
-
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch.object(db, 'virtual_interface_get_by_instance_and_network',
- return_value=None)
- @mock.patch('nova.objects.fixed_ip.FixedIP')
- def test_allocate_fixed_ip_add_vif_fails(self, mock_fixedip,
- mock_get_vif, mock_instance_get):
- # Tests that we don't try to do anything with fixed IPs if
- # _add_virtual_interface fails.
- instance = fake_instance.fake_instance_obj(self.context)
- mock_instance_get.return_value = instance
- network = {'cidr': '24', 'id': 1,
- 'uuid': '398399b3-f696-4859-8695-a6560e14cb02'}
- vif_error = exception.VirtualInterfaceMacAddressException()
- # mock out quotas because we don't care in this test
- with mock.patch.object(self.network, 'quotas_cls', objects.QuotasNoOp):
- with mock.patch.object(self.network, '_add_virtual_interface',
- side_effect=vif_error):
- self.assertRaises(
- exception.VirtualInterfaceMacAddressException,
- self.network.allocate_fixed_ip, self.context,
- '9d2ee1e3-ffad-4e5f-81ff-c96dd97b0ee0', network)
- self.assertFalse(mock_fixedip.called, str(mock_fixedip.mock_calls))
-
-
-class FlatDHCPNetworkTestCase(test.TestCase):
-
- REQUIRES_LOCKING = True
-
- def setUp(self):
- super(FlatDHCPNetworkTestCase, self).setUp()
- self.useFixture(test.SampleNetworks())
- self.network = network_manager.FlatDHCPManager(host=HOST)
- self.network.db = db
- self.context = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=False)
- self.context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
-
- @mock.patch('nova.objects.fixed_ip.FixedIP.get_by_id')
- @mock.patch('nova.objects.floating_ip.FloatingIPList.get_by_host')
- @mock.patch('nova.network.linux_net.iptables_manager._apply')
- @mock.patch('nova.privsep.linux_net.bind_ip')
- @mock.patch('nova.privsep.linux_net.modify_ebtables')
- def test_init_host_iptables_defer_apply(self, modify_ebtables,
- bind_ip, iptable_apply,
- floating_get_by_host,
- fixed_get_by_id):
- def get_by_id(context, fixed_ip_id, **kwargs):
- net = objects.Network(bridge='testbridge',
- cidr='192.168.1.0/24')
- if fixed_ip_id == 1:
- return objects.FixedIP(address='192.168.1.4',
- network=net)
- elif fixed_ip_id == 2:
- return objects.FixedIP(address='192.168.1.5',
- network=net)
-
- def fake_apply():
- fake_apply.count += 1
-
- fake_apply.count = 0
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=True)
- float1 = objects.FloatingIP(address='1.2.3.4', fixed_ip_id=1)
- float2 = objects.FloatingIP(address='1.2.3.5', fixed_ip_id=2)
- float1._context = ctxt
- float2._context = ctxt
-
- iptable_apply.side_effect = fake_apply
- floating_get_by_host.return_value = [float1, float2]
- fixed_get_by_id.side_effect = get_by_id
-
- self.network.init_host()
- self.assertEqual(1, fake_apply.count)
-
-
-class VlanNetworkTestCase(test.TestCase):
-
- REQUIRES_LOCKING = True
-
- def setUp(self):
- super(VlanNetworkTestCase, self).setUp()
- self.useFixture(test.SampleNetworks())
- self.network = network_manager.VlanManager(host=HOST)
- self.network.db = db
- self.context = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=False)
- self.context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
-
- def test_quota_driver_type(self):
- self.assertEqual(objects.QuotasNoOp,
- self.network.quotas_cls)
-
- @mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.routes_show', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.lookup_ip', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.change_ip')
- @mock.patch('nova.privsep.linux_net.address_command_deprecated')
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=False)
- @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.bridge_setfd')
- @mock.patch('nova.privsep.linux_net.bridge_disable_stp')
- @mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', ''))
- def test_vpn_allocate_fixed_ip(
- self, mock_bridge_add_interface, mock_bridge_disable_stp,
- mock_bridge_setfd, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_forwarding_enable,
- mock_forwarding_check, mock_address_command, mock_change_ip,
- mock_lookup_ip, mock_routes_show, mock_enabled, mock_add_bridge):
- self.mox.StubOutWithMock(db, 'fixed_ip_associate')
- self.mox.StubOutWithMock(db, 'fixed_ip_update')
- self.mox.StubOutWithMock(db,
- 'virtual_interface_get_by_instance_and_network')
- self.mox.StubOutWithMock(db, 'instance_get_by_uuid')
-
- fixed = dict(test_fixed_ip.fake_fixed_ip,
- address='192.168.0.1')
- db.fixed_ip_associate(mox.IgnoreArg(),
- mox.IgnoreArg(),
- mox.IgnoreArg(),
- network_id=mox.IgnoreArg(),
- reserved=True,
- virtual_interface_id=vifs[0]['id']
- ).AndReturn(fixed)
- db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
- mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(vifs[0])
- db.instance_get_by_uuid(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=['info_cache',
- 'security_groups']
- ).AndReturn(fake_inst(display_name=HOST,
- uuid=FAKEUUID))
- self.mox.ReplayAll()
-
- network = objects.Network._from_db_object(
- self.context, objects.Network(),
- dict(test_network.fake_network, **networks[0]))
- network.vpn_private_address = '192.168.0.2'
- self.network.allocate_fixed_ip(self.context, FAKEUUID, network,
- vpn=True)
-
- @mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.routes_show', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.lookup_ip', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.change_ip')
- @mock.patch('nova.privsep.linux_net.address_command_deprecated')
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=False)
- @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.bridge_setfd')
- @mock.patch('nova.privsep.linux_net.bridge_disable_stp')
- @mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', ''))
- def test_allocate_fixed_ip(
- self, mock_bridge_add_interface, mock_bridge_disable_stp,
- mock_bridge_setfd, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_forwarding_enable,
- mock_forwarding_check, mock_address_command, mock_change_ip,
- mock_lookup_ip, mock_routes_show, mock_enabled, mock_add_bridge):
- self.stubs.Set(self.network,
- '_do_trigger_security_group_members_refresh_for_instance',
- lambda *a, **kw: None)
- self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
- self.mox.StubOutWithMock(db,
- 'virtual_interface_get_by_instance_and_network')
- self.mox.StubOutWithMock(db, 'instance_get_by_uuid')
-
- fixed = dict(test_fixed_ip.fake_fixed_ip,
- address='192.168.0.1')
- db.fixed_ip_associate_pool(mox.IgnoreArg(),
- mox.IgnoreArg(),
- instance_uuid=mox.IgnoreArg(),
- host=None,
- virtual_interface_id=vifs[0]['id']
- ).AndReturn(fixed)
- db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
- mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(vifs[0])
- db.instance_get_by_uuid(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=['info_cache',
- 'security_groups']
- ).AndReturn(fake_inst(display_name=HOST,
- uuid=FAKEUUID))
- self.mox.ReplayAll()
-
- network = objects.Network._from_db_object(
- self.context, objects.Network(),
- dict(test_network.fake_network, **networks[0]))
- network.vpn_private_address = '192.168.0.2'
- self.network.allocate_fixed_ip(self.context, FAKEUUID, network)
-
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate_pool')
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.QuotasNoOp.check_deltas')
- @mock.patch('nova.objects.quotas.ids_from_instance')
- def test_allocate_fixed_ip_super_call(self, mock_ids, mock_check, mock_get,
- mock_associate):
- # No code in the VlanManager actually calls
- # NetworkManager.allocate_fixed_ip() at this time. This is just to
- # test that if it did, it would call through the QuotasNoOp class.
- inst = objects.Instance()
- inst['uuid'] = uuids.instance
- inst['display_name'] = 'test'
- mock_get.return_value = inst
-
- mock_ids.return_value = ('foo', 'bar')
-
- network = network_obj.Network._from_db_object(
- self.context, network_obj.Network(), test_network.fake_network)
- network.save = mock.MagicMock()
-
- @mock.patch.object(self.network, '_setup_network_on_host')
- @mock.patch.object(self.network, 'instance_dns_manager')
- @mock.patch.object(self.network,
- '_do_trigger_security_group_members_refresh_for_instance')
- def _test(trigger, dns, setup):
- super(network_manager.VlanManager, self.network).allocate_fixed_ip(
- self.context, FAKEUUID, network)
-
- _test()
-
- # Make sure we called the QuotasNoOp.check_deltas() for VlanManager.
- self.assertEqual(2, mock_check.call_count)
-
- @mock.patch('nova.network.manager.VlanManager._setup_network_on_host')
- @mock.patch('nova.network.manager.VlanManager.'
- '_validate_instance_zone_for_dns_domain')
- @mock.patch('nova.network.manager.VlanManager.'
- '_do_trigger_security_group_members_refresh_for_instance')
- @mock.patch('nova.network.manager.VlanManager._add_virtual_interface')
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate')
- @mock.patch('nova.objects.VirtualInterface.get_by_instance_and_network')
- def test_allocate_fixed_ip_return_none(self, mock_get,
- mock_associate, mock_get_uuid, mock_add, mock_trigger,
- mock_validate, mock_setup):
- net = {'cidr': '24', 'id': 1, 'uuid': uuids.instance}
- fip = objects.FixedIP(instance_uuid=uuids.instance,
- address=netaddr.IPAddress('1.2.3.4'),
- virtual_interface_id=1)
-
- instance = objects.Instance(context=self.context)
- instance.create()
-
- vif = objects.VirtualInterface(self.context,
- id=1000,
- address='00:00:00:00:00:00',
- instance_uuid=instance.uuid,
- network_id=net['id'],
- uuid=uuids.instance)
- mock_associate.return_value = fip
- mock_add.return_value = vif
- mock_get.return_value = None
- mock_get_uuid.return_value = instance
- mock_validate.return_value = False
-
- self.network.allocate_fixed_ip(self.context_admin, instance.uuid, net)
-
- mock_add.assert_called_once_with(self.context_admin, instance.uuid,
- net['id'])
-
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate')
- def test_allocate_fixed_ip_passes_string_address(self, mock_associate,
- mock_get):
- mock_associate.side_effect = test.TestingException
- instance = objects.Instance(context=self.context)
- instance.create()
- mock_get.return_value = instance
- self.assertRaises(test.TestingException,
- self.network.allocate_fixed_ip,
- self.context, instance.uuid,
- {'cidr': '24', 'id': 1, 'uuid': uuids.instance},
- address=netaddr.IPAddress('1.2.3.4'))
- mock_associate.assert_called_once_with(self.context,
- '1.2.3.4',
- instance.uuid,
- 1,
- vif_id=1)
-
- @mock.patch('nova.objects.instance.Instance.get_by_uuid')
- @mock.patch('nova.objects.fixed_ip.FixedIP.associate')
- def test_allocate_fixed_ip_passes_string_address_vpn(self, mock_associate,
- mock_get):
- mock_associate.side_effect = test.TestingException
- instance = objects.Instance(context=self.context)
- instance.create()
- mock_get.return_value = instance
- self.assertRaises(test.TestingException,
- self.network.allocate_fixed_ip,
- self.context, instance.uuid,
- {'cidr': '24', 'id': 1, 'uuid': uuids.instance,
- 'vpn_private_address': netaddr.IPAddress('1.2.3.4')
- }, vpn=1)
- mock_associate.assert_called_once_with(self.context,
- '1.2.3.4',
- instance.uuid,
- 1, reserved=True,
- vif_id=1)
-
- @mock.patch.object(db, 'virtual_interface_get_by_instance_and_network',
- return_value=None)
- @mock.patch('nova.objects.fixed_ip.FixedIP')
- def test_allocate_fixed_ip_add_vif_fails(self, mock_fixedip,
- mock_get_vif):
- # Tests that we don't try to do anything with fixed IPs if
- # _add_virtual_interface fails.
- vif_error = exception.VirtualInterfaceMacAddressException()
- with mock.patch.object(self.network, '_add_virtual_interface',
- side_effect=vif_error):
- self.assertRaises(exception.VirtualInterfaceMacAddressException,
- self.network.allocate_fixed_ip, self.context,
- '9d2ee1e3-ffad-4e5f-81ff-c96dd97b0ee0',
- networks[0])
- self.assertFalse(mock_fixedip.called, str(mock_fixedip.mock_calls))
-
- def test_create_networks_too_big(self):
- self.assertRaises(ValueError, self.network.create_networks, None,
- num_networks=4094, vlan_start=1)
-
- def test_create_networks_too_many(self):
- self.assertRaises(ValueError, self.network.create_networks, None,
- num_networks=100, vlan_start=1,
- cidr='192.168.0.1/24', network_size=100)
-
- def test_duplicate_vlan_raises(self):
- # VLAN 100 is already used and we force the network to be created
- # in that vlan (vlan=100).
- self.assertRaises(exception.DuplicateVlan,
- self.network.create_networks,
- self.context_admin, label="fake", num_networks=1,
- vlan=100, cidr='192.168.0.1/24', network_size=100)
-
- def test_vlan_start(self):
- # VLAN 100 and 101 are used, so this network should be created in 102
- networks = self.network.create_networks(
- self.context_admin, label="fake", num_networks=1,
- vlan_start=100, cidr='192.168.3.1/24',
- network_size=100)
-
- self.assertEqual(102, networks[0]["vlan"])
-
- def test_vlan_start_multiple(self):
- # VLAN 100 and 101 are used, so these networks should be created in 102
- # and 103
- networks = self.network.create_networks(
- self.context_admin, label="fake", num_networks=2,
- vlan_start=100, cidr='192.168.3.1/24',
- network_size=100)
-
- self.assertEqual(102, networks[0]["vlan"])
- self.assertEqual(103, networks[1]["vlan"])
-
- def test_vlan_start_used(self):
- # VLAN 100 and 101 are used, but vlan_start=99.
- networks = self.network.create_networks(
- self.context_admin, label="fake", num_networks=1,
- vlan_start=99, cidr='192.168.3.1/24',
- network_size=100)
-
- self.assertEqual(102, networks[0]["vlan"])
-
- def test_vlan_parameter(self):
- # vlan parameter could not be greater than 4094
- exc = self.assertRaises(ValueError,
- self.network.create_networks,
- self.context_admin, label="fake",
- num_networks=1,
- vlan=4095, cidr='192.168.0.1/24')
- error_msg = 'The vlan number cannot be greater than 4094'
- self.assertIn(error_msg, six.text_type(exc))
-
- # vlan parameter could not be less than 1
- exc = self.assertRaises(ValueError,
- self.network.create_networks,
- self.context_admin, label="fake",
- num_networks=1,
- vlan=0, cidr='192.168.0.1/24')
- error_msg = 'The vlan number cannot be less than 1'
- self.assertIn(error_msg, six.text_type(exc))
-
- def test_vlan_be_integer(self):
- # vlan must be an integer
- exc = self.assertRaises(ValueError,
- self.network.create_networks,
- self.context_admin, label="fake",
- num_networks=1,
- vlan='fake', cidr='192.168.0.1/24')
- error_msg = 'vlan must be an integer'
- self.assertIn(error_msg, six.text_type(exc))
-
- def test_vlan_multiple_without_dhcp_server(self):
- networks = self.network.create_networks(
- self.context_admin, label="fake", num_networks=2,
- vlan_start=100, cidr='192.168.3.1/24',
- network_size=100)
-
- self.assertEqual("192.168.3.1", networks[0]["dhcp_server"])
- self.assertEqual("192.168.3.129", networks[1]["dhcp_server"])
-
- def test_vlan_multiple_with_dhcp_server(self):
- networks = self.network.create_networks(
- self.context_admin, label="fake", num_networks=2,
- vlan_start=100, cidr='192.168.3.1/24',
- network_size=100, dhcp_server='192.168.3.1')
-
- self.assertEqual("192.168.3.1", networks[0]["dhcp_server"])
- self.assertEqual("192.168.3.1", networks[1]["dhcp_server"])
-
- def test_validate_networks(self):
- self.mox.StubOutWithMock(db, "fixed_ip_get_by_address")
-
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- '192.168.1.100'),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
- '192.168.0.100')]
-
- db_fixed1 = dict(test_fixed_ip.fake_fixed_ip,
- network_id=networks[1]['id'],
- network=dict(test_network.fake_network,
- **networks[1]),
- instance_uuid=None)
- db.fixed_ip_get_by_address(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=mox.IgnoreArg()
- ).AndReturn(db_fixed1)
- db_fixed2 = dict(test_fixed_ip.fake_fixed_ip,
- network_id=networks[0]['id'],
- network=dict(test_network.fake_network,
- **networks[0]),
- instance_uuid=None)
- db.fixed_ip_get_by_address(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=mox.IgnoreArg()
- ).AndReturn(db_fixed2)
-
- self.mox.ReplayAll()
- self.network.validate_networks(self.context, requested_networks)
-
- def test_validate_networks_none_requested_networks(self):
- self.network.validate_networks(self.context, None)
-
- def test_validate_networks_empty_requested_networks(self):
- requested_networks = []
- self.mox.ReplayAll()
-
- self.network.validate_networks(self.context, requested_networks)
-
- def test_validate_networks_invalid_fixed_ip(self):
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- '192.168.1.100.1'),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
- '192.168.0.100.1')]
- self.mox.ReplayAll()
-
- self.assertRaises(exception.FixedIpInvalid,
- self.network.validate_networks, self.context,
- requested_networks)
-
- def test_validate_networks_empty_fixed_ip(self):
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', ''),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', '')]
- self.mox.ReplayAll()
-
- self.assertRaises(exception.FixedIpInvalid,
- self.network.validate_networks,
- self.context, requested_networks)
-
- def test_validate_networks_none_fixed_ip(self):
- requested_networks = [('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', None),
- ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', None)]
- self.mox.ReplayAll()
- self.network.validate_networks(self.context, requested_networks)
-
- def test_floating_ip_owned_by_project(self):
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- # raises because floating_ip project_id is None
- floating_ip = objects.FloatingIP(address='10.0.0.1',
- project_id=None)
- self.assertRaises(exception.Forbidden,
- self.network._floating_ip_owned_by_project,
- ctxt,
- floating_ip)
-
- # raises because floating_ip project_id is not equal to ctxt project_id
- floating_ip = objects.FloatingIP(address='10.0.0.1',
- project_id=uuids.non_existent_uuid)
- self.assertRaises(exception.Forbidden,
- self.network._floating_ip_owned_by_project,
- ctxt,
- floating_ip)
-
- # does not raise (floating ip is owned by ctxt project)
- floating_ip = objects.FloatingIP(address='10.0.0.1',
- project_id=ctxt.project_id)
- self.network._floating_ip_owned_by_project(ctxt, floating_ip)
-
- ctxt = context.RequestContext(None, None,
- is_admin=True)
-
- # does not raise (ctxt is admin)
- floating_ip = objects.FloatingIP(address='10.0.0.1',
- project_id=None)
- self.network._floating_ip_owned_by_project(ctxt, floating_ip)
-
- # does not raise (ctxt is admin)
- floating_ip = objects.FloatingIP(address='10.0.0.1',
- project_id=fakes.FAKE_PROJECT_ID)
- self.network._floating_ip_owned_by_project(ctxt, floating_ip)
-
- def test_allocate_floating_ip(self):
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- self.stubs.Set(self.network, '_floating_ip_pool_exists',
- lambda _x, _y: True)
-
- def fake_allocate_address(*args, **kwargs):
- return {'address': '10.0.0.1', 'project_id': ctxt.project_id}
-
- self.stubs.Set(self.network.db, 'floating_ip_allocate_address',
- fake_allocate_address)
-
- self.network.allocate_floating_ip(ctxt, ctxt.project_id)
-
- @mock.patch('nova.objects.FloatingIP.deallocate')
- @mock.patch('nova.network.floating_ips.FloatingIP.'
- '_floating_ip_owned_by_project')
- @mock.patch('nova.objects.FloatingIP.get_by_address')
- def test_deallocate_floating_ip(self, mock_get, mock_owned, mock_dealloc):
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- def fake1(*args, **kwargs):
- params = dict(test_floating_ip.fake_floating_ip)
- return objects.FloatingIP(**params)
-
- def fake2(*args, **kwargs):
- params = dict(test_floating_ip.fake_floating_ip,
- address='10.0.0.1', fixed_ip_id=1)
- return objects.FloatingIP(**params)
-
- def fake3(*args, **kwargs):
- params = dict(test_floating_ip.fake_floating_ip,
- address='10.0.0.1', fixed_ip_id=None,
- project_id=ctxt.project_id)
- return objects.FloatingIP(**params)
-
- mock_dealloc.side_effect = fake1
- mock_owned.side_effect = fake1
- mock_get.side_effect = fake2
-
- # this time should raise because floating ip is associated to
- # fixed_ip
- self.assertRaises(exception.FloatingIpAssociated,
- self.network.deallocate_floating_ip,
- ctxt,
- 'fake-address')
- mock_dealloc.assert_not_called()
-
- # this time should not raise
- mock_dealloc.reset_mock()
- mock_get.side_effect = fake3
-
- self.network.deallocate_floating_ip(ctxt, 'fake-address')
- mock_dealloc.assert_called_once_with(ctxt, 'fake-address')
-
- @mock.patch('nova.db.api.fixed_ip_get')
- def test_associate_floating_ip(self, fixed_get):
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- def fake1(*args, **kwargs):
- return dict(test_fixed_ip.fake_fixed_ip,
- address='10.0.0.1',
- network=test_network.fake_network)
-
- # floating ip that's already associated
- def fake2(*args, **kwargs):
- return dict(test_floating_ip.fake_floating_ip,
- address='10.0.0.1',
- pool='nova',
- interface='eth0',
- fixed_ip_id=1)
-
- # floating ip that isn't associated
- def fake3(*args, **kwargs):
- return dict(test_floating_ip.fake_floating_ip,
- address='10.0.0.1',
- pool='nova',
- interface='eth0',
- fixed_ip_id=None)
-
- # fixed ip with remote host
- def fake4(*args, **kwargs):
- return dict(test_fixed_ip.fake_fixed_ip,
- address='10.0.0.1',
- pool='nova',
- instance_uuid=FAKEUUID,
- interface='eth0',
- network_id=123)
-
- def fake4_network(*args, **kwargs):
- return dict(test_network.fake_network,
- multi_host=False, host='jibberjabber')
-
- # fixed ip with local host
- def fake5(*args, **kwargs):
- return dict(test_fixed_ip.fake_fixed_ip,
- address='10.0.0.1',
- pool='nova',
- instance_uuid=FAKEUUID,
- interface='eth0',
- network_id=1234)
-
- def fake5_network(*args, **kwargs):
- return dict(test_network.fake_network,
- multi_host=False, host='testhost')
-
- def fake6(ctxt, method, **kwargs):
- self.local = False
-
- def fake7(*args, **kwargs):
- self.local = True
-
- def fake8(*args, **kwargs):
- raise processutils.ProcessExecutionError('',
- 'Cannot find device "em0"\n')
-
- def fake9(*args, **kwargs):
- raise test.TestingException()
-
- # raises because interface doesn't exist
- self.stubs.Set(self.network.db,
- 'floating_ip_fixed_ip_associate',
- fake1)
- self.stubs.Set(self.network.db, 'floating_ip_disassociate', fake1)
- self.stubs.Set(self.network.driver, 'ensure_floating_forward', fake8)
- self.assertRaises(exception.NoFloatingIpInterface,
- self.network._associate_floating_ip,
- ctxt,
- '1.2.3.4',
- '1.2.3.5',
- mox.IgnoreArg(),
- mox.IgnoreArg())
-
- self.stubs.Set(self.network, '_floating_ip_owned_by_project', fake1)
-
- # raises because floating_ip is already associated to a fixed_ip
- self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake2)
- self.stubs.Set(self.network, 'disassociate_floating_ip', fake9)
-
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- address='1.2.3.4',
- instance_uuid=uuids.instance,
- network=test_network.fake_network)
-
- # doesn't raise because we exit early if the address is the same
- self.network.associate_floating_ip(ctxt, mox.IgnoreArg(), '1.2.3.4')
-
- # raises because we call disassociate which is mocked
- self.assertRaises(test.TestingException,
- self.network.associate_floating_ip,
- ctxt,
- mox.IgnoreArg(),
- 'new')
-
- self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake3)
-
- # does not raise and makes call remotely
- self.local = True
- self.stubs.Set(self.network.db, 'fixed_ip_get_by_address', fake4)
- self.stubs.Set(self.network.db, 'network_get', fake4_network)
- self.stubs.Set(self.network.network_rpcapi.client, 'prepare',
- lambda **kw: self.network.network_rpcapi.client)
- self.stubs.Set(self.network.network_rpcapi.client, 'call', fake6)
- self.network.associate_floating_ip(ctxt, mox.IgnoreArg(),
- mox.IgnoreArg())
- self.assertFalse(self.local)
-
- # does not raise and makes call locally
- self.local = False
- self.stubs.Set(self.network.db, 'fixed_ip_get_by_address', fake5)
- self.stubs.Set(self.network.db, 'network_get', fake5_network)
- self.stubs.Set(self.network, '_associate_floating_ip', fake7)
- self.network.associate_floating_ip(ctxt, mox.IgnoreArg(),
- mox.IgnoreArg())
- self.assertTrue(self.local)
-
- def test_add_floating_ip_nat_before_bind(self):
- # Tried to verify order with documented mox record/verify
- # functionality, but it doesn't seem to work since I can't make it
- # fail. I'm using stubs and a flag for now, but if this mox feature
- # can be made to work, it would be a better way to test this.
- #
- # self.mox.StubOutWithMock(self.network.driver,
- # 'ensure_floating_forward')
- # self.mox.StubOutWithMock(self.network.driver, 'bind_floating_ip')
- #
- # self.network.driver.ensure_floating_forward(mox.IgnoreArg(),
- # mox.IgnoreArg(),
- # mox.IgnoreArg(),
- # mox.IgnoreArg())
- # self.network.driver.bind_floating_ip(mox.IgnoreArg(),
- # mox.IgnoreArg())
- # self.mox.ReplayAll()
-
- nat_called = [False]
-
- def fake_nat(*args, **kwargs):
- nat_called[0] = True
-
- def fake_bind(*args, **kwargs):
- self.assertTrue(nat_called[0])
-
- self.stubs.Set(self.network.driver,
- 'ensure_floating_forward',
- fake_nat)
- self.stubs.Set(self.network.driver, 'bind_floating_ip', fake_bind)
-
- self.network.l3driver.add_floating_ip('fakefloat',
- 'fakefixed',
- 'fakeiface',
- 'fakenet')
-
- @mock.patch('nova.db.api.floating_ip_get_all_by_host')
- @mock.patch('nova.db.api.fixed_ip_get')
- def _test_floating_ip_init_host(self, fixed_get, floating_get,
- public_interface, expected_arg):
-
- floating_get.return_value = [
- dict(test_floating_ip.fake_floating_ip,
- interface='foo',
- address='1.2.3.4'),
- dict(test_floating_ip.fake_floating_ip,
- interface='fakeiface',
- address='1.2.3.5',
- fixed_ip_id=1),
- dict(test_floating_ip.fake_floating_ip,
- interface='bar',
- address='1.2.3.6',
- fixed_ip_id=2),
- ]
-
- def fixed_ip_get(_context, fixed_ip_id, get_network):
- if fixed_ip_id == 1:
- return dict(test_fixed_ip.fake_fixed_ip,
- address='1.2.3.4',
- network=test_network.fake_network)
- raise exception.FixedIpNotFound(id=fixed_ip_id)
- fixed_get.side_effect = fixed_ip_get
-
- self.mox.StubOutWithMock(self.network.l3driver, 'add_floating_ip')
- self.flags(public_interface=public_interface)
- self.network.l3driver.add_floating_ip(netaddr.IPAddress('1.2.3.5'),
- netaddr.IPAddress('1.2.3.4'),
- expected_arg,
- mox.IsA(objects.Network))
- self.mox.ReplayAll()
- self.network.init_host_floating_ips()
- self.mox.UnsetStubs()
- self.mox.VerifyAll()
-
- def test_floating_ip_init_host_without_public_interface(self):
- self._test_floating_ip_init_host(public_interface='',
- expected_arg='fakeiface')
-
- def test_floating_ip_init_host_with_public_interface(self):
- self._test_floating_ip_init_host(public_interface='fooiface',
- expected_arg='fooiface')
-
- def test_disassociate_floating_ip(self):
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- def fake1(*args, **kwargs):
- pass
-
- # floating ip that isn't associated
- def fake2(*args, **kwargs):
- return dict(test_floating_ip.fake_floating_ip,
- address='10.0.0.1',
- pool='nova',
- interface='eth0',
- fixed_ip_id=None)
-
- # floating ip that is associated
- def fake3(*args, **kwargs):
- return dict(test_floating_ip.fake_floating_ip,
- address='10.0.0.1',
- pool='nova',
- interface='eth0',
- fixed_ip_id=1,
- project_id=ctxt.project_id)
-
- # fixed ip with remote host
- def fake4(*args, **kwargs):
- return dict(test_fixed_ip.fake_fixed_ip,
- address='10.0.0.1',
- pool='nova',
- instance_uuid=FAKEUUID,
- interface='eth0',
- network_id=123)
-
- def fake4_network(*args, **kwargs):
- return dict(test_network.fake_network,
- multi_host=False,
- host='jibberjabber')
-
- # fixed ip with local host
- def fake5(*args, **kwargs):
- return dict(test_fixed_ip.fake_fixed_ip,
- address='10.0.0.1',
- pool='nova',
- instance_uuid=FAKEUUID,
- interface='eth0',
- network_id=1234)
-
- def fake5_network(*args, **kwargs):
- return dict(test_network.fake_network,
- multi_host=False, host='testhost')
-
- def fake6(ctxt, method, **kwargs):
- self.local = False
-
- def fake7(*args, **kwargs):
- self.local = True
-
- def fake8(*args, **kwargs):
- return dict(test_floating_ip.fake_floating_ip,
- address='10.0.0.1',
- pool='nova',
- interface='eth0',
- fixed_ip_id=1,
- auto_assigned=True,
- project_id=ctxt.project_id)
-
- self.stubs.Set(self.network, '_floating_ip_owned_by_project', fake1)
-
- # raises because floating_ip is not associated to a fixed_ip
- self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake2)
- self.assertRaises(exception.FloatingIpNotAssociated,
- self.network.disassociate_floating_ip,
- ctxt,
- mox.IgnoreArg())
-
- self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake3)
-
- # does not raise and makes call remotely
- self.local = True
- self.stubs.Set(self.network.db, 'fixed_ip_get', fake4)
- self.stubs.Set(self.network.db, 'network_get', fake4_network)
- self.stubs.Set(self.network.network_rpcapi.client, 'prepare',
- lambda **kw: self.network.network_rpcapi.client)
- self.stubs.Set(self.network.network_rpcapi.client, 'call', fake6)
- self.network.disassociate_floating_ip(ctxt, mox.IgnoreArg())
- self.assertFalse(self.local)
-
- # does not raise and makes call locally
- self.local = False
- self.stubs.Set(self.network.db, 'fixed_ip_get', fake5)
- self.stubs.Set(self.network.db, 'network_get', fake5_network)
- self.stubs.Set(self.network, '_disassociate_floating_ip', fake7)
- self.network.disassociate_floating_ip(ctxt, mox.IgnoreArg())
- self.assertTrue(self.local)
-
- # raises because auto_assigned floating IP cannot be disassociated
- self.stubs.Set(self.network.db, 'floating_ip_get_by_address', fake8)
- self.assertRaises(exception.CannotDisassociateAutoAssignedFloatingIP,
- self.network.disassociate_floating_ip,
- ctxt,
- mox.IgnoreArg())
-
- @mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.routes_show',
- return_value=('fake', 0))
- @mock.patch('nova.privsep.linux_net.lookup_ip', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.change_ip')
- @mock.patch('nova.privsep.linux_net.address_command_deprecated')
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=False)
- @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.bridge_setfd')
- @mock.patch('nova.privsep.linux_net.bridge_disable_stp')
- @mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', ''))
- def test_add_fixed_ip_instance_without_vpn_requested_networks(
- self, mock_bridge_add_interface, mock_bridge_disable_stp,
- mock_bridge_setfd, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_forwarding_enable,
- mock_forwarding_check, mock_address_command, mock_change_ip,
- mock_lookup_ip, mock_routes_show, mock_enabled, mock_add_bridge):
- self.stubs.Set(self.network,
- '_do_trigger_security_group_members_refresh_for_instance',
- lambda *a, **kw: None)
- self.mox.StubOutWithMock(db, 'network_get')
- self.mox.StubOutWithMock(db, 'fixed_ip_associate_pool')
- self.mox.StubOutWithMock(db,
- 'virtual_interface_get_by_instance_and_network')
- self.mox.StubOutWithMock(db, 'instance_get_by_uuid')
- self.mox.StubOutWithMock(self.network, 'get_instance_nw_info')
-
- db.virtual_interface_get_by_instance_and_network(mox.IgnoreArg(),
- mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(vifs[0])
-
- fixed = dict(test_fixed_ip.fake_fixed_ip,
- address='192.168.0.101')
- db.fixed_ip_associate_pool(mox.IgnoreArg(),
- mox.IgnoreArg(),
- instance_uuid=mox.IgnoreArg(),
- host=None,
- virtual_interface_id=vifs[0]['id']
- ).AndReturn(fixed)
- db.network_get(mox.IgnoreArg(),
- mox.IgnoreArg(),
- project_only=mox.IgnoreArg()
- ).AndReturn(dict(test_network.fake_network,
- **networks[0]))
- db.instance_get_by_uuid(mox.IgnoreArg(),
- mox.IgnoreArg(),
- columns_to_join=['info_cache',
- 'security_groups']
- ).AndReturn(fake_inst(display_name=HOST,
- uuid=FAKEUUID))
- self.network.get_instance_nw_info(mox.IgnoreArg(), mox.IgnoreArg(),
- mox.IgnoreArg(), mox.IgnoreArg())
- self.mox.ReplayAll()
- self.network.add_fixed_ip_to_instance(self.context, FAKEUUID, HOST,
- networks[0]['id'])
-
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.privsep.linux_net.bind_ip')
- @mock.patch('nova.privsep.linux_net.unbind_ip')
- @mock.patch('nova.privsep.linux_net.clean_conntrack')
- @mock.patch('nova.privsep.linux_net.modify_ebtables')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def test_ip_association_and_allocation_of_other_project(
- self, mock_iptables_set_rules, mock_iptables_get_rules,
- modify_ebtables, clean_conntrack, unbind_ip, bind_ip,
- net_get, fixed_get):
- """Makes sure that we cannot deallocaate or disassociate
- a public IP of other project.
- """
- net_get.return_value = dict(test_network.fake_network,
- **networks[1])
-
- context1 = context.RequestContext('user', fakes.FAKE_PROJECT_ID)
- context2 = context.RequestContext('user', 'project2')
-
- float_ip = db.floating_ip_create(context1.elevated(),
- {'address': '1.2.3.4',
- 'project_id': context1.project_id})
-
- float_addr = float_ip['address']
-
- instance = db.instance_create(context1,
- {'project_id': fakes.FAKE_PROJECT_ID})
-
- fix_addr = db.fixed_ip_associate_pool(context1.elevated(),
- 1, instance['uuid']).address
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- address=fix_addr,
- instance_uuid=instance.uuid,
- network=dict(test_network.fake_network,
- **networks[1]))
-
- # Associate the IP with non-admin user context
- self.assertRaises(exception.Forbidden,
- self.network.associate_floating_ip,
- context2,
- float_addr,
- fix_addr)
-
- # Deallocate address from other project
- self.assertRaises(exception.Forbidden,
- self.network.deallocate_floating_ip,
- context2,
- float_addr)
-
- # Now Associates the address to the actual project
- self.network.associate_floating_ip(context1, float_addr, fix_addr)
-
- # Now try dis-associating from other project
- self.assertRaises(exception.Forbidden,
- self.network.disassociate_floating_ip,
- context2,
- float_addr)
-
- # Clean up the ip addresses
- self.network.disassociate_floating_ip(context1, float_addr)
- self.network.deallocate_floating_ip(context1, float_addr)
- self.network.deallocate_fixed_ip(context1, fix_addr, 'fake')
- db.floating_ip_destroy(context1.elevated(), float_addr)
- db.fixed_ip_disassociate(context1.elevated(), fix_addr)
-
- @mock.patch('nova.network.rpcapi.NetworkAPI.release_dhcp')
- @mock.patch('nova.db.api.virtual_interface_get')
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.fixed_ip_update')
- def test_deallocate_fixed(self, fixed_update, net_get, fixed_get,
- vif_get, release_dhcp):
- """Verify that release is called properly.
-
- Ensures https://bugs.launchpad.net/nova/+bug/973442 doesn't return
- """
- net_get.return_value = dict(test_network.fake_network,
- **networks[1])
- vif_get.return_value = vifs[0]
- context1 = context.RequestContext('user', fakes.FAKE_PROJECT_ID)
-
- instance = db.instance_create(context1,
- {'project_id': fakes.FAKE_PROJECT_ID})
-
- elevated = context1.elevated()
- fix_addr = db.fixed_ip_associate_pool(elevated, 1, instance['uuid'])
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- address=fix_addr.address,
- instance_uuid=instance.uuid,
- allocated=True,
- virtual_interface_id=3,
- network=dict(test_network.fake_network,
- **networks[1]))
-
- self.flags(force_dhcp_release=True)
- self.network.deallocate_fixed_ip(context1, fix_addr.address, 'fake')
- fixed_update.assert_called_once_with(context1, fix_addr.address,
- {'allocated': False})
- release_dhcp.assert_called_once_with(context1, None,
- networks[1]['bridge'],
- fix_addr.address,
- 'DE:AD:BE:EF:00:00')
-
- @mock.patch.object(linux_net, 'release_dhcp')
- @mock.patch('nova.network.rpcapi.NetworkAPI.release_dhcp')
- @mock.patch('nova.db.api.virtual_interface_get')
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.fixed_ip_update')
- def test_deallocate_fixed_rpc_pinned(self, fixed_update, net_get,
- fixed_get, vif_get,
- release_dhcp,
- net_release_dhcp):
- """Ensure that if the RPC call to release_dhcp raises a
- RPCPinnedToOldVersion, we fall back to the previous behaviour of
- calling release_dhcp in the local linux_net driver. In the previous
- test, release_dhcp was mocked to call the driver, since this is what
- happens on a successful RPC call. In this test, we mock it to raise,
- but the expected behaviour is exactly the same - namely that
- release_dhcp is called in the linux_net driver, which is why the two
- tests are otherwise identical.
- """
- net_get.return_value = dict(test_network.fake_network,
- **networks[1])
- vif_get.return_value = vifs[0]
- release_dhcp.side_effect = exception.RPCPinnedToOldVersion()
- context1 = context.RequestContext('user', fakes.FAKE_PROJECT_ID)
-
- instance = db.instance_create(context1,
- {'project_id': fakes.FAKE_PROJECT_ID})
-
- elevated = context1.elevated()
- fix_addr = db.fixed_ip_associate_pool(elevated, 1, instance['uuid'])
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- address=fix_addr.address,
- instance_uuid=instance.uuid,
- allocated=True,
- virtual_interface_id=3,
- network=dict(test_network.fake_network,
- **networks[1]))
-
- self.flags(force_dhcp_release=True)
- self.network.deallocate_fixed_ip(context1, fix_addr.address, 'fake')
- net_release_dhcp.assert_called_once_with(networks[1]['bridge'],
- fix_addr.address,
- 'DE:AD:BE:EF:00:00')
- fixed_update.assert_called_once_with(context1, fix_addr.address,
- {'allocated': False})
-
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.fixed_ip_update')
- def _deallocate_fixed_with_dhcp(self, mock_dev_exists, fixed_update,
- net_get, fixed_get):
- net_get.return_value = dict(test_network.fake_network,
- **networks[1])
-
- def vif_get(_context, _vif_id):
- return vifs[0]
-
- def release_dhcp(self, context, instance, dev, address, vif_address):
- linux_net.release_dhcp(dev, address, vif_address)
-
- with test.nested(
- mock.patch.object(network_rpcapi.NetworkAPI, 'release_dhcp',
- release_dhcp),
- mock.patch.object(db, 'virtual_interface_get', vif_get),
- mock.patch('nova.privsep.linux_net.dhcp_release',
- side_effect=processutils.ProcessExecutionError()),
- ) as (release_dhcp, _vif_get, privsep_dhcp_release):
- context1 = context.RequestContext('user', fakes.FAKE_PROJECT_ID)
-
- instance = db.instance_create(context1,
- {'project_id': fakes.FAKE_PROJECT_ID})
-
- elevated = context1.elevated()
- fix_addr = db.fixed_ip_associate_pool(elevated, 1,
- instance['uuid'])
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- address=fix_addr.address,
- instance_uuid=instance.uuid,
- allocated=True,
- virtual_interface_id=3,
- network=dict(
- test_network.fake_network,
- **networks[1]))
- self.flags(force_dhcp_release=True)
- self.network.deallocate_fixed_ip(context1, fix_addr.address,
- 'fake')
- fixed_update.assert_called_once_with(context1, fix_addr.address,
- {'allocated': False})
- mock_dev_exists.assert_called_once_with(networks[1]['bridge'])
- if mock_dev_exists.return_value:
- privsep_dhcp_release.assert_called_once_with(
- networks[1]['bridge'], fix_addr.address,
- 'DE:AD:BE:EF:00:00')
-
- @mock.patch('nova.privsep.linux_net.device_exists', return_value=True)
- def test_deallocate_fixed_with_dhcp(self, mock_dev_exists):
- self._deallocate_fixed_with_dhcp(mock_dev_exists)
-
- @mock.patch('nova.privsep.linux_net.device_exists', return_value=False)
- def test_deallocate_fixed_without_dhcp(self, mock_dev_exists):
- self._deallocate_fixed_with_dhcp(mock_dev_exists)
-
- def test_deallocate_fixed_deleted(self):
- # Verify doesn't deallocate deleted fixed_ip from deleted network.
-
- def teardown_network_on_host(_context, network):
- if network['id'] == 0:
- raise test.TestingException()
-
- self.stubs.Set(self.network, '_teardown_network_on_host',
- teardown_network_on_host)
-
- context1 = context.RequestContext('user', fakes.FAKE_PROJECT_ID)
- elevated = context1.elevated()
-
- instance = db.instance_create(context1,
- {'project_id': fakes.FAKE_PROJECT_ID})
- network = db.network_create_safe(elevated, networks[0])
-
- _fix_addr = db.fixed_ip_associate_pool(elevated, 1, instance['uuid'])
- fix_addr = _fix_addr.address
- db.fixed_ip_update(elevated, fix_addr, {'deleted': 1})
- elevated.read_deleted = 'yes'
- delfixed = db.fixed_ip_get_by_address(elevated, fix_addr)
- values = {'address': fix_addr,
- 'network_id': network.id,
- 'instance_uuid': delfixed['instance_uuid']}
- db.fixed_ip_create(elevated, values)
- elevated.read_deleted = 'no'
- elevated.read_deleted = 'yes'
-
- deallocate = self.network.deallocate_fixed_ip
- self.assertRaises(test.TestingException, deallocate, context1,
- fix_addr, 'fake')
-
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.fixed_ip_update')
- def test_deallocate_fixed_no_vif(self, fixed_update, net_get, fixed_get):
- """Verify that deallocate doesn't raise when no vif is returned.
-
- Ensures https://bugs.launchpad.net/nova/+bug/968457 doesn't return
- """
- net_get.return_value = dict(test_network.fake_network,
- **networks[1])
-
- def vif_get(_context, _vif_id):
- return None
-
- self.stub_out('nova.db.api.virtual_interface_get', vif_get)
- context1 = context.RequestContext('user', fakes.FAKE_PROJECT_ID)
-
- instance = db.instance_create(context1,
- {'project_id': fakes.FAKE_PROJECT_ID})
-
- elevated = context1.elevated()
- fix_addr = db.fixed_ip_associate_pool(elevated, 1, instance['uuid'])
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- address=fix_addr.address,
- allocated=True,
- virtual_interface_id=3,
- instance_uuid=instance.uuid,
- network=dict(test_network.fake_network,
- **networks[1]))
- self.flags(force_dhcp_release=True)
- fixed_update.return_value = fixed_get.return_value
- self.network.deallocate_fixed_ip(context1, fix_addr.address, 'fake')
- fixed_update.assert_called_once_with(context1, fix_addr.address,
- {'allocated': False})
-
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.fixed_ip_update')
- def test_fixed_ip_cleanup_fail(self, fixed_update, net_get, fixed_get):
- # Verify IP is not deallocated if the security group refresh fails.
- net_get.return_value = dict(test_network.fake_network,
- **networks[1])
- context1 = context.RequestContext('user', fakes.FAKE_PROJECT_ID)
-
- instance = db.instance_create(context1,
- {'project_id': fakes.FAKE_PROJECT_ID})
-
- elevated = context1.elevated()
- fix_addr = objects.FixedIP.associate_pool(elevated, 1,
- instance['uuid'])
-
- def fake_refresh(instance_uuid):
- raise test.TestingException()
- self.stubs.Set(self.network,
- '_do_trigger_security_group_members_refresh_for_instance',
- fake_refresh)
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- address=fix_addr.address,
- allocated=True,
- virtual_interface_id=3,
- instance_uuid=instance.uuid,
- network=dict(test_network.fake_network,
- **networks[1]))
- self.assertRaises(test.TestingException,
- self.network.deallocate_fixed_ip,
- context1, str(fix_addr.address), 'fake')
- self.assertFalse(fixed_update.called)
-
- def test_get_networks_by_uuids_ordering(self):
- self.mox.StubOutWithMock(db, 'network_get_all_by_uuids')
-
- requested_networks = ['bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa']
- db.network_get_all_by_uuids(mox.IgnoreArg(), mox.IgnoreArg(),
- mox.IgnoreArg()).AndReturn(
- [dict(test_network.fake_network, **net)
- for net in networks])
-
- self.mox.ReplayAll()
- res = self.network._get_networks_by_uuids(self.context,
- requested_networks)
-
- self.assertEqual(1, res[0]['id'])
- self.assertEqual(0, res[1]['id'])
-
- @mock.patch('nova.objects.fixed_ip.FixedIP.get_by_id')
- @mock.patch('nova.objects.floating_ip.FloatingIPList.get_by_host')
- @mock.patch('nova.network.linux_net.iptables_manager._apply')
- @mock.patch('nova.privsep.linux_net.bind_ip')
- @mock.patch('nova.privsep.linux_net.modify_ebtables')
- def test_init_host_iptables_defer_apply(self, modify_ebtables, bind_ip,
- iptable_apply,
- floating_get_by_host,
- fixed_get_by_id):
- def get_by_id(context, fixed_ip_id, **kwargs):
- net = objects.Network(bridge='testbridge',
- cidr='192.168.1.0/24')
- if fixed_ip_id == 1:
- return objects.FixedIP(address='192.168.1.4',
- network=net)
- elif fixed_ip_id == 2:
- return objects.FixedIP(address='192.168.1.5',
- network=net)
-
- def fake_apply():
- fake_apply.count += 1
-
- fake_apply.count = 0
- ctxt = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
- float1 = objects.FloatingIP(address='1.2.3.4', fixed_ip_id=1)
- float2 = objects.FloatingIP(address='1.2.3.5', fixed_ip_id=2)
- float1._context = ctxt
- float2._context = ctxt
-
- iptable_apply.side_effect = fake_apply
- floating_get_by_host.return_value = [float1, float2]
- fixed_get_by_id.side_effect = get_by_id
-
- self.network.init_host()
- self.assertEqual(1, fake_apply.count)
-
-
-class _TestDomainObject(object):
- def __init__(self, **kwargs):
- for k, v in kwargs.items():
- self.__setattr__(k, v)
-
-
-class CommonNetworkTestCase(test.TestCase):
-
- REQUIRES_LOCKING = True
-
- def setUp(self):
- super(CommonNetworkTestCase, self).setUp()
- self.context = context.RequestContext('fake', 'fake')
- self.flags(ipv6_backend='rfc2462', use_neutron=False)
- ipv6.reset_backend()
-
- def test_validate_instance_zone_for_dns_domain(self):
- domain = 'example.com'
- az = 'test_az'
- domains = {
- domain: _TestDomainObject(
- domain=domain,
- availability_zone=az)}
-
- def dnsdomain_get(context, instance_domain):
- return domains.get(instance_domain)
-
- self.stub_out('nova.db.api.dnsdomain_get', dnsdomain_get)
- fake_instance = {'uuid': FAKEUUID,
- 'availability_zone': az}
-
- manager = network_manager.NetworkManager()
- res = manager._validate_instance_zone_for_dns_domain(self.context,
- fake_instance)
- self.assertTrue(res)
-
- def fake_create_fixed_ips(self, context, network_id, fixed_cidr=None,
- extra_reserved=None, bottom_reserved=0,
- top_reserved=0):
- return None
-
- def test_get_instance_nw_info_client_exceptions(self):
- manager = network_manager.NetworkManager()
- self.mox.StubOutWithMock(manager.db,
- 'fixed_ip_get_by_instance')
- manager.db.fixed_ip_get_by_instance(
- self.context, FAKEUUID).AndRaise(exception.InstanceNotFound(
- instance_id=FAKEUUID))
- self.mox.ReplayAll()
- self.assertRaises(messaging.ExpectedException,
- manager.get_instance_nw_info,
- self.context, FAKEUUID, 'fake_rxtx_factor', HOST)
-
- @mock.patch('nova.db.api.instance_get')
- @mock.patch('nova.db.api.fixed_ip_get_by_instance')
- def test_deallocate_for_instance_passes_host_info(self, fixed_get,
- instance_get):
- manager = fake_network.FakeNetworkManager()
- db = manager.db
- instance_get.return_value = fake_inst(uuid=uuids.non_existent_uuid)
- db.virtual_interface_delete_by_instance = lambda _x, _y: None
- ctx = context.RequestContext('igonre', 'igonre')
-
- fixed_get.return_value = [dict(test_fixed_ip.fake_fixed_ip,
- address='1.2.3.4',
- network_id=123)]
-
- manager.deallocate_for_instance(
- ctx, instance=objects.Instance._from_db_object(self.context,
- objects.Instance(), instance_get.return_value))
-
- self.assertEqual([
- (ctx, '1.2.3.4', 'fake-host')
- ], manager.deallocate_fixed_ip_calls)
-
- @mock.patch('nova.db.api.fixed_ip_get_by_instance')
- def test_deallocate_for_instance_passes_host_info_with_update_dns_entries(
- self, fixed_get):
- self.flags(update_dns_entries=True)
- manager = fake_network.FakeNetworkManager()
- db = manager.db
- db.virtual_interface_delete_by_instance = lambda _x, _y: None
- ctx = context.RequestContext('igonre', 'igonre')
-
- fixed_get.return_value = [dict(test_fixed_ip.fake_fixed_ip,
- address='1.2.3.4',
- network_id=123)]
-
- with mock.patch.object(manager.network_rpcapi,
- 'update_dns') as mock_update_dns:
- manager.deallocate_for_instance(
- ctx, instance=fake_instance.fake_instance_obj(ctx))
- mock_update_dns.assert_called_once_with(ctx, ['123'])
-
- self.assertEqual([
- (ctx, '1.2.3.4', 'fake-host')
- ], manager.deallocate_fixed_ip_calls)
-
- def test_deallocate_for_instance_with_requested_networks(self):
- manager = fake_network.FakeNetworkManager()
- db = manager.db
- db.virtual_interface_delete_by_instance = mock.Mock()
- ctx = context.RequestContext('igonre', 'igonre')
- requested_networks = objects.NetworkRequestList.from_tuples(
- [('123', '1.2.3.4'), ('123', '4.3.2.1'), ('123', None)])
- manager.deallocate_for_instance(
- ctx,
- instance=fake_instance.fake_instance_obj(ctx),
- requested_networks=requested_networks)
-
- self.assertEqual([
- (ctx, '1.2.3.4', 'fake-host'), (ctx, '4.3.2.1', 'fake-host')
- ], manager.deallocate_fixed_ip_calls)
-
- def test_deallocate_for_instance_with_update_dns_entries(self):
- self.flags(update_dns_entries=True)
- manager = fake_network.FakeNetworkManager()
- db = manager.db
- db.virtual_interface_delete_by_instance = mock.Mock()
- ctx = context.RequestContext('igonre', 'igonre')
- requested_networks = objects.NetworkRequestList.from_tuples(
- [('123', '1.2.3.4'), ('123', '4.3.2.1')])
- with mock.patch.object(manager.network_rpcapi,
- 'update_dns') as mock_update_dns:
- manager.deallocate_for_instance(
- ctx,
- instance=fake_instance.fake_instance_obj(ctx),
- requested_networks=requested_networks)
- mock_update_dns.assert_called_once_with(ctx, ['123'])
-
- self.assertEqual([
- (ctx, '1.2.3.4', 'fake-host'), (ctx, '4.3.2.1', 'fake-host')
- ], manager.deallocate_fixed_ip_calls)
-
- @mock.patch('nova.db.api.fixed_ip_get_by_instance')
- @mock.patch('nova.db.api.fixed_ip_disassociate')
- def test_remove_fixed_ip_from_instance(self, disassociate, get):
- manager = fake_network.FakeNetworkManager()
- get.return_value = [
- dict(test_fixed_ip.fake_fixed_ip, **x)
- for x in manager.db.fixed_ip_get_by_instance(None,
- FAKEUUID)]
- manager.remove_fixed_ip_from_instance(self.context, FAKEUUID,
- HOST,
- '10.0.0.1')
-
- self.assertEqual('10.0.0.1', manager.deallocate_called)
- disassociate.assert_called_once_with(self.context, '10.0.0.1')
-
- @mock.patch('nova.db.api.fixed_ip_get_by_instance')
- def test_remove_fixed_ip_from_instance_bad_input(self, get):
- manager = fake_network.FakeNetworkManager()
- get.return_value = []
- self.assertRaises(exception.FixedIpNotFoundForSpecificInstance,
- manager.remove_fixed_ip_from_instance,
- self.context, 99, HOST, 'bad input')
-
- def test_validate_cidrs(self):
- manager = fake_network.FakeNetworkManager()
- nets = manager.create_networks(self.context.elevated(), 'fake',
- '192.168.0.0/24',
- False, 1, 256, None, None, None,
- None, None)
- self.assertEqual(1, len(nets))
- cidrs = [str(net['cidr']) for net in nets]
- self.assertIn('192.168.0.0/24', cidrs)
-
- def test_validate_cidrs_split_exact_in_half(self):
- manager = fake_network.FakeNetworkManager()
- nets = manager.create_networks(self.context.elevated(), 'fake',
- '192.168.0.0/24',
- False, 2, 128, None, None, None,
- None, None)
- self.assertEqual(2, len(nets))
- cidrs = [str(net['cidr']) for net in nets]
- self.assertIn('192.168.0.0/25', cidrs)
- self.assertIn('192.168.0.128/25', cidrs)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_validate_cidrs_split_cidr_in_use_middle_of_range(self, get_all):
- manager = fake_network.FakeNetworkManager()
- get_all.return_value = [dict(test_network.fake_network,
- id=1, cidr='192.168.2.0/24')]
- nets = manager.create_networks(self.context.elevated(), 'fake',
- '192.168.0.0/16',
- False, 4, 256, None, None, None,
- None, None)
- self.assertEqual(4, len(nets))
- cidrs = [str(net['cidr']) for net in nets]
- exp_cidrs = ['192.168.0.0/24', '192.168.1.0/24', '192.168.3.0/24',
- '192.168.4.0/24']
- for exp_cidr in exp_cidrs:
- self.assertIn(exp_cidr, cidrs)
- self.assertNotIn('192.168.2.0/24', cidrs)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_validate_cidrs_smaller_subnet_in_use(self, get_all):
- manager = fake_network.FakeNetworkManager()
- get_all.return_value = [dict(test_network.fake_network,
- id=1, cidr='192.168.2.9/25')]
- # CidrConflict: requested cidr (192.168.2.0/24) conflicts with
- # existing smaller cidr
- args = (self.context.elevated(), 'fake', '192.168.2.0/24', False,
- 1, 256, None, None, None, None, None)
- self.assertRaises(exception.CidrConflict,
- manager.create_networks, *args)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_validate_cidrs_split_smaller_cidr_in_use(self, get_all):
- manager = fake_network.FakeNetworkManager()
- get_all.return_value = [dict(test_network.fake_network,
- id=1, cidr='192.168.2.0/25')]
- nets = manager.create_networks(self.context.elevated(), 'fake',
- '192.168.0.0/16',
- False, 4, 256, None, None, None, None,
- None)
- self.assertEqual(4, len(nets))
- cidrs = [str(net['cidr']) for net in nets]
- exp_cidrs = ['192.168.0.0/24', '192.168.1.0/24', '192.168.3.0/24',
- '192.168.4.0/24']
- for exp_cidr in exp_cidrs:
- self.assertIn(exp_cidr, cidrs)
- self.assertNotIn('192.168.2.0/24', cidrs)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_validate_cidrs_split_smaller_cidr_in_use2(self, get_all):
- manager = fake_network.FakeNetworkManager()
- self.mox.StubOutWithMock(manager.db, 'network_get_all')
- get_all.return_value = [dict(test_network.fake_network, id=1,
- cidr='192.168.2.9/29')]
- nets = manager.create_networks(self.context.elevated(), 'fake',
- '192.168.2.0/24',
- False, 3, 32, None, None, None, None,
- None)
- self.assertEqual(3, len(nets))
- cidrs = [str(net['cidr']) for net in nets]
- exp_cidrs = ['192.168.2.32/27', '192.168.2.64/27', '192.168.2.96/27']
- for exp_cidr in exp_cidrs:
- self.assertIn(exp_cidr, cidrs)
- self.assertNotIn('192.168.2.0/27', cidrs)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_validate_cidrs_split_all_in_use(self, get_all):
- manager = fake_network.FakeNetworkManager()
- in_use = [dict(test_network.fake_network, **values) for values in
- [{'id': 1, 'cidr': '192.168.2.9/29'},
- {'id': 2, 'cidr': '192.168.2.64/26'},
- {'id': 3, 'cidr': '192.168.2.128/26'}]]
- get_all.return_value = in_use
- args = (self.context.elevated(), 'fake', '192.168.2.0/24', False,
- 3, 64, None, None, None, None, None)
- # CidrConflict: Not enough subnets avail to satisfy requested num_
- # networks - some subnets in requested range already
- # in use
- self.assertRaises(exception.CidrConflict,
- manager.create_networks, *args)
-
- def test_validate_cidrs_one_in_use(self):
- manager = fake_network.FakeNetworkManager()
- args = (None, 'fake', '192.168.0.0/24', False, 2, 256, None, None,
- None, None, None)
- # ValueError: network_size * num_networks exceeds cidr size
- self.assertRaises(ValueError, manager.create_networks, *args)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_validate_cidrs_already_used(self, get_all):
- manager = fake_network.FakeNetworkManager()
- get_all.return_value = [dict(test_network.fake_network,
- cidr='192.168.0.0/24')]
- # CidrConflict: cidr already in use
- args = (self.context.elevated(), 'fake', '192.168.0.0/24', False,
- 1, 256, None, None, None, None, None)
- self.assertRaises(exception.CidrConflict,
- manager.create_networks, *args)
-
- def test_validate_cidrs_too_many(self):
- manager = fake_network.FakeNetworkManager()
- args = (None, 'fake', '192.168.0.0/24', False, 200, 256, None, None,
- None, None, None)
- # ValueError: Not enough subnets avail to satisfy requested
- # num_networks
- self.assertRaises(ValueError, manager.create_networks, *args)
-
- def test_validate_cidrs_split_partial(self):
- manager = fake_network.FakeNetworkManager()
- nets = manager.create_networks(self.context.elevated(), 'fake',
- '192.168.0.0/16',
- False, 2, 256, None, None, None, None,
- None)
- returned_cidrs = [str(net['cidr']) for net in nets]
- self.assertIn('192.168.0.0/24', returned_cidrs)
- self.assertIn('192.168.1.0/24', returned_cidrs)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_validate_cidrs_conflict_existing_supernet(self, get_all):
- manager = fake_network.FakeNetworkManager()
- get_all.return_value = [dict(test_network.fake_network,
- id=1, cidr='192.168.0.0/8')]
- args = (self.context.elevated(), 'fake', '192.168.0.0/24', False,
- 1, 256, None, None, None, None, None)
- # CidrConflict: requested cidr (192.168.0.0/24) conflicts
- # with existing supernet
- self.assertRaises(exception.CidrConflict,
- manager.create_networks, *args)
-
- def test_create_networks(self):
- cidr = '192.168.0.0/24'
- manager = fake_network.FakeNetworkManager()
- self.stubs.Set(manager, '_create_fixed_ips',
- self.fake_create_fixed_ips)
- args = [self.context.elevated(), 'foo', cidr, None, 1, 256,
- 'fd00::/48', None, None, None, None, None]
- self.assertTrue(manager.create_networks(*args))
-
- def test_create_networks_with_uuid(self):
- cidr = '192.168.0.0/24'
- uuid = FAKEUUID
- manager = fake_network.FakeNetworkManager()
- self.stubs.Set(manager, '_create_fixed_ips',
- self.fake_create_fixed_ips)
- args = [self.context.elevated(), 'foo', cidr, None, 1, 256,
- 'fd00::/48', None, None, None, None, None]
- kwargs = {'uuid': uuid}
- nets = manager.create_networks(*args, **kwargs)
- self.assertEqual(1, len(nets))
- net = nets[0]
- self.assertEqual(uuid, net['uuid'])
-
- @mock.patch('nova.db.api.network_get_all')
- def test_create_networks_cidr_already_used(self, get_all):
- manager = fake_network.FakeNetworkManager()
- get_all.return_value = [dict(test_network.fake_network,
- id=1, cidr='192.168.0.0/24')]
- args = [self.context.elevated(), 'foo', '192.168.0.0/24', None, 1, 256,
- 'fd00::/48', None, None, None, None, None]
- self.assertRaises(exception.CidrConflict,
- manager.create_networks, *args)
-
- def test_create_networks_many(self):
- cidr = '192.168.0.0/16'
- manager = fake_network.FakeNetworkManager()
- self.stubs.Set(manager, '_create_fixed_ips',
- self.fake_create_fixed_ips)
- args = [self.context.elevated(), 'foo', cidr, None, 10, 256,
- 'fd00::/48', None, None, None, None, None]
- self.assertTrue(manager.create_networks(*args))
-
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.fixed_ips_by_virtual_interface')
- def test_get_instance_uuids_by_ip_regex(self, fixed_get, network_get):
- manager = fake_network.FakeNetworkManager(self.stubs)
- fixed_get.side_effect = manager.db.fixed_ips_by_virtual_interface
- _vifs = manager.db.virtual_interface_get_all(None)
- fake_context = context.RequestContext('user', 'project')
- network_get.return_value = dict(test_network.fake_network,
- **manager.db.network_get(None, 1))
-
- # Greedy get eveything
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip': '.*'})
- self.assertEqual(len(_vifs), len(res))
-
- # Doesn't exist
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip': '10.0.0.1'})
- self.assertFalse(res)
-
- # Get instance 1
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip': '172.16.0.2'})
- self.assertTrue(res)
- self.assertEqual(1, len(res))
- self.assertEqual(_vifs[1]['instance_uuid'], res[0]['instance_uuid'])
-
- # Get instance 2
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip': '173.16.0.2'})
- self.assertTrue(res)
- self.assertEqual(1, len(res))
- self.assertEqual(_vifs[2]['instance_uuid'], res[0]['instance_uuid'])
-
- # Get instance 0 and 1
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip': '172.16.0.*'})
- self.assertTrue(res)
- self.assertEqual(2, len(res))
- self.assertEqual(_vifs[0]['instance_uuid'], res[0]['instance_uuid'])
- self.assertEqual(_vifs[1]['instance_uuid'], res[1]['instance_uuid'])
-
- # Get instance 1 and 2
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip': '17..16.0.2'})
- self.assertTrue(res)
- self.assertEqual(2, len(res))
- self.assertEqual(_vifs[1]['instance_uuid'], res[0]['instance_uuid'])
- self.assertEqual(_vifs[2]['instance_uuid'], res[1]['instance_uuid'])
-
- @mock.patch('nova.db.api.network_get')
- def test_get_instance_uuids_by_ipv6_regex(self, network_get):
- manager = fake_network.FakeNetworkManager(self.stubs)
- _vifs = manager.db.virtual_interface_get_all(None)
- fake_context = context.RequestContext('user', 'project')
-
- def _network_get(context, network_id, **args):
- return dict(test_network.fake_network,
- **manager.db.network_get(context, network_id))
- network_get.side_effect = _network_get
-
- # Greedy get eveything
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip6': '.*'})
- self.assertEqual(len(_vifs), len(res))
-
- # Doesn't exist
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip6': '.*1034.*'})
- self.assertFalse(res)
-
- # Get instance 1
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip6': '2001:.*2'})
- self.assertTrue(res)
- self.assertEqual(1, len(res))
- self.assertEqual(_vifs[1]['instance_uuid'], res[0]['instance_uuid'])
-
- # Get instance 2
- ip6 = '2001:db8:69:1f:dead:beff:feff:ef03'
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip6': ip6})
- self.assertTrue(res)
- self.assertEqual(1, len(res))
- self.assertEqual(_vifs[2]['instance_uuid'], res[0]['instance_uuid'])
-
- # Get instance 0 and 1
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip6': '.*ef0[1,2]'})
- self.assertTrue(res)
- self.assertEqual(2, len(res))
- self.assertEqual(_vifs[0]['instance_uuid'], res[0]['instance_uuid'])
- self.assertEqual(_vifs[1]['instance_uuid'], res[1]['instance_uuid'])
-
- # Get instance 1 and 2
- ip6 = '2001:db8:69:1.:dead:beff:feff:ef0.'
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'ip6': ip6})
- self.assertTrue(res)
- self.assertEqual(2, len(res))
- self.assertEqual(_vifs[1]['instance_uuid'], res[0]['instance_uuid'])
- self.assertEqual(_vifs[2]['instance_uuid'], res[1]['instance_uuid'])
-
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.fixed_ips_by_virtual_interface')
- def test_get_instance_uuids_by_ip(self, fixed_get, network_get):
- manager = fake_network.FakeNetworkManager(self.stubs)
- fixed_get.side_effect = manager.db.fixed_ips_by_virtual_interface
- _vifs = manager.db.virtual_interface_get_all(None)
- fake_context = context.RequestContext('user', 'project')
- network_get.return_value = dict(test_network.fake_network,
- **manager.db.network_get(None, 1))
-
- # No regex for you!
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'fixed_ip': '.*'})
- self.assertFalse(res)
-
- # Doesn't exist
- ip = '10.0.0.1'
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'fixed_ip': ip})
- self.assertFalse(res)
-
- # Get instance 1
- ip = '172.16.0.2'
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'fixed_ip': ip})
- self.assertTrue(res)
- self.assertEqual(1, len(res))
- self.assertEqual(_vifs[1]['instance_uuid'], res[0]['instance_uuid'])
-
- # Get instance 2
- ip = '173.16.0.2'
- res = manager.get_instance_uuids_by_ip_filter(fake_context,
- {'fixed_ip': ip})
- self.assertTrue(res)
- self.assertEqual(1, len(res))
- self.assertEqual(_vifs[2]['instance_uuid'], res[0]['instance_uuid'])
-
- @mock.patch('nova.db.api.network_get_by_uuid')
- def test_get_network(self, get):
- manager = fake_network.FakeNetworkManager()
- fake_context = context.RequestContext('user', 'project')
- get.return_value = dict(test_network.fake_network, **networks[0])
- uuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
- network = manager.get_network(fake_context, uuid)
- self.assertEqual(uuid, network['uuid'])
-
- @mock.patch('nova.db.api.network_get_by_uuid')
- def test_get_network_not_found(self, get):
- manager = fake_network.FakeNetworkManager()
- fake_context = context.RequestContext('user', 'project')
- get.side_effect = exception.NetworkNotFoundForUUID(uuid='foo')
- uuid = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
- self.assertRaises(exception.NetworkNotFound,
- manager.get_network, fake_context, uuid)
-
- @mock.patch('nova.db.api.network_get_all')
- def test_get_all_networks(self, get_all):
- manager = fake_network.FakeNetworkManager()
- fake_context = context.RequestContext('user', 'project')
- get_all.return_value = [dict(test_network.fake_network, **net)
- for net in networks]
- output = manager.get_all_networks(fake_context)
- self.assertEqual(2, len(networks))
- self.assertEqual('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
- output[0]['uuid'])
- self.assertEqual('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
- output[1]['uuid'])
-
- @mock.patch('nova.db.api.network_get_by_uuid')
- @mock.patch('nova.db.api.network_disassociate')
- def test_disassociate_network(self, disassociate, get):
- manager = fake_network.FakeNetworkManager()
- disassociate.return_value = True
- fake_context = context.RequestContext('user', 'project')
- get.return_value = dict(test_network.fake_network,
- **networks[0])
- uuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
- manager.disassociate_network(fake_context, uuid)
-
- @mock.patch('nova.db.api.network_get_by_uuid')
- def test_disassociate_network_not_found(self, get):
- manager = fake_network.FakeNetworkManager()
- fake_context = context.RequestContext('user', 'project')
- get.side_effect = exception.NetworkNotFoundForUUID(uuid='fake')
- uuid = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee'
- self.assertRaises(exception.NetworkNotFound,
- manager.disassociate_network, fake_context, uuid)
-
- def _test_init_host_dynamic_fixed_range(self, net_manager):
- self.flags(fake_network=True,
- routing_source_ip='172.16.0.1',
- metadata_host='172.16.0.1',
- public_interface='eth1',
- dmz_cidr=['10.0.3.0/24'])
- binary_name = linux_net.get_binary_name()
-
- # Stub out calls we don't want to really run, mock the db
- self.stubs.Set(linux_net.iptables_manager, '_apply', lambda: None)
- self.stubs.Set(floating_ips.FloatingIP, 'init_host_floating_ips',
- lambda *args: None)
- self.stubs.Set(net_manager.l3driver, 'initialize_gateway',
- lambda *args: None)
- self.mox.StubOutWithMock(db, 'network_get_all_by_host')
- fake_networks = [dict(test_network.fake_network, **n)
- for n in networks]
- db.network_get_all_by_host(mox.IgnoreArg(),
- mox.IgnoreArg()
- ).MultipleTimes().AndReturn(fake_networks)
- self.mox.ReplayAll()
-
- net_manager.init_host()
-
- # Get the iptables rules that got created
- current_lines = []
- new_lines = linux_net.iptables_manager._modify_rules(current_lines,
- linux_net.iptables_manager.ipv4['nat'],
- table_name='nat')
-
- expected_lines = ['[0:0] -A %s-snat -s %s -d 0.0.0.0/0 '
- '-j SNAT --to-source %s -o %s'
- % (binary_name, networks[0]['cidr'],
- CONF.routing_source_ip,
- CONF.public_interface),
- '[0:0] -A %s-POSTROUTING -s %s -d %s/32 -j ACCEPT'
- % (binary_name, networks[0]['cidr'],
- CONF.metadata_host),
- '[0:0] -A %s-POSTROUTING -s %s -d %s -j ACCEPT'
- % (binary_name, networks[0]['cidr'],
- CONF.dmz_cidr[0]),
- '[0:0] -A %s-POSTROUTING -s %s -d %s -m conntrack ! '
- '--ctstate DNAT -j ACCEPT' % (binary_name,
- networks[0]['cidr'],
- networks[0]['cidr']),
- '[0:0] -A %s-snat -s %s -d 0.0.0.0/0 '
- '-j SNAT --to-source %s -o %s'
- % (binary_name, networks[1]['cidr'],
- CONF.routing_source_ip,
- CONF.public_interface),
- '[0:0] -A %s-POSTROUTING -s %s -d %s/32 -j ACCEPT'
- % (binary_name, networks[1]['cidr'],
- CONF.metadata_host),
- '[0:0] -A %s-POSTROUTING -s %s -d %s -j ACCEPT'
- % (binary_name, networks[1]['cidr'],
- CONF.dmz_cidr[0]),
- '[0:0] -A %s-POSTROUTING -s %s -d %s -m conntrack ! '
- '--ctstate DNAT -j ACCEPT' % (binary_name,
- networks[1]['cidr'],
- networks[1]['cidr'])]
-
- # Compare the expected rules against the actual ones
- for line in expected_lines:
- self.assertIn(line, new_lines)
-
- # Add an additional network and ensure the rules get configured
- new_network = {'id': 2,
- 'uuid': uuids.network_1,
- 'label': 'test2',
- 'injected': False,
- 'multi_host': False,
- 'cidr': '192.168.2.0/24',
- 'cidr_v6': '2001:dba::/64',
- 'gateway_v6': '2001:dba::1',
- 'netmask_v6': '64',
- 'netmask': '255.255.255.0',
- 'bridge': 'fa1',
- 'bridge_interface': 'fake_fa1',
- 'gateway': '192.168.2.1',
- 'dhcp_server': '192.168.2.1',
- 'broadcast': '192.168.2.255',
- 'dns1': '192.168.2.1',
- 'dns2': '192.168.2.2',
- 'vlan': None,
- 'host': HOST,
- 'project_id': fakes.FAKE_PROJECT_ID,
- 'vpn_public_address': '192.168.2.2',
- 'vpn_public_port': '22',
- 'vpn_private_address': '10.0.0.2'}
- new_network_obj = objects.Network._from_db_object(
- self.context, objects.Network(),
- dict(test_network.fake_network, **new_network))
-
- ctxt = context.get_admin_context()
- net_manager._setup_network_on_host(ctxt, new_network_obj)
-
- # Get the new iptables rules that got created from adding a new network
- current_lines = []
- new_lines = linux_net.iptables_manager._modify_rules(current_lines,
- linux_net.iptables_manager.ipv4['nat'],
- table_name='nat')
-
- # Add the new expected rules to the old ones
- expected_lines += ['[0:0] -A %s-snat -s %s -d 0.0.0.0/0 '
- '-j SNAT --to-source %s -o %s'
- % (binary_name, new_network['cidr'],
- CONF.routing_source_ip,
- CONF.public_interface),
- '[0:0] -A %s-POSTROUTING -s %s -d %s/32 -j ACCEPT'
- % (binary_name, new_network['cidr'],
- CONF.metadata_host),
- '[0:0] -A %s-POSTROUTING -s %s -d %s -j ACCEPT'
- % (binary_name, new_network['cidr'],
- CONF.dmz_cidr[0]),
- '[0:0] -A %s-POSTROUTING -s %s -d %s -m conntrack '
- '! --ctstate DNAT -j ACCEPT' % (binary_name,
- new_network['cidr'],
- new_network['cidr'])]
-
- # Compare the expected rules (with new network) against the actual ones
- for line in expected_lines:
- self.assertIn(line, new_lines)
-
- @mock.patch('nova.privsep.linux_net.bind_ip')
- def test_flatdhcpmanager_dynamic_fixed_range(self, mock_bind_ip):
- """Test FlatDHCPManager NAT rules for fixed_range."""
- # Set the network manager
- self.network = network_manager.FlatDHCPManager(host=HOST)
- self.network.db = db
-
- # Test new behavior:
- # CONF.fixed_range is not set, defaults to None
- # Determine networks to NAT based on lookup
- self._test_init_host_dynamic_fixed_range(self.network)
-
- @mock.patch('nova.privsep.linux_net.bind_ip')
- def test_vlanmanager_dynamic_fixed_range(self, mock_bind_ip):
- """Test VlanManager NAT rules for fixed_range."""
- # Set the network manager
- self.network = network_manager.VlanManager(host=HOST)
- self.network.db = db
-
- # Test new behavior:
- # CONF.fixed_range is not set, defaults to None
- # Determine networks to NAT based on lookup
- self._test_init_host_dynamic_fixed_range(self.network)
-
- def test_fixed_cidr_out_of_range(self):
- manager = network_manager.NetworkManager()
- ctxt = context.get_admin_context()
- self.assertRaises(exception.AddressOutOfRange,
- manager.create_networks, ctxt, label="fake",
- cidr='10.1.0.0/24', fixed_cidr='10.1.1.0/25')
-
-
-class FakeRPCFixedManager(network_manager.RPCAllocateFixedIP,
- network_manager.NetworkManager):
- """Dummy manager that implements RPCAllocateFixedIP."""
-
-
-class RPCAllocateTestCase(test.NoDBTestCase):
- """Tests nova.network.manager.RPCAllocateFixedIP."""
- def setUp(self):
- super(RPCAllocateTestCase, self).setUp()
- self.rpc_fixed = FakeRPCFixedManager()
- self.context = context.RequestContext('fake', 'fake')
-
- def test_rpc_allocate(self):
- """Test to verify bug 855030 doesn't resurface.
-
- Mekes sure _rpc_allocate_fixed_ip returns a value so the call
- returns properly and the greenpool completes.
- """
- address = '10.10.10.10'
-
- def fake_allocate(*args, **kwargs):
- return address
-
- def fake_network_get(*args, **kwargs):
- return test_network.fake_network
-
- self.stubs.Set(self.rpc_fixed, 'allocate_fixed_ip', fake_allocate)
- self.stubs.Set(self.rpc_fixed.db, 'network_get', fake_network_get)
- rval = self.rpc_fixed._rpc_allocate_fixed_ip(self.context,
- 'fake_instance',
- 'fake_network')
- self.assertEqual(address, rval)
-
-
-class FakeFloatingIPManager(floating_ips.FloatingIP,
- network_manager.NetworkManager):
- """Dummy manager that implements FloatingIP."""
-
-
-class AllocateTestCase(test.TestCase):
-
- REQUIRES_LOCKING = True
-
- def setUp(self):
- super(AllocateTestCase, self).setUp()
- dns = 'nova.network.noop_dns_driver.NoopDNSDriver'
- self.flags(instance_dns_manager=dns)
- self.useFixture(test.SampleNetworks())
- self.network = network_manager.VlanManager(host=HOST)
-
- self.user_id = fakes.FAKE_USER_ID
- self.project_id = fakes.FAKE_PROJECT_ID
- self.context = context.RequestContext(self.user_id,
- self.project_id,
- is_admin=True)
- self.user_context = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID)
-
- @mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.set_device_mtu')
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.set_device_macaddr')
- @mock.patch('nova.privsep.linux_net.bind_ip')
- @mock.patch('nova.privsep.linux_net.unbind_ip')
- @mock.patch('nova.privsep.linux_net.routes_show', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.lookup_ip', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.change_ip')
- @mock.patch('nova.privsep.linux_net.clean_conntrack')
- @mock.patch('nova.privsep.linux_net.address_command_deprecated')
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=False)
- @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
- @mock.patch('nova.privsep.linux_net.modify_ebtables')
- @mock.patch('nova.privsep.linux_net.add_vlan')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.bridge_setfd')
- @mock.patch('nova.privsep.linux_net.bridge_disable_stp')
- @mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', ''))
- def test_allocate_for_instance(
- self, mock_bridge_add_interface, mock_bridge_disable_stp,
- mock_bridge_setfd, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_add_vlan, mock_modify_ebtables,
- mock_forwarding_enable, mock_forwarding_check,
- mock_clean_conntrack, mock_address_command,
- mock_change_ip, mock_lookup_ip, mock_routes_show, mock_unbind,
- mock_bind, mock_set_macaddr, mock_set_enabled, mock_set_mtu,
- mock_add_bridge):
- address = "10.10.10.10"
- self.flags(auto_assign_floating_ip=True)
-
- db.floating_ip_create(self.context,
- {'address': address,
- 'pool': 'nova'})
- inst = objects.Instance(context=self.context)
- inst.host = HOST
- inst.display_name = HOST
- inst.instance_type_id = 1
- inst.uuid = FAKEUUID
- inst.create()
- networks = db.network_get_all(self.context)
- reqnets = objects.NetworkRequestList(objects=[])
- index = 0
- project_id = self.user_context.project_id
- for network in networks:
- db.network_update(self.context, network['id'],
- {'host': HOST,
- 'project_id': project_id})
- if index == 0:
- reqnets.objects.append(objects.NetworkRequest(
- network_id=network['uuid'],
- tag='mynic'))
- index += 1
- nw_info = self.network.allocate_for_instance(self.user_context,
- instance_id=inst['id'], instance_uuid=inst['uuid'],
- host=inst['host'], vpn=None, rxtx_factor=3,
- project_id=project_id, macs=None, requested_networks=reqnets)
- self.assertEqual(1, len(nw_info))
- vifs = objects.VirtualInterfaceList.get_all(self.context)
- self.assertEqual(['mynic'], [vif.tag for vif in vifs])
- fixed_ip = nw_info.fixed_ips()[0]['address']
- self.assertTrue(netutils.is_valid_ipv4(fixed_ip))
- self.network.deallocate_for_instance(self.context,
- instance=inst)
-
- def test_allocate_for_instance_illegal_network(self):
- networks = db.network_get_all(self.context)
- requested_networks = []
- for network in networks:
- # set all networks to other projects
- db.network_update(self.context, network['id'],
- {'host': HOST,
- 'project_id': 'otherid'})
- requested_networks.append((network['uuid'], None))
- # set the first network to our project
- db.network_update(self.context, networks[0]['id'],
- {'project_id': self.user_context.project_id})
-
- inst = objects.Instance(context=self.context)
- inst.host = HOST
- inst.display_name = HOST
- inst.instance_type_id = 1
- inst.uuid = FAKEUUID
- inst.create()
- self.assertRaises(exception.NetworkNotFoundForProject,
- self.network.allocate_for_instance, self.user_context,
- instance_id=inst['id'], instance_uuid=inst['uuid'],
- host=inst['host'], vpn=None, rxtx_factor=3,
- project_id=self.context.project_id, macs=None,
- requested_networks=requested_networks)
-
- @mock.patch('nova.privsep.linux_net.add_bridge', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.set_device_mtu')
- @mock.patch('nova.privsep.linux_net.set_device_enabled')
- @mock.patch('nova.privsep.linux_net.set_device_macaddr')
- @mock.patch('nova.privsep.linux_net.routes_show', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.lookup_ip', return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.change_ip')
- @mock.patch('nova.privsep.linux_net.address_command_deprecated')
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=False)
- @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner')
- @mock.patch('nova.privsep.linux_net.add_vlan')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.bridge_setfd')
- @mock.patch('nova.privsep.linux_net.bridge_disable_stp')
- @mock.patch('nova.privsep.linux_net.bridge_add_interface',
- return_value=('', ''))
- def test_allocate_for_instance_with_mac(
- self, mock_bridge_add_interface, mock_bridge_disable_stp,
- mock_bridge_setfd, mock_iptables_set_rules,
- mock_iptables_get_rules, mock_add_vlan, mock_forwarding_enable,
- mock_forwarding_check, mock_address_command,
- mock_change_ip, mock_lookup_ip, mock_routes_show,
- mock_set_addr, mock_enabled, mock_set_mtu, mock_add_bridge):
- available_macs = set(['ca:fe:de:ad:be:ef'])
- inst = db.instance_create(self.context, {'host': HOST,
- 'display_name': HOST,
- 'instance_type_id': 1})
- networks = db.network_get_all(self.context)
- for network in networks:
- db.network_update(self.context, network['id'],
- {'host': HOST})
- project_id = self.context.project_id
- nw_info = self.network.allocate_for_instance(self.user_context,
- instance_id=inst['id'], instance_uuid=inst['uuid'],
- host=inst['host'], vpn=None, rxtx_factor=3,
- project_id=project_id, macs=available_macs)
- assigned_macs = [vif['address'] for vif in nw_info]
- self.assertEqual(1, len(assigned_macs))
- self.assertEqual(available_macs.pop(), assigned_macs[0])
- self.network.deallocate_for_instance(self.context,
- instance_id=inst['id'],
- host=self.network.host,
- project_id=project_id)
-
- def test_allocate_for_instance_not_enough_macs(self):
- available_macs = set()
- inst = db.instance_create(self.context, {'host': HOST,
- 'display_name': HOST,
- 'instance_type_id': 1})
- networks = db.network_get_all(self.context)
- for network in networks:
- db.network_update(self.context, network['id'],
- {'host': self.network.host})
- project_id = self.context.project_id
- self.assertRaises(exception.VirtualInterfaceCreateException,
- self.network.allocate_for_instance,
- self.user_context,
- instance_id=inst['id'], instance_uuid=inst['uuid'],
- host=inst['host'], vpn=None, rxtx_factor=3,
- project_id=project_id, macs=available_macs)
-
-
-class FloatingIPTestCase(test.TestCase):
- """Tests nova.network.manager.FloatingIP."""
-
- REQUIRES_LOCKING = True
-
- def setUp(self):
- super(FloatingIPTestCase, self).setUp()
- self.tempdir = self.useFixture(fixtures.TempDir()).path
- self.flags(log_dir=self.tempdir)
- self.network = FakeFloatingIPManager()
- self.network.db = db
- self.project_id = fakes.FAKE_PROJECT_ID
- self.context = context.RequestContext('testuser', self.project_id,
- is_admin=False)
-
- @mock.patch('nova.db.api.fixed_ip_get')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.instance_get_by_uuid')
- @mock.patch('nova.db.api.service_get_by_host_and_binary')
- @mock.patch('nova.db.api.floating_ip_get_by_address')
- def test_disassociate_floating_ip_multi_host_calls(self, floating_get,
- service_get,
- inst_get, net_get,
- fixed_get):
- floating_ip = dict(test_floating_ip.fake_floating_ip,
- fixed_ip_id=12)
-
- fixed_ip = dict(test_fixed_ip.fake_fixed_ip,
- network_id=None,
- instance_uuid=uuids.instance)
-
- network = dict(test_network.fake_network,
- multi_host=True)
-
- instance = dict(fake_instance.fake_db_instance(host='some-other-host'))
-
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- self.stubs.Set(self.network,
- '_floating_ip_owned_by_project',
- lambda _x, _y: True)
-
- floating_get.return_value = floating_ip
- fixed_get.return_value = fixed_ip
- net_get.return_value = network
- inst_get.return_value = instance
- service_get.return_value = test_service.fake_service
-
- self.stubs.Set(self.network.servicegroup_api,
- 'service_is_up',
- lambda _x: True)
-
- self.mox.StubOutWithMock(
- self.network.network_rpcapi, '_disassociate_floating_ip')
-
- self.network.network_rpcapi._disassociate_floating_ip(
- ctxt, 'fl_ip', mox.IgnoreArg(), 'some-other-host',
- uuids.instance)
- self.mox.ReplayAll()
-
- self.network.disassociate_floating_ip(ctxt, 'fl_ip', True)
-
- @mock.patch('nova.db.api.fixed_ip_get_by_address')
- @mock.patch('nova.db.api.network_get')
- @mock.patch('nova.db.api.instance_get_by_uuid')
- @mock.patch('nova.db.api.floating_ip_get_by_address')
- def test_associate_floating_ip_multi_host_calls(self, floating_get,
- inst_get, net_get,
- fixed_get):
- floating_ip = dict(test_floating_ip.fake_floating_ip,
- fixed_ip_id=None)
-
- fixed_ip = dict(test_fixed_ip.fake_fixed_ip,
- network_id=None,
- instance_uuid=uuids.instance)
-
- network = dict(test_network.fake_network,
- multi_host=True)
-
- instance = dict(fake_instance.fake_db_instance(host='some-other-host'))
-
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=False)
-
- self.stubs.Set(self.network,
- '_floating_ip_owned_by_project',
- lambda _x, _y: True)
-
- floating_get.return_value = floating_ip
- fixed_get.return_value = fixed_ip
- net_get.return_value = network
- inst_get.return_value = instance
-
- self.mox.StubOutWithMock(
- self.network.network_rpcapi, '_associate_floating_ip')
-
- self.network.network_rpcapi._associate_floating_ip(
- ctxt, 'fl_ip', 'fix_ip', mox.IgnoreArg(), 'some-other-host',
- uuids.instance)
- self.mox.ReplayAll()
-
- self.network.associate_floating_ip(ctxt, 'fl_ip', 'fix_ip', True)
-
- def test_double_deallocation(self):
- instance_ref = db.instance_create(self.context,
- {"project_id": self.project_id})
- # Run it twice to make it fault if it does not handle
- # instances without fixed networks
- # If this fails in either, it does not handle having no addresses
- self.network.deallocate_for_instance(self.context,
- instance_id=instance_ref['id'])
- self.network.deallocate_for_instance(self.context,
- instance_id=instance_ref['id'])
-
- @mock.patch('nova.privsep.linux_net.unbind_ip')
- @mock.patch('nova.privsep.linux_net.clean_conntrack')
- @mock.patch('nova.privsep.linux_net.modify_ebtables')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def test_deallocation_deleted_instance(
- self, mock_iptables_set_rules, mock_iptables_get_rules,
- mock_modify_ebtables, mock_clean_conntrack, mock_unbind_ip):
- self.stubs.Set(self.network, '_teardown_network_on_host',
- lambda *args, **kwargs: None)
- instance = objects.Instance(context=self.context)
- instance.project_id = self.project_id
- instance.create()
- instance.destroy()
- network = db.network_create_safe(self.context.elevated(), {
- 'project_id': self.project_id,
- 'host': CONF.host,
- 'label': 'foo'})
- fixed = db.fixed_ip_create(self.context, {'allocated': True,
- 'instance_uuid': instance.uuid, 'address': '10.1.1.1',
- 'network_id': network['id']})
- db.floating_ip_create(self.context, {
- 'address': '10.10.10.10', 'instance_uuid': instance.uuid,
- 'fixed_ip_id': fixed['id'],
- 'project_id': self.project_id})
- self.network.deallocate_for_instance(self.context, instance=instance)
-
- @mock.patch('nova.privsep.linux_net.unbind_ip')
- @mock.patch('nova.privsep.linux_net.clean_conntrack')
- @mock.patch('nova.privsep.linux_net.modify_ebtables')
- @mock.patch('nova.privsep.linux_net.iptables_get_rules',
- return_value=('', ''))
- @mock.patch('nova.privsep.linux_net.iptables_set_rules',
- return_value=('', ''))
- def test_deallocation_duplicate_floating_ip(
- self, mock_iptables_set_rules, mock_iptables_get_rules,
- mock_modify_ebtables, mock_clean_conntrack, mock_unbind_ip):
- self.stubs.Set(self.network, '_teardown_network_on_host',
- lambda *args, **kwargs: None)
- instance = objects.Instance(context=self.context)
- instance.project_id = self.project_id
- instance.create()
- network = db.network_create_safe(self.context.elevated(), {
- 'project_id': self.project_id,
- 'host': CONF.host,
- 'label': 'foo'})
- fixed = db.fixed_ip_create(self.context, {'allocated': True,
- 'instance_uuid': instance.uuid, 'address': '10.1.1.1',
- 'network_id': network['id']})
- db.floating_ip_create(self.context, {
- 'address': '10.10.10.10',
- 'deleted': True})
- db.floating_ip_create(self.context, {
- 'address': '10.10.10.10', 'instance_uuid': instance.uuid,
- 'fixed_ip_id': fixed['id'],
- 'project_id': self.project_id})
- self.network.deallocate_for_instance(self.context, instance=instance)
-
- @mock.patch('nova.db.api.fixed_ip_get')
- @mock.patch('nova.db.api.floating_ip_get_by_address')
- @mock.patch('nova.db.api.floating_ip_update')
- @mock.patch('nova.privsep.linux_net.clean_conntrack')
- def test_migrate_instance_start(self, clean_conntrack, floating_update,
- floating_get, fixed_get):
- called = {'count': 0}
-
- def fake_floating_ip_get_by_address(context, address):
- return dict(test_floating_ip.fake_floating_ip,
- address=address,
- fixed_ip_id=0)
-
- def fake_is_stale_floating_ip_address(context, floating_ip):
- return str(floating_ip.address) == '172.24.4.23'
-
- floating_get.side_effect = fake_floating_ip_get_by_address
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- instance_uuid=uuids.instance,
- address='10.0.0.2',
- network=test_network.fake_network)
- floating_update.return_value = fake_floating_ip_get_by_address(
- None, '1.2.3.4')
-
- def fake_remove_floating_ip(floating_addr, fixed_addr, interface,
- network):
- called['count'] += 1
-
- def fake_clean_conntrack(fixed_ip):
- if not str(fixed_ip) == "10.0.0.2":
- raise exception.FixedIpInvalid(address=fixed_ip)
-
- self.stubs.Set(self.network, '_is_stale_floating_ip_address',
- fake_is_stale_floating_ip_address)
- self.stubs.Set(self.network.l3driver, 'remove_floating_ip',
- fake_remove_floating_ip)
- clean_conntrack.side_effect = fake_clean_conntrack
-
- self.mox.ReplayAll()
- addresses = ['172.24.4.23', '172.24.4.24', '172.24.4.25']
- self.network.migrate_instance_start(self.context,
- instance_uuid=FAKEUUID,
- floating_addresses=addresses,
- rxtx_factor=3,
- project_id=self.project_id,
- source='fake_source',
- dest='fake_dest')
-
- self.assertEqual(2, called['count'])
-
- @mock.patch('nova.db.api.fixed_ip_get')
- @mock.patch('nova.db.api.floating_ip_update')
- def test_migrate_instance_finish(self, floating_update, fixed_get):
- called = {'count': 0}
-
- def fake_floating_ip_get_by_address(context, address):
- return dict(test_floating_ip.fake_floating_ip,
- address=address,
- fixed_ip_id=0)
-
- def fake_is_stale_floating_ip_address(context, floating_ip):
- return str(floating_ip.address) == '172.24.4.23'
-
- fixed_get.return_value = dict(test_fixed_ip.fake_fixed_ip,
- instance_uuid=uuids.instance,
- address='10.0.0.2',
- network=test_network.fake_network)
- floating_update.return_value = fake_floating_ip_get_by_address(
- None, '1.2.3.4')
-
- def fake_add_floating_ip(floating_addr, fixed_addr, interface,
- network):
- called['count'] += 1
-
- self.stubs.Set(self.network.db, 'floating_ip_get_by_address',
- fake_floating_ip_get_by_address)
- self.stubs.Set(self.network, '_is_stale_floating_ip_address',
- fake_is_stale_floating_ip_address)
- self.stubs.Set(self.network.l3driver, 'add_floating_ip',
- fake_add_floating_ip)
- self.mox.ReplayAll()
- addresses = ['172.24.4.23', '172.24.4.24', '172.24.4.25']
- self.network.migrate_instance_finish(self.context,
- instance_uuid=FAKEUUID,
- floating_addresses=addresses,
- host='fake_dest',
- rxtx_factor=3,
- project_id=self.project_id,
- source='fake_source')
-
- self.assertEqual(2, called['count'])
-
- def test_floating_dns_create_conflict(self):
- zone = "example.org"
- address1 = "10.10.10.11"
- name1 = "foo"
-
- self.network.add_dns_entry(self.context, address1, name1, "A", zone)
-
- self.assertRaises(exception.FloatingIpDNSExists,
- self.network.add_dns_entry, self.context,
- address1, name1, "A", zone)
-
- def test_floating_create_and_get(self):
- zone = "example.org"
- address1 = "10.10.10.11"
- name1 = "foo"
- name2 = "bar"
- entries = self.network.get_dns_entries_by_address(self.context,
- address1, zone)
- self.assertFalse(entries)
-
- self.network.add_dns_entry(self.context, address1, name1, "A", zone)
- self.network.add_dns_entry(self.context, address1, name2, "A", zone)
- entries = self.network.get_dns_entries_by_address(self.context,
- address1, zone)
- self.assertEqual(2, len(entries))
- self.assertEqual(name1, entries[0])
- self.assertEqual(name2, entries[1])
-
- entries = self.network.get_dns_entries_by_name(self.context,
- name1, zone)
- self.assertEqual(1, len(entries))
- self.assertEqual(address1, entries[0])
-
- def test_floating_dns_delete(self):
- zone = "example.org"
- address1 = "10.10.10.11"
- name1 = "foo"
- name2 = "bar"
-
- self.network.add_dns_entry(self.context, address1, name1, "A", zone)
- self.network.add_dns_entry(self.context, address1, name2, "A", zone)
- self.network.delete_dns_entry(self.context, name1, zone)
-
- entries = self.network.get_dns_entries_by_address(self.context,
- address1, zone)
- self.assertEqual(1, len(entries))
- self.assertEqual(name2, entries[0])
-
- self.assertRaises(exception.NotFound,
- self.network.delete_dns_entry, self.context,
- name1, zone)
-
- def test_floating_dns_domains_public(self):
- domain1 = "example.org"
- domain2 = "example.com"
- address1 = '10.10.10.10'
- entryname = 'testentry'
-
- self.network.create_public_dns_domain(self.context, domain1,
- fakes.FAKE_PROJECT_ID)
- self.network.create_public_dns_domain(self.context, domain2,
- 'fakeproject')
-
- domains = self.network.get_dns_domains(self.context)
- self.assertEqual(2, len(domains))
- self.assertEqual(domain1, domains[0]['domain'])
- self.assertEqual(domain2, domains[1]['domain'])
- self.assertEqual(fakes.FAKE_PROJECT_ID, domains[0]['project'])
- self.assertEqual('fakeproject', domains[1]['project'])
-
- self.network.add_dns_entry(self.context, address1, entryname,
- 'A', domain1)
- entries = self.network.get_dns_entries_by_name(self.context,
- entryname, domain1)
- self.assertEqual(1, len(entries))
- self.assertEqual(address1, entries[0])
-
- self.network.delete_dns_domain(self.context, domain1)
- self.network.delete_dns_domain(self.context, domain2)
-
- # Verify that deleting the domain deleted the associated entry
- entries = self.network.get_dns_entries_by_name(self.context,
- entryname, domain1)
- self.assertFalse(entries)
-
- def test_delete_all_by_ip(self):
- domain1 = "example.org"
- domain2 = "example.com"
- address = "10.10.10.10"
- name1 = "foo"
- name2 = "bar"
-
- def fake_domains(context):
- return [{'domain': 'example.org', 'scope': 'public'},
- {'domain': 'example.com', 'scope': 'public'},
- {'domain': 'test.example.org', 'scope': 'public'}]
-
- self.stubs.Set(self.network, 'get_dns_domains', fake_domains)
-
- context_admin = context.RequestContext('testuser',
- fakes.FAKE_PROJECT_ID,
- is_admin=True)
-
- self.network.create_public_dns_domain(context_admin, domain1,
- fakes.FAKE_PROJECT_ID)
- self.network.create_public_dns_domain(context_admin, domain2,
- 'fakeproject')
-
- domains = self.network.get_dns_domains(self.context)
- for domain in domains:
- self.network.add_dns_entry(self.context, address,
- name1, "A", domain['domain'])
- self.network.add_dns_entry(self.context, address,
- name2, "A", domain['domain'])
- entries = self.network.get_dns_entries_by_address(self.context,
- address,
- domain['domain'])
- self.assertEqual(2, len(entries))
-
- self.network._delete_all_entries_for_ip(self.context, address)
-
- for domain in domains:
- entries = self.network.get_dns_entries_by_address(self.context,
- address,
- domain['domain'])
- self.assertFalse(entries)
-
- self.network.delete_dns_domain(context_admin, domain1)
- self.network.delete_dns_domain(context_admin, domain2)
-
- def test_mac_conflicts(self):
- # Make sure MAC collisions are retried.
- self.flags(create_unique_mac_address_attempts=3)
- ctxt = context.RequestContext('testuser', fakes.FAKE_PROJECT_ID,
- is_admin=True)
- macs = ['bb:bb:bb:bb:bb:bb', 'aa:aa:aa:aa:aa:aa']
-
- # Create a VIF with aa:aa:aa:aa:aa:aa
- crash_test_dummy_vif = {
- 'address': macs[1],
- 'instance_uuid': uuids.instance,
- 'network_id': 123,
- 'uuid': 'fake_uuid',
- }
- self.network.db.virtual_interface_create(ctxt, crash_test_dummy_vif)
-
- # Hand out a collision first, then a legit MAC
- def fake_gen_mac():
- return macs.pop()
- self.stubs.Set(utils, 'generate_mac_address', fake_gen_mac)
-
- # SQLite doesn't seem to honor the uniqueness constraint on the
- # address column, so fake the collision-avoidance here
- def fake_vif_save(vif, session=None):
- if vif.address == crash_test_dummy_vif['address']:
- raise db_exc.DBError("If you're smart, you'll retry!")
- # NOTE(russellb) The VirtualInterface object requires an ID to be
- # set, and we expect it to get set automatically when we do the
- # save.
- vif.id = 1
- self.stubs.Set(models.VirtualInterface, 'save', fake_vif_save)
-
- # Attempt to add another and make sure that both MACs are consumed
- # by the retry loop
- self.network._add_virtual_interface(ctxt, uuids.instance, 123)
- self.assertEqual([], macs)
-
- def test_deallocate_client_exceptions(self):
- # Ensure that FloatingIpNotFoundForAddress is wrapped.
- self.mox.StubOutWithMock(self.network.db, 'floating_ip_get_by_address')
- self.network.db.floating_ip_get_by_address(
- self.context, '1.2.3.4').AndRaise(
- exception.FloatingIpNotFoundForAddress(address='fake'))
- self.mox.ReplayAll()
- self.assertRaises(messaging.ExpectedException,
- self.network.deallocate_floating_ip,
- self.context, '1.2.3.4')
-
- def test_associate_client_exceptions(self):
- # Ensure that FloatingIpNotFoundForAddress is wrapped.
- self.mox.StubOutWithMock(self.network.db, 'floating_ip_get_by_address')
- self.network.db.floating_ip_get_by_address(
- self.context, '1.2.3.4').AndRaise(
- exception.FloatingIpNotFoundForAddress(address='fake'))
- self.mox.ReplayAll()
- self.assertRaises(messaging.ExpectedException,
- self.network.associate_floating_ip,
- self.context, '1.2.3.4', '10.0.0.1')
-
- def test_disassociate_client_exceptions(self):
- # Ensure that FloatingIpNotFoundForAddress is wrapped.
- self.mox.StubOutWithMock(self.network.db, 'floating_ip_get_by_address')
- self.network.db.floating_ip_get_by_address(
- self.context, '1.2.3.4').AndRaise(
- exception.FloatingIpNotFoundForAddress(address='fake'))
- self.mox.ReplayAll()
- self.assertRaises(messaging.ExpectedException,
- self.network.disassociate_floating_ip,
- self.context, '1.2.3.4')
-
- def test_get_floating_ip_client_exceptions(self):
- # Ensure that FloatingIpNotFoundForAddress is wrapped.
- self.mox.StubOutWithMock(self.network.db, 'floating_ip_get')
- self.network.db.floating_ip_get(self.context, 'fake-id').AndRaise(
- exception.FloatingIpNotFound(id='fake'))
- self.mox.ReplayAll()
- self.assertRaises(messaging.ExpectedException,
- self.network.get_floating_ip,
- self.context, 'fake-id')
-
- def _test_associate_floating_ip_failure(self, stdout, expected_exception):
- def _fake_catchall(*args, **kwargs):
- return dict(test_fixed_ip.fake_fixed_ip,
- network=test_network.fake_network)
-
- def _fake_add_floating_ip(*args, **kwargs):
- raise processutils.ProcessExecutionError(stdout)
-
- self.stubs.Set(self.network.db, 'floating_ip_fixed_ip_associate',
- _fake_catchall)
- self.stubs.Set(self.network.db, 'floating_ip_disassociate',
- _fake_catchall)
- self.stubs.Set(self.network.l3driver, 'add_floating_ip',
- _fake_add_floating_ip)
-
- self.assertRaises(expected_exception,
- self.network._associate_floating_ip, self.context,
- '1.2.3.4', '1.2.3.5', '', '')
-
- def test_associate_floating_ip_failure(self):
- self._test_associate_floating_ip_failure(None,
- processutils.ProcessExecutionError)
-
- def test_associate_floating_ip_failure_interface_not_found(self):
- self._test_associate_floating_ip_failure('Cannot find device',
- exception.NoFloatingIpInterface)
-
- @mock.patch('nova.objects.FloatingIP.get_by_address')
- def test_get_floating_ip_by_address(self, mock_get):
- mock_get.return_value = mock.sentinel.floating
- self.assertEqual(mock.sentinel.floating,
- self.network.get_floating_ip_by_address(
- self.context,
- mock.sentinel.address))
- mock_get.assert_called_once_with(self.context, mock.sentinel.address)
-
- @mock.patch('nova.objects.FloatingIPList.get_by_project')
- def test_get_floating_ips_by_project(self, mock_get):
- mock_get.return_value = mock.sentinel.floatings
- self.assertEqual(mock.sentinel.floatings,
- self.network.get_floating_ips_by_project(
- self.context))
- mock_get.assert_called_once_with(self.context, self.context.project_id)
-
- @mock.patch('nova.objects.FloatingIPList.get_by_fixed_address')
- def test_get_floating_ips_by_fixed_address(self, mock_get):
- mock_get.return_value = [objects.FloatingIP(address='1.2.3.4'),
- objects.FloatingIP(address='5.6.7.8')]
- self.assertEqual(['1.2.3.4', '5.6.7.8'],
- self.network.get_floating_ips_by_fixed_address(
- self.context, mock.sentinel.address))
- mock_get.assert_called_once_with(self.context, mock.sentinel.address)
-
- @mock.patch('nova.db.api.floating_ip_get_pools')
- def test_floating_ip_pool_exists(self, floating_ip_get_pools):
- floating_ip_get_pools.return_value = [{'name': 'public'}]
- self.assertTrue(self.network._floating_ip_pool_exists(self.context,
- 'public'))
-
- @mock.patch('nova.db.api.floating_ip_get_pools')
- def test_floating_ip_pool_does_not_exist(self, floating_ip_get_pools):
- floating_ip_get_pools.return_value = []
- self.assertFalse(self.network._floating_ip_pool_exists(self.context,
- 'public'))
-
-
-class InstanceDNSTestCase(test.TestCase):
- """Tests nova.network.manager instance DNS."""
- def setUp(self):
- super(InstanceDNSTestCase, self).setUp()
- self.tempdir = self.useFixture(fixtures.TempDir()).path
- self.flags(log_dir=self.tempdir)
- self.network = FakeFloatingIPManager()
- self.network.db = db
- self.project_id = fakes.FAKE_PROJECT_ID
- self.context = context.RequestContext('testuser', self.project_id,
- is_admin=False)
-
- def test_dns_domains_private(self):
- zone1 = 'testzone'
- domain1 = 'example.org'
-
- self.network.create_private_dns_domain(self.context, domain1, zone1)
- domains = self.network.get_dns_domains(self.context)
- self.assertEqual(1, len(domains))
- self.assertEqual(domain1, domains[0]['domain'])
- self.assertEqual(zone1, domains[0]['availability_zone'])
-
- self.network.delete_dns_domain(self.context, domain1)
-
-
-domain1 = "example.org"
-domain2 = "example.com"
-
-
-@testtools.skipIf(six.PY3, 'python-ldap is not compatible for Python 3.')
-class LdapDNSTestCase(test.NoDBTestCase):
- """Tests nova.network.ldapdns.LdapDNS."""
- def setUp(self):
- super(LdapDNSTestCase, self).setUp()
-
- self.useFixture(fixtures.MonkeyPatch(
- 'nova.network.ldapdns.ldap',
- fake_ldap))
- dns_class = 'nova.network.ldapdns.LdapDNS'
- self.driver = importutils.import_object(dns_class)
-
- attrs = {'objectClass': ['domainrelatedobject', 'dnsdomain',
- 'domain', 'dcobject', 'top'],
- 'associateddomain': ['root'],
- 'dc': ['root']}
- self.driver.lobj.add_s("ou=hosts,dc=example,dc=org", attrs.items())
- self.driver.create_domain(domain1)
- self.driver.create_domain(domain2)
-
- def tearDown(self):
- self.driver.delete_domain(domain1)
- self.driver.delete_domain(domain2)
- super(LdapDNSTestCase, self).tearDown()
-
- def test_ldap_dns_domains(self):
- domains = self.driver.get_domains()
- self.assertEqual(2, len(domains))
- self.assertIn(domain1, domains)
- self.assertIn(domain2, domains)
-
- def test_ldap_dns_create_conflict(self):
- address1 = "10.10.10.11"
- name1 = "foo"
-
- self.driver.create_entry(name1, address1, "A", domain1)
-
- self.assertRaises(exception.FloatingIpDNSExists,
- self.driver.create_entry,
- name1, address1, "A", domain1)
-
- def test_ldap_dns_create_and_get(self):
- address1 = "10.10.10.11"
- name1 = "foo"
- name2 = "bar"
- entries = self.driver.get_entries_by_address(address1, domain1)
- self.assertFalse(entries)
-
- self.driver.create_entry(name1, address1, "A", domain1)
- self.driver.create_entry(name2, address1, "A", domain1)
- entries = self.driver.get_entries_by_address(address1, domain1)
- self.assertEqual(2, len(entries))
- self.assertEqual(name1, entries[0])
- self.assertEqual(name2, entries[1])
-
- entries = self.driver.get_entries_by_name(name1, domain1)
- self.assertEqual(1, len(entries))
- self.assertEqual(address1, entries[0])
-
- def test_ldap_dns_delete(self):
- address1 = "10.10.10.11"
- name1 = "foo"
- name2 = "bar"
-
- self.driver.create_entry(name1, address1, "A", domain1)
- self.driver.create_entry(name2, address1, "A", domain1)
- entries = self.driver.get_entries_by_address(address1, domain1)
- self.assertEqual(2, len(entries))
-
- self.driver.delete_entry(name1, domain1)
- entries = self.driver.get_entries_by_address(address1, domain1)
- LOG.debug("entries: %s", entries)
- self.assertEqual(1, len(entries))
- self.assertEqual(name2, entries[0])
-
- self.assertRaises(exception.NotFound,
- self.driver.delete_entry,
- name1, domain1)
-
-
-class NetworkManagerNoDBTestCase(test.NoDBTestCase):
- """Tests nova.network.manager.NetworkManager without a database."""
-
- def setUp(self):
- super(NetworkManagerNoDBTestCase, self).setUp()
- self.context = context.RequestContext('fake-user', 'fake-project')
- self.manager = network_manager.NetworkManager()
-
- @mock.patch.object(objects.FixedIP, 'get_by_address')
- def test_release_fixed_ip_not_associated(self, mock_fip_get_by_addr):
- # Tests that the method is a no-op when the fixed IP is not associated
- # to an instance.
- fip = objects.FixedIP._from_db_object(
- self.context, objects.FixedIP(), fake_network.next_fixed_ip(1))
- fip.instance_uuid = None
- with mock.patch.object(fip, 'disassociate') as mock_disassociate:
- self.manager.release_fixed_ip(self.context, fip.address)
-
- self.assertFalse(mock_disassociate.called,
- str(mock_disassociate.mock_calls))
-
- @mock.patch.object(objects.FixedIP, 'get_by_address')
- def test_release_fixed_ip_allocated(self, mock_fip_get_by_addr):
- # Tests that the fixed IP is not disassociated if it's allocated.
- fip = objects.FixedIP._from_db_object(
- self.context, objects.FixedIP(), fake_network.next_fixed_ip(1))
- fip.leased = False
- fip.allocated = True
- with mock.patch.object(fip, 'disassociate') as mock_disassociate:
- self.manager.release_fixed_ip(self.context, fip.address)
-
- self.assertFalse(mock_disassociate.called,
- str(mock_disassociate.mock_calls))
-
- @mock.patch.object(objects.FixedIP, 'get_by_address')
- @mock.patch.object(objects.VirtualInterface, 'get_by_address')
- def test_release_fixed_ip_mac_matches_associated_instance(self,
- mock_vif_get_by_addr,
- mock_fip_get_by_addr):
- # Tests that the fixed IP is disassociated when the mac passed to
- # release_fixed_ip matches the VIF which has the same instance_uuid
- # as the instance associated to the FixedIP object. Also tests
- # that the fixed IP is marked as not leased in the database if it was
- # currently leased.
- instance = fake_instance.fake_instance_obj(self.context)
- fip = fake_network.next_fixed_ip(1)
- fip['instance_uuid'] = instance.uuid
- fip['leased'] = True
- vif = fip['virtual_interface']
- vif['instance_uuid'] = instance.uuid
- vif = objects.VirtualInterface._from_db_object(
- self.context, objects.VirtualInterface(), vif)
- fip = objects.FixedIP._from_db_object(
- self.context, objects.FixedIP(), fip)
- mock_fip_get_by_addr.return_value = fip
- mock_vif_get_by_addr.return_value = vif
-
- with mock.patch.object(fip, 'save') as mock_fip_save:
- with mock.patch.object(fip, 'disassociate') as mock_disassociate:
- self.manager.release_fixed_ip(
- self.context, fip.address, vif.address)
-
- mock_fip_save.assert_called_once_with()
- self.assertFalse(fip.leased)
- mock_vif_get_by_addr.assert_called_once_with(self.context, vif.address)
- mock_disassociate.assert_called_once_with()
-
- @mock.patch.object(objects.FixedIP, 'get_by_address')
- @mock.patch.object(objects.VirtualInterface, 'get_by_address',
- return_value=None)
- def test_release_fixed_ip_vif_not_found_for_mac(self, mock_vif_get_by_addr,
- mock_fip_get_by_addr):
- # Tests that the fixed IP is disassociated when the fixed IP is marked
- # as deallocated and there is no VIF found in the database for the mac
- # passed in.
- fip = fake_network.next_fixed_ip(1)
- fip['leased'] = False
- mac = fip['virtual_interface']['address']
- fip = objects.FixedIP._from_db_object(
- self.context, objects.FixedIP(), fip)
- mock_fip_get_by_addr.return_value = fip
-
- with mock.patch.object(fip, 'disassociate') as mock_disassociate:
- self.manager.release_fixed_ip(self.context, fip.address, mac)
-
- mock_vif_get_by_addr.assert_called_once_with(self.context, mac)
- mock_disassociate.assert_called_once_with()
-
- @mock.patch.object(objects.FixedIP, 'get_by_address')
- def test_release_fixed_ip_no_mac(self, mock_fip_get_by_addr):
- # Tests that the fixed IP is disassociated when the fixed IP is
- # deallocated and there is no mac address passed in (like before
- # the network rpc api version bump to pass it in).
- fip = fake_network.next_fixed_ip(1)
- fip['leased'] = False
- fip = objects.FixedIP._from_db_object(
- self.context, objects.FixedIP(), fip)
- mock_fip_get_by_addr.return_value = fip
-
- with mock.patch.object(fip, 'disassociate') as mock_disassociate:
- self.manager.release_fixed_ip(self.context, fip.address)
-
- mock_disassociate.assert_called_once_with()
-
- @mock.patch.object(objects.FixedIP, 'get_by_address')
- @mock.patch.object(objects.VirtualInterface, 'get_by_address')
- def test_release_fixed_ip_mac_mismatch_associated_instance(self,
- mock_vif_get_by_addr,
- mock_fip_get_by_addr):
- # Tests that the fixed IP is not disassociated when the VIF for the mac
- # passed to release_fixed_ip does not have an instance_uuid that
- # matches fixed_ip.instance_uuid.
- old_instance = fake_instance.fake_instance_obj(self.context)
- new_instance = fake_instance.fake_instance_obj(self.context)
- fip = fake_network.next_fixed_ip(1)
- fip['instance_uuid'] = new_instance.uuid
- fip['leased'] = False
- vif = fip['virtual_interface']
- vif['instance_uuid'] = old_instance.uuid
- vif = objects.VirtualInterface._from_db_object(
- self.context, objects.VirtualInterface(), vif)
- fip = objects.FixedIP._from_db_object(
- self.context, objects.FixedIP(), fip)
- mock_fip_get_by_addr.return_value = fip
- mock_vif_get_by_addr.return_value = vif
-
- with mock.patch.object(fip, 'disassociate') as mock_disassociate:
- self.manager.release_fixed_ip(
- self.context, fip.address, vif.address)
-
- mock_vif_get_by_addr.assert_called_once_with(self.context, vif.address)
- self.assertFalse(mock_disassociate.called,
- str(mock_disassociate.mock_calls))
-
- @mock.patch.object(network_rpcapi.NetworkAPI, 'release_dhcp')
- @mock.patch.object(objects.FixedIP, 'get_by_address')
- @mock.patch.object(objects.VirtualInterface, 'get_by_id')
- @mock.patch.object(objects.Quotas, 'reserve')
- def test_deallocate_fixed_ip_explicit_disassociate(self,
- mock_quota_reserve,
- mock_vif_get_by_id,
- mock_fip_get_by_addr,
- mock_release_dhcp):
- # Tests that we explicitly call FixedIP.disassociate when the fixed IP
- # is not leased and has an associated instance (race with dnsmasq).
- self.flags(force_dhcp_release=True)
- fake_inst = fake_instance.fake_instance_obj(self.context)
- fip = fake_network.next_fixed_ip(1)
- fip['instance_uuid'] = fake_inst.uuid
- fip['leased'] = False
- vif = fip['virtual_interface']
- vif['instance_uuid'] = fake_inst.uuid
- vif = objects.VirtualInterface._from_db_object(
- self.context, objects.VirtualInterface(), vif)
- fip = objects.FixedIP._from_db_object(
- self.context, objects.FixedIP(), fip)
- fip.network = fake_network.fake_network_obj(self.context,
- fip.network_id)
- mock_fip_get_by_addr.return_value = fip
- mock_vif_get_by_id.return_value = vif
-
- @mock.patch.object(self.manager,
- '_do_trigger_security_group_members_refresh_for_instance')
- @mock.patch.object(self.manager,
- '_validate_instance_zone_for_dns_domain',
- return_value=False)
- @mock.patch.object(self.manager, '_teardown_network_on_host')
- @mock.patch.object(fip, 'save')
- @mock.patch.object(fip, 'disassociate')
- def do_test(mock_disassociate, mock_fip_save,
- mock_teardown_network_on_host, mock_validate_zone,
- mock_trigger_secgroup_refresh):
- self.assertEqual(fake_inst.uuid, fip.instance_uuid)
- self.assertFalse(fip.leased)
- self.manager.deallocate_fixed_ip(
- self.context, fip['address'], instance=fake_inst)
-
- mock_trigger_secgroup_refresh.assert_called_once_with(
- fake_inst.uuid)
- mock_teardown_network_on_host.assert_called_once_with(self.context,
- fip.network)
- mock_disassociate.assert_called_once_with()
-
- do_test()
diff --git a/nova/tests/unit/network/test_rpcapi.py b/nova/tests/unit/network/test_rpcapi.py
deleted file mode 100644
index 26a620d9d8..0000000000
--- a/nova/tests/unit/network/test_rpcapi.py
+++ /dev/null
@@ -1,417 +0,0 @@
-# Copyright 2013 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Unit Tests for nova.network.rpcapi
-"""
-
-import collections
-
-import mock
-from oslo_config import cfg
-
-from nova import context
-from nova import exception
-from nova.network import rpcapi as network_rpcapi
-from nova.objects import base as objects_base
-from nova import test
-from nova.tests.unit import fake_instance
-from nova.tests.unit import fake_network
-
-CONF = cfg.CONF
-
-
-class NetworkRpcAPITestCase(test.NoDBTestCase):
- def setUp(self):
- super(NetworkRpcAPITestCase, self).setUp()
- self.flags(multi_host=True)
-
- # Used to specify the default value expected if no real value is passed
- DefaultArg = collections.namedtuple('DefaultArg', ['value'])
-
- def _test_network_api(self, method, rpc_method, **kwargs):
- ctxt = context.RequestContext('fake_user', 'fake_project')
-
- rpcapi = network_rpcapi.NetworkAPI()
- self.assertIsNotNone(rpcapi.client)
- self.assertEqual(network_rpcapi.RPC_TOPIC,
- rpcapi.client.target.topic)
-
- expected_retval = 'foo' if rpc_method == 'call' else None
- expected_version = kwargs.pop('version', None)
- expected_fanout = kwargs.pop('fanout', None)
- expected_kwargs = kwargs.copy()
-
- for k, v in expected_kwargs.items():
- if isinstance(v, self.DefaultArg):
- expected_kwargs[k] = v.value
- kwargs.pop(k)
-
- prepare_kwargs = {}
- if expected_version:
- prepare_kwargs['version'] = expected_version
- if expected_fanout:
- prepare_kwargs['fanout'] = True
-
- if 'source_compute' in expected_kwargs:
- # Fix up for migrate_instance_* calls.
- expected_kwargs['source'] = expected_kwargs.pop('source_compute')
- expected_kwargs['dest'] = expected_kwargs.pop('dest_compute')
-
- targeted_methods = [
- 'lease_fixed_ip', 'release_fixed_ip', 'rpc_setup_network_on_host',
- '_rpc_allocate_fixed_ip', 'deallocate_fixed_ip', 'update_dns',
- '_associate_floating_ip', '_disassociate_floating_ip',
- 'lease_fixed_ip', 'release_fixed_ip', 'migrate_instance_start',
- 'migrate_instance_finish',
- 'allocate_for_instance', 'deallocate_for_instance',
- ]
- targeted_by_instance = ['deallocate_for_instance']
- if method in targeted_methods and ('host' in expected_kwargs or
- 'instance' in expected_kwargs):
- if method in targeted_by_instance:
- host = expected_kwargs['instance']['host']
- else:
- host = expected_kwargs['host']
- if method not in ['allocate_for_instance',
- 'deallocate_fixed_ip']:
- expected_kwargs.pop('host')
- if CONF.multi_host:
- prepare_kwargs['server'] = host
-
- with test.nested(
- mock.patch.object(rpcapi.client, rpc_method),
- mock.patch.object(rpcapi.client, 'prepare'),
- mock.patch.object(rpcapi.client, 'can_send_version'),
- ) as (
- rpc_mock, prepare_mock, csv_mock
- ):
-
- version_check = [
- 'deallocate_for_instance', 'deallocate_fixed_ip',
- 'allocate_for_instance', 'release_fixed_ip',
- 'set_network_host', 'setup_networks_on_host'
- ]
- if method in version_check:
- csv_mock.return_value = True
-
- if prepare_kwargs:
- prepare_mock.return_value = rpcapi.client
-
- if rpc_method == 'call':
- rpc_mock.return_value = 'foo'
- else:
- rpc_mock.return_value = None
-
- retval = getattr(rpcapi, method)(ctxt, **kwargs)
- self.assertEqual(expected_retval, retval)
-
- if method in version_check:
- csv_mock.assert_called_once_with(mock.ANY)
- if prepare_kwargs:
- prepare_mock.assert_called_once_with(**prepare_kwargs)
- rpc_mock.assert_called_once_with(ctxt, method, **expected_kwargs)
-
- def test_create_networks(self):
- self._test_network_api('create_networks', rpc_method='call',
- arg1='arg', arg2='arg')
-
- def test_delete_network(self):
- self._test_network_api('delete_network', rpc_method='call',
- uuid='fake_uuid', fixed_range='range')
-
- def test_allocate_for_instance(self):
- self._test_network_api('allocate_for_instance', rpc_method='call',
- instance_id='fake_id', project_id='fake_id', host='fake_host',
- rxtx_factor='fake_factor', vpn=False, requested_networks={},
- macs=[], version='1.13')
-
- def test_deallocate_for_instance(self):
- instance = fake_instance.fake_instance_obj(context.get_admin_context())
- self._test_network_api('deallocate_for_instance', rpc_method='call',
- requested_networks=self.DefaultArg(None), instance=instance,
- version='1.11')
-
- def test_deallocate_for_instance_with_expected_networks(self):
- instance = fake_instance.fake_instance_obj(context.get_admin_context())
- self._test_network_api('deallocate_for_instance', rpc_method='call',
- instance=instance, requested_networks={}, version='1.11')
-
- def test_release_dhcp(self):
- ctxt = context.RequestContext('fake_user', 'fake_project')
-
- dev = 'eth0'
- address = '192.168.65.158'
- vif_address = '00:0c:29:2c:b2:64'
- host = 'fake-host'
-
- rpcapi = network_rpcapi.NetworkAPI()
- call_mock = mock.Mock()
- cctxt_mock = mock.Mock(call=call_mock)
-
- with test.nested(
- mock.patch.object(rpcapi.client, 'can_send_version',
- return_value=True),
- mock.patch.object(rpcapi.client, 'prepare',
- return_value=cctxt_mock)
- ) as (
- can_send_mock, prepare_mock
- ):
- rpcapi.release_dhcp(ctxt, host, dev, address, vif_address)
-
- can_send_mock.assert_called_once_with('1.17')
- prepare_mock.assert_called_once_with(server=host, version='1.17')
- call_mock.assert_called_once_with(ctxt, 'release_dhcp', dev=dev,
- address=address,
- vif_address=vif_address)
-
- def test_release_dhcp_v116(self):
- ctxt = context.RequestContext('fake_user', 'fake_project')
-
- dev = 'eth0'
- address = '192.168.65.158'
- vif_address = '00:0c:29:2c:b2:64'
- host = 'fake-host'
- rpcapi = network_rpcapi.NetworkAPI()
-
- with mock.patch.object(rpcapi.client, 'can_send_version',
- return_value=False) as can_send_mock:
- self.assertRaises(exception.RPCPinnedToOldVersion,
- rpcapi.release_dhcp, ctxt, host, dev, address,
- vif_address)
- can_send_mock.assert_called_once_with('1.17')
-
- def test_add_fixed_ip_to_instance(self):
- self._test_network_api('add_fixed_ip_to_instance', rpc_method='call',
- instance_id='fake_id', rxtx_factor='fake_factor',
- host='fake_host', network_id='fake_id', version='1.9')
-
- def test_remove_fixed_ip_from_instance(self):
- self._test_network_api('remove_fixed_ip_from_instance',
- rpc_method='call', instance_id='fake_id',
- rxtx_factor='fake_factor', host='fake_host',
- address='fake_address', version='1.9')
-
- def test_get_instance_nw_info(self):
- self._test_network_api('get_instance_nw_info', rpc_method='call',
- instance_id='fake_id', rxtx_factor='fake_factor',
- host='fake_host', project_id='fake_id', version='1.9')
-
- def test_validate_networks(self):
- self._test_network_api('validate_networks', rpc_method='call',
- networks={})
-
- def test_get_dns_domains(self):
- self._test_network_api('get_dns_domains', rpc_method='call')
-
- def test_add_dns_entry(self):
- self._test_network_api('add_dns_entry', rpc_method='call',
- address='addr', name='name', dns_type='foo', domain='domain')
-
- def test_modify_dns_entry(self):
- self._test_network_api('modify_dns_entry', rpc_method='call',
- address='addr', name='name', domain='domain')
-
- def test_delete_dns_entry(self):
- self._test_network_api('delete_dns_entry', rpc_method='call',
- name='name', domain='domain')
-
- def test_delete_dns_domain(self):
- self._test_network_api('delete_dns_domain', rpc_method='call',
- domain='fake_domain')
-
- def test_get_dns_entries_by_address(self):
- self._test_network_api('get_dns_entries_by_address', rpc_method='call',
- address='fake_address', domain='fake_domain')
-
- def test_get_dns_entries_by_name(self):
- self._test_network_api('get_dns_entries_by_name', rpc_method='call',
- name='fake_name', domain='fake_domain')
-
- def test_create_private_dns_domain(self):
- self._test_network_api('create_private_dns_domain', rpc_method='call',
- domain='fake_domain', av_zone='fake_zone')
-
- def test_create_public_dns_domain(self):
- self._test_network_api('create_public_dns_domain', rpc_method='call',
- domain='fake_domain', project='fake_project')
-
- def test_setup_networks_on_host(self):
- ctxt = context.RequestContext('fake_user', 'fake_project')
- instance = fake_instance.fake_instance_obj(ctxt)
- self._test_network_api('setup_networks_on_host', rpc_method='call',
- instance_id=instance.id, host='fake_host', teardown=False,
- instance=instance, version='1.16')
-
- def test_setup_networks_on_host_v1_0(self):
- ctxt = context.RequestContext('fake_user', 'fake_project')
- instance = fake_instance.fake_instance_obj(ctxt)
- host = 'fake_host'
- teardown = True
- rpcapi = network_rpcapi.NetworkAPI()
- call_mock = mock.Mock()
- cctxt_mock = mock.Mock(call=call_mock)
- with test.nested(
- mock.patch.object(rpcapi.client, 'can_send_version',
- return_value=False),
- mock.patch.object(rpcapi.client, 'prepare',
- return_value=cctxt_mock)
- ) as (
- can_send_mock, prepare_mock
- ):
- rpcapi.setup_networks_on_host(ctxt, instance.id, host, teardown,
- instance)
- # assert our mocks were called as expected
- can_send_mock.assert_called_once_with('1.16')
- prepare_mock.assert_called_once_with(version='1.0')
- call_mock.assert_called_once_with(ctxt, 'setup_networks_on_host',
- host=host, teardown=teardown,
- instance_id=instance.id)
-
- def test_lease_fixed_ip(self):
- self._test_network_api('lease_fixed_ip', rpc_method='cast',
- host='fake_host', address='fake_addr')
-
- def test_release_fixed_ip(self):
- self._test_network_api('release_fixed_ip', rpc_method='cast',
- host='fake_host', address='fake_addr', mac='fake_mac',
- version='1.14')
-
- def test_release_fixed_ip_no_mac_support(self):
- # Tests that the mac kwarg is not passed when we can't send version
- # 1.14 to the network manager.
- ctxt = context.RequestContext('fake_user', 'fake_project')
- address = '192.168.65.158'
- host = 'fake-host'
- mac = '00:0c:29:2c:b2:64'
- rpcapi = network_rpcapi.NetworkAPI()
- cast_mock = mock.Mock()
- cctxt_mock = mock.Mock(cast=cast_mock)
- with test.nested(
- mock.patch.object(rpcapi.client, 'can_send_version',
- return_value=False),
- mock.patch.object(rpcapi.client, 'prepare',
- return_value=cctxt_mock)
- ) as (
- can_send_mock, prepare_mock
- ):
- rpcapi.release_fixed_ip(ctxt, address, host, mac)
- # assert our mocks were called as expected 232
- can_send_mock.assert_called_once_with('1.14')
- prepare_mock.assert_called_once_with(server=host, version='1.0')
- cast_mock.assert_called_once_with(ctxt, 'release_fixed_ip',
- address=address)
-
- def test_set_network_host(self):
- network = fake_network.fake_network_obj(context.get_admin_context())
- self._test_network_api('set_network_host', rpc_method='call',
- network_ref=network, version='1.15')
-
- def test_set_network_host_network_object_to_primitive(self):
- # Tests that the network object is converted to a primitive if it
- # can't send version 1.15.
- ctxt = context.RequestContext('fake_user', 'fake_project')
- network = fake_network.fake_network_obj(ctxt)
- network_dict = objects_base.obj_to_primitive(network)
- rpcapi = network_rpcapi.NetworkAPI()
- call_mock = mock.Mock()
- cctxt_mock = mock.Mock(call=call_mock)
- with test.nested(
- mock.patch.object(rpcapi.client, 'can_send_version',
- return_value=False),
- mock.patch.object(rpcapi.client, 'prepare',
- return_value=cctxt_mock)
- ) as (
- can_send_mock, prepare_mock
- ):
- rpcapi.set_network_host(ctxt, network)
- # assert our mocks were called as expected
- can_send_mock.assert_called_once_with('1.15')
- prepare_mock.assert_called_once_with(version='1.0')
- call_mock.assert_called_once_with(ctxt, 'set_network_host',
- network_ref=network_dict)
-
- def test_rpc_setup_network_on_host(self):
- self._test_network_api('rpc_setup_network_on_host', rpc_method='call',
- network_id='fake_id', teardown=False, host='fake_host')
-
- def test_rpc_allocate_fixed_ip(self):
- self._test_network_api('_rpc_allocate_fixed_ip', rpc_method='call',
- instance_id='fake_id', network_id='fake_id', address='addr',
- vpn=True, host='fake_host')
-
- def test_deallocate_fixed_ip(self):
- instance = fake_instance.fake_db_instance()
- self._test_network_api('deallocate_fixed_ip', rpc_method='call',
- address='fake_addr', host='fake_host', instance=instance,
- version='1.12')
-
- def test_update_dns(self):
- self._test_network_api('update_dns', rpc_method='cast', fanout=True,
- network_ids='fake_id', version='1.3')
-
- def test__associate_floating_ip(self):
- self._test_network_api('_associate_floating_ip', rpc_method='call',
- floating_address='fake_addr', fixed_address='fixed_address',
- interface='fake_interface', host='fake_host',
- instance_uuid='fake_uuid', version='1.6')
-
- def test__disassociate_floating_ip(self):
- self._test_network_api('_disassociate_floating_ip', rpc_method='call',
- address='fake_addr', interface='fake_interface',
- host='fake_host', instance_uuid='fake_uuid', version='1.6')
-
- def test_migrate_instance_start(self):
- self._test_network_api('migrate_instance_start', rpc_method='call',
- instance_uuid='fake_instance_uuid',
- rxtx_factor='fake_factor',
- project_id='fake_project',
- source_compute='fake_src_compute',
- dest_compute='fake_dest_compute',
- floating_addresses='fake_floating_addresses',
- host=self.DefaultArg(None),
- version='1.2')
-
- def test_migrate_instance_start_multi_host(self):
- self._test_network_api('migrate_instance_start', rpc_method='call',
- instance_uuid='fake_instance_uuid',
- rxtx_factor='fake_factor',
- project_id='fake_project',
- source_compute='fake_src_compute',
- dest_compute='fake_dest_compute',
- floating_addresses='fake_floating_addresses',
- host='fake_host',
- version='1.2')
-
- def test_migrate_instance_finish(self):
- self._test_network_api('migrate_instance_finish', rpc_method='call',
- instance_uuid='fake_instance_uuid',
- rxtx_factor='fake_factor',
- project_id='fake_project',
- source_compute='fake_src_compute',
- dest_compute='fake_dest_compute',
- floating_addresses='fake_floating_addresses',
- host=self.DefaultArg(None),
- version='1.2')
-
- def test_migrate_instance_finish_multi_host(self):
- self._test_network_api('migrate_instance_finish', rpc_method='call',
- instance_uuid='fake_instance_uuid',
- rxtx_factor='fake_factor',
- project_id='fake_project',
- source_compute='fake_src_compute',
- dest_compute='fake_dest_compute',
- floating_addresses='fake_floating_addresses',
- host='fake_host',
- version='1.2')
diff --git a/nova/tests/unit/objects/test_dns_domain.py b/nova/tests/unit/objects/test_dns_domain.py
deleted file mode 100644
index fc2810fbed..0000000000
--- a/nova/tests/unit/objects/test_dns_domain.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (C) 2014, Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from nova.db import api as db
-from nova.objects import dns_domain
-from nova.tests.unit.objects import test_objects
-
-
-fake_dnsd = {
- 'created_at': None,
- 'updated_at': None,
- 'deleted_at': None,
- 'deleted': 0,
- 'domain': 'blah.example.com',
- 'scope': 'private',
- 'availability_zone': 'overthere',
- 'project_id': '867530niner',
-}
-
-
-class _TestDNSDomain(object):
- @staticmethod
- def _compare(test, db, obj):
- for field, value in db.items():
- test.assertEqual(db[field], getattr(obj, field))
-
- def test_get_by_domain(self):
- with mock.patch.object(db, 'dnsdomain_get') as get:
- get.return_value = fake_dnsd
- dnsd = dns_domain.DNSDomain.get_by_domain(self.context, 'domain')
- self._compare(self, fake_dnsd, dnsd)
-
- def test_register_for_zone(self):
- dns_domain.DNSDomain.register_for_zone(self.context.elevated(),
- 'domain', 'zone')
- dnsd = dns_domain.DNSDomain.get_by_domain(self.context, 'domain')
- self.assertEqual('domain', dnsd.domain)
- self.assertEqual('zone', dnsd.availability_zone)
-
- def test_register_for_project(self):
- dns_domain.DNSDomain.register_for_project(self.context.elevated(),
- 'domain', 'project')
- dnsd = dns_domain.DNSDomain.get_by_domain(self.context, 'domain')
- self.assertEqual('domain', dnsd.domain)
- self.assertEqual('project', dnsd.project_id)
-
- def test_delete_by_domain(self):
- dns_domain.DNSDomain.register_for_zone(self.context.elevated(),
- 'domain', 'zone')
- dnsd = dns_domain.DNSDomain.get_by_domain(self.context, 'domain')
- self.assertEqual('domain', dnsd.domain)
- self.assertEqual('zone', dnsd.availability_zone)
-
- dns_domain.DNSDomain.delete_by_domain(self.context.elevated(),
- 'domain')
- dnsd = dns_domain.DNSDomain.get_by_domain(self.context, 'domain')
- self.assertIsNone(dnsd)
-
- def test_get_all(self):
- with mock.patch.object(db, 'dnsdomain_get_all') as get:
- get.return_value = [fake_dnsd]
- dns_domain.DNSDomainList.get_all(self.context)
-
-
-class TestDNSDomainObject(test_objects._LocalTest,
- _TestDNSDomain):
- pass
-
-
-class TestRemoteDNSDomainObject(test_objects._RemoteTest,
- _TestDNSDomain):
- pass
diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py
index cfcfc71f39..2cdf1d5229 100644
--- a/nova/tests/unit/objects/test_objects.py
+++ b/nova/tests/unit/objects/test_objects.py
@@ -1047,8 +1047,6 @@ object_data = {
'ComputeNodeList': '1.17-52f3b0962b1c86b98590144463ebb192',
'ConsoleAuthToken': '1.1-8da320fb065080eb4d3c2e5c59f8bf52',
'CpuDiagnostics': '1.0-d256f2e442d1b837735fd17dfe8e3d47',
- 'DNSDomain': '1.0-7b0b2dab778454b6a7b6c66afe163a1a',
- 'DNSDomainList': '1.0-4ee0d9efdfd681fed822da88376e04d2',
'Destination': '1.4-3b440d29459e2c98987ad5b25ad1cb2c',
'DeviceBus': '1.0-77509ea1ea0dd750d5864b9bd87d3f9d',
'DeviceMetadata': '1.0-04eb8fd218a49cbc3b1e54b774d179f7',
diff --git a/nova/tests/unit/privsep/test_linux_net.py b/nova/tests/unit/privsep/test_linux_net.py
index 86776544d4..5bdac6ca02 100644
--- a/nova/tests/unit/privsep/test_linux_net.py
+++ b/nova/tests/unit/privsep/test_linux_net.py
@@ -16,9 +16,7 @@
import mock
from oslo_concurrency import processutils
-import six
-from nova import exception
import nova.privsep.linux_net
from nova import test
from nova.tests import fixtures
@@ -32,11 +30,6 @@ class LinuxNetTestCase(test.NoDBTestCase):
super(LinuxNetTestCase, self).setUp()
self.useFixture(fixtures.PrivsepFixture())
- def test_bridge_add_interface(self, mock_execute):
- nova.privsep.linux_net.bridge_add_interface('br0', 'eth0')
- cmd = ['brctl', 'addif', 'br0', 'eth0']
- mock_execute.assert_called_once_with(*cmd, check_exit_code=False)
-
@mock.patch('os.path.exists')
def test_device_exists(self, mock_exists, mock_execute):
nova.privsep.linux_net.device_exists('eth0')
@@ -123,115 +116,8 @@ class LinuxNetTestCase(test.NoDBTestCase):
nova.privsep.linux_net.create_tap_dev,
'tap42', multiqueue=True)
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=False)
- def test_enable_ipv4_forwarding_required(self, mock_check, mock_execute):
- nova.privsep.linux_net.enable_ipv4_forwarding()
- mock_check.assert_called_once()
- mock_execute.assert_called_once_with(
- 'sysctl', '-w', 'net.ipv4.ip_forward=1')
-
- @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check',
- return_value=True)
- def test_enable_ipv4_forwarding_redundant(self, mock_check, mock_execute):
- nova.privsep.linux_net.enable_ipv4_forwarding()
- mock_check.assert_called_once()
- mock_execute.assert_not_called()
-
- def test_modify_ebtables_insert_rule(self, mock_execute):
- table = 'filter'
- rule = 'INPUT -p ARP -i %s --arp-ip-dst %s -j DROP'.split()
-
- nova.privsep.linux_net.modify_ebtables(table, rule, insert_rule=True)
-
- cmd = ['ebtables', '--concurrent', '-t', table] + ['-I'] + rule
- mock_execute.assert_called_once_with(*cmd, check_exit_code=[0])
-
- def test_modify_ebtables_remove_rule(self, mock_execute):
- table = 'filter'
- rule = 'INPUT -p ARP -i %s --arp-ip-dst %s -j DROP'.split()
-
- nova.privsep.linux_net.modify_ebtables(table, rule, insert_rule=False)
-
- cmd = ['ebtables', '--concurrent', '-t', table] + ['-D'] + rule
- mock_execute.assert_called_once_with(*cmd, check_exit_code=[0])
-
def test_add_vlan(self, mock_execute):
nova.privsep.linux_net.add_vlan('eth0', 'vlan_name', 1)
cmd = ['ip', 'link', 'add', 'link', 'eth0', 'name', 'vlan_name',
'type', 'vlan', 'id', 1]
mock_execute.assert_called_once_with(*cmd, check_exit_code=[0, 2, 254])
-
- def test_iptables_get_rules(self, mock_execute):
- nova.privsep.linux_net.iptables_get_rules()
- cmd = ['iptables-save', '-c']
- mock_execute.assert_called_once_with(*cmd, attempts=5)
-
- def test_iptables_get_rules_ipv6(self, mock_execute):
- nova.privsep.linux_net.iptables_get_rules(ipv4=False)
- cmd = ['ip6tables-save', '-c']
- mock_execute.assert_called_once_with(*cmd, attempts=5)
-
- def test_iptables_set_rules(self, mock_execute):
- rules = [
- "# Generated by iptables-save v1.8.2 on Mon Aug 19 11:25:48 2019",
- "*security",
- ":INPUT ACCEPT [508089:729290563]",
- ":FORWARD ACCEPT [247333:239588306]",
- ":OUTPUT ACCEPT [340769:25538424]",
- ":FORWARD_direct - [0:0]",
- ":INPUT_direct - [0:0]",
- ":OUTPUT_direct - [0:0]",
- "-A INPUT -j INPUT_direct",
- "-A FORWARD -j FORWARD_direct",
- "-A OUTPUT -j OUTPUT_direct",
- "COMMIT",
- "# Completed on Mon Aug 19 11:25:48 2019",
- ]
- rules_str = six.b('\n'.join(rules))
-
- nova.privsep.linux_net.iptables_set_rules(rules)
- cmd = ['iptables-restore', '-c']
- mock_execute.assert_called_once_with(*cmd, process_input=rules_str,
- attempts=5)
-
- def test_iptables_set_rules_ipv6(self, mock_execute):
- rules = [
- "# Generated by ip6tables-save v1.8.2 on Mon Aug 19 12:00:29 2019",
- "*security",
- ":INPUT ACCEPT [56:10115]",
- ":FORWARD ACCEPT [0:0]",
- ":OUTPUT ACCEPT [147:15301]",
- ":FORWARD_direct - [0:0]",
- ":INPUT_direct - [0:0]",
- ":OUTPUT_direct - [0:0]",
- "-A INPUT -j INPUT_direct",
- "-A FORWARD -j FORWARD_direct",
- "-A OUTPUT -j OUTPUT_direct",
- "COMMIT",
- "# Completed on Mon Aug 19 12:00:29 2019",
- ]
- rules_str = six.b('\n'.join(rules))
-
- nova.privsep.linux_net.iptables_set_rules(rules, ipv4=False)
- cmd = ['ip6tables-restore', '-c']
- mock_execute.assert_called_once_with(*cmd, process_input=rules_str,
- attempts=5)
-
- def test_ovs_plug__fail(self, mock_execute):
- mock_execute.side_effect = processutils.ProcessExecutionError
-
- exc = self.assertRaises(exception.OVSConfigurationFailure,
- nova.privsep.linux_net.ovs_plug,
- 60, 'int-br', 'eth0', '00:14:22:01:23:45')
- self.assertIsInstance(exc.kwargs['inner_exception'],
- processutils.ProcessExecutionError)
-
- def test_ovs_unplug__fail(self, mock_execute):
- mock_execute.side_effect = processutils.ProcessExecutionError
-
- exc = self.assertRaises(exception.OVSConfigurationFailure,
- nova.privsep.linux_net.ovs_unplug,
- 60, 'int-br', 'eth0')
- self.assertIsInstance(exc.kwargs['inner_exception'],
- processutils.ProcessExecutionError)
diff --git a/nova/tests/unit/privsep/test_utils.py b/nova/tests/unit/privsep/test_utils.py
index f136572750..84d0767c29 100644
--- a/nova/tests/unit/privsep/test_utils.py
+++ b/nova/tests/unit/privsep/test_utils.py
@@ -18,7 +18,6 @@ import os
import nova.privsep.utils
from nova import test
-from nova.tests import fixtures
class SupportDirectIOTestCase(test.NoDBTestCase):
@@ -126,14 +125,3 @@ class SupportDirectIOTestCase(test.NoDBTestCase):
self.mock_write.assert_not_called()
self.mock_close.assert_not_called()
self.mock_unlink.assert_called_once_with(self.test_path)
-
-
-class UtilsTestCase(test.NoDBTestCase):
- def setUp(self):
- super(UtilsTestCase, self).setUp()
- self.useFixture(fixtures.PrivsepFixture())
-
- @mock.patch('os.kill')
- def test_kill(self, mock_kill):
- nova.privsep.utils.kill(42, -9)
- mock_kill.assert_called_with(42, -9)
diff --git a/nova/tests/unit/test_fixtures.py b/nova/tests/unit/test_fixtures.py
index 2711730907..3ca7066290 100644
--- a/nova/tests/unit/test_fixtures.py
+++ b/nova/tests/unit/test_fixtures.py
@@ -47,48 +47,6 @@ from nova import utils
CONF = cfg.CONF
-class TestConfFixture(testtools.TestCase):
- """Test the Conf fixtures in Nova.
-
- This is a basic test that this fixture works like we expect.
-
- Expectations:
-
- 1. before using the fixture, a default value (api_paste_config)
- comes through untouched.
-
- 2. before using the fixture, a known default value that we
- override is correct.
-
- 3. after using the fixture a known value that we override is the
- new value.
-
- 4. after using the fixture we can set a default value to something
- random, and it will be reset once we are done.
-
- There are 2 copies of this test so that you can verify they do the
- right thing with:
-
- tox -e py27 test_fixtures -- --concurrency=1
-
- As regardless of run order, their initial asserts would be
- impacted if the reset behavior isn't working correctly.
-
- """
- def _test_override(self):
- self.assertEqual('api-paste.ini', CONF.wsgi.api_paste_config)
- self.assertFalse(CONF.fake_network)
- self.useFixture(conf_fixture.ConfFixture())
- CONF.set_default('api_paste_config', 'foo', group='wsgi')
- self.assertTrue(CONF.fake_network)
-
- def test_override1(self):
- self._test_override()
-
- def test_override2(self):
- self._test_override()
-
-
class TestLogging(testtools.TestCase):
def test_default_logging(self):
stdlog = self.useFixture(fixtures.StandardLogging())
diff --git a/nova/tests/unit/test_iptables_network.py b/nova/tests/unit/test_iptables_network.py
deleted file mode 100644
index 45b0052a59..0000000000
--- a/nova/tests/unit/test_iptables_network.py
+++ /dev/null
@@ -1,276 +0,0 @@
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-"""Unit Tests for network code."""
-
-import mock
-import six
-
-from nova.network import linux_net
-from nova import test
-
-
-class IptablesManagerTestCase(test.NoDBTestCase):
-
- binary_name = linux_net.get_binary_name()
-
- sample_filter = ['#Generated by iptables-save on Fri Feb 18 15:17:05 2011',
- '*filter',
- ':INPUT ACCEPT [2223527:305688874]',
- ':FORWARD ACCEPT [0:0]',
- ':OUTPUT ACCEPT [2172501:140856656]',
- ':iptables-top-rule - [0:0]',
- ':iptables-bottom-rule - [0:0]',
- ':%s-FORWARD - [0:0]' % (binary_name),
- ':%s-INPUT - [0:0]' % (binary_name),
- ':%s-OUTPUT - [0:0]' % (binary_name),
- ':%s-local - [0:0]' % (binary_name),
- ':nova-filter-top - [0:0]',
- '[0:0] -A FORWARD -j nova-filter-top',
- '[0:0] -A OUTPUT -j nova-filter-top',
- '[0:0] -A nova-filter-top -j %s-local' % (binary_name),
- '[0:0] -A INPUT -j %s-INPUT' % (binary_name),
- '[0:0] -A OUTPUT -j %s-OUTPUT' % (binary_name),
- '[0:0] -A FORWARD -j %s-FORWARD' % (binary_name),
- '[0:0] -A INPUT -i virbr0 -p udp -m udp --dport 53 '
- '-j ACCEPT',
- '[0:0] -A INPUT -i virbr0 -p tcp -m tcp --dport 53 '
- '-j ACCEPT',
- '[0:0] -A INPUT -i virbr0 -p udp -m udp --dport 67 '
- '-j ACCEPT',
- '[0:0] -A INPUT -i virbr0 -p tcp -m tcp --dport 67 '
- '-j ACCEPT',
- '[0:0] -A FORWARD -s 192.168.122.0/24 -i virbr0 '
- '-j ACCEPT',
- '[0:0] -A FORWARD -i virbr0 -o virbr0 -j ACCEPT',
- '[0:0] -A FORWARD -o virbr0 -j REJECT --reject-with '
- 'icmp-port-unreachable',
- '[0:0] -A FORWARD -i virbr0 -j REJECT --reject-with '
- 'icmp-port-unreachable',
- 'COMMIT',
- '# Completed on Fri Feb 18 15:17:05 2011']
-
- sample_nat = ['# Generated by iptables-save on Fri Feb 18 15:17:05 2011',
- '*nat',
- ':PREROUTING ACCEPT [3936:762355]',
- ':INPUT ACCEPT [2447:225266]',
- ':OUTPUT ACCEPT [63491:4191863]',
- ':POSTROUTING ACCEPT [63112:4108641]',
- ':%s-OUTPUT - [0:0]' % (binary_name),
- ':%s-POSTROUTING - [0:0]' % (binary_name),
- ':%s-PREROUTING - [0:0]' % (binary_name),
- ':%s-float-snat - [0:0]' % (binary_name),
- ':%s-snat - [0:0]' % (binary_name),
- ':nova-postrouting-bottom - [0:0]',
- '[0:0] -A PREROUTING -j %s-PREROUTING' % (binary_name),
- '[0:0] -A OUTPUT -j %s-OUTPUT' % (binary_name),
- '[0:0] -A POSTROUTING -j %s-POSTROUTING' % (binary_name),
- '[0:0] -A nova-postrouting-bottom '
- '-j %s-snat' % (binary_name),
- '[0:0] -A %s-snat '
- '-j %s-float-snat' % (binary_name, binary_name),
- '[0:0] -A POSTROUTING -j nova-postrouting-bottom',
- 'COMMIT',
- '# Completed on Fri Feb 18 15:17:05 2011']
-
- def setUp(self):
- super(IptablesManagerTestCase, self).setUp()
- self.manager = linux_net.IptablesManager()
-
- def test_duplicate_rules_no_dirty(self):
- table = self.manager.ipv4['filter']
- table.dirty = False
- num_rules = len(table.rules)
- table.add_rule('FORWARD', '-s 1.2.3.4/5 -j DROP')
- self.assertEqual(len(table.rules), num_rules + 1)
- self.assertTrue(table.dirty)
- table.dirty = False
- num_rules = len(table.rules)
- table.add_rule('FORWARD', '-s 1.2.3.4/5 -j DROP')
- self.assertEqual(len(table.rules), num_rules)
- self.assertFalse(table.dirty)
-
- def test_clean_tables_no_apply(self):
- for table in six.itervalues(self.manager.ipv4):
- table.dirty = False
- for table in six.itervalues(self.manager.ipv6):
- table.dirty = False
-
- with mock.patch.object(self.manager, '_apply') as mock_apply:
- self.manager.apply()
- self.assertFalse(mock_apply.called)
-
- def test_filter_rules_are_wrapped(self):
- current_lines = self.sample_filter
-
- table = self.manager.ipv4['filter']
- table.add_rule('FORWARD', '-s 1.2.3.4/5 -j DROP')
- new_lines = self.manager._modify_rules(current_lines, table, 'filter')
- self.assertIn('[0:0] -A %s-FORWARD '
- '-s 1.2.3.4/5 -j DROP' % self.binary_name, new_lines)
-
- table.remove_rule('FORWARD', '-s 1.2.3.4/5 -j DROP')
- new_lines = self.manager._modify_rules(current_lines, table, 'filter')
- self.assertNotIn('[0:0] -A %s-FORWARD '
- '-s 1.2.3.4/5 -j DROP' % self.binary_name, new_lines)
-
- def test_remove_rules_regex(self):
- current_lines = self.sample_nat
- table = self.manager.ipv4['nat']
- table.add_rule('float-snat', '-s 10.0.0.1 -j SNAT --to 10.10.10.10'
- ' -d 10.0.0.1')
- table.add_rule('float-snat', '-s 10.0.0.1 -j SNAT --to 10.10.10.10'
- ' -o eth0')
- table.add_rule('PREROUTING', '-d 10.10.10.10 -j DNAT --to 10.0.0.1')
- table.add_rule('OUTPUT', '-d 10.10.10.10 -j DNAT --to 10.0.0.1')
- table.add_rule('float-snat', '-s 10.0.0.10 -j SNAT --to 10.10.10.11'
- ' -d 10.0.0.10')
- table.add_rule('float-snat', '-s 10.0.0.10 -j SNAT --to 10.10.10.11'
- ' -o eth0')
- table.add_rule('PREROUTING', '-d 10.10.10.11 -j DNAT --to 10.0.0.10')
- table.add_rule('OUTPUT', '-d 10.10.10.11 -j DNAT --to 10.0.0.10')
- new_lines = self.manager._modify_rules(current_lines, table, 'nat')
- self.assertEqual(len(new_lines) - len(current_lines), 8)
- regex = r'.*\s+%s(/32|\s+|$)'
- num_removed = table.remove_rules_regex(regex % '10.10.10.10')
- self.assertEqual(num_removed, 4)
- new_lines = self.manager._modify_rules(current_lines, table, 'nat')
- self.assertEqual(len(new_lines) - len(current_lines), 4)
- num_removed = table.remove_rules_regex(regex % '10.10.10.11')
- self.assertEqual(num_removed, 4)
- new_lines = self.manager._modify_rules(current_lines, table, 'nat')
- self.assertEqual(current_lines, new_lines)
-
- def test_nat_rules(self):
- current_lines = self.sample_nat
- new_lines = self.manager._modify_rules(current_lines,
- self.manager.ipv4['nat'],
- 'nat')
-
- for line in [':%s-OUTPUT - [0:0]' % (self.binary_name),
- ':%s-float-snat - [0:0]' % (self.binary_name),
- ':%s-snat - [0:0]' % (self.binary_name),
- ':%s-PREROUTING - [0:0]' % (self.binary_name),
- ':%s-POSTROUTING - [0:0]' % (self.binary_name)]:
- self.assertIn(line, new_lines, "One of our chains went"
- " missing.")
-
- seen_lines = set()
- for line in new_lines:
- line = line.strip()
- self.assertNotIn(line, seen_lines, "Duplicate line: %s" % line)
- seen_lines.add(line)
-
- last_postrouting_line = ''
-
- for line in new_lines:
- if line.startswith('[0:0] -A POSTROUTING'):
- last_postrouting_line = line
-
- self.assertIn('-j nova-postrouting-bottom', last_postrouting_line,
- "Last POSTROUTING rule does not jump to "
- "nova-postouting-bottom: %s" % last_postrouting_line)
-
- for chain in ['POSTROUTING', 'PREROUTING', 'OUTPUT']:
- self.assertTrue('[0:0] -A %s -j %s-%s' %
- (chain, self.binary_name, chain) in new_lines,
- "Built-in chain %s not wrapped" % (chain,))
-
- def test_filter_rules(self):
- current_lines = self.sample_filter
- new_lines = self.manager._modify_rules(current_lines,
- self.manager.ipv4['filter'],
- 'nat')
-
- for line in [':%s-FORWARD - [0:0]' % (self.binary_name),
- ':%s-INPUT - [0:0]' % (self.binary_name),
- ':%s-local - [0:0]' % (self.binary_name),
- ':%s-OUTPUT - [0:0]' % (self.binary_name)]:
- self.assertIn(line, new_lines, "One of our chains went"
- " missing.")
-
- seen_lines = set()
- for line in new_lines:
- line = line.strip()
- self.assertNotIn(line, seen_lines, "Duplicate line: %s" % line)
- seen_lines.add(line)
-
- for chain in ['FORWARD', 'OUTPUT']:
- for line in new_lines:
- if line.startswith('[0:0] -A %s' % chain):
- self.assertIn('-j nova-filter-top', line,
- "First %s rule does not "
- "jump to nova-filter-top" % chain)
- break
-
- self.assertTrue('[0:0] -A nova-filter-top '
- '-j %s-local' % self.binary_name in new_lines,
- "nova-filter-top does not jump to wrapped local chain")
-
- for chain in ['INPUT', 'OUTPUT', 'FORWARD']:
- self.assertTrue('[0:0] -A %s -j %s-%s' %
- (chain, self.binary_name, chain) in new_lines,
- "Built-in chain %s not wrapped" % (chain,))
-
- def test_missing_table(self):
- current_lines = []
- new_lines = self.manager._modify_rules(current_lines,
- self.manager.ipv4['filter'],
- 'filter')
-
- for line in ['*filter',
- 'COMMIT']:
- self.assertIn(line, new_lines, "One of iptables key lines "
- "went missing.")
-
- self.assertGreater(len(new_lines), 4, "No iptables rules added")
-
- msg = "iptables rules not generated in the correct order"
- self.assertEqual("#Generated by nova", new_lines[0], msg)
- self.assertEqual("*filter", new_lines[1], msg)
- self.assertEqual("COMMIT", new_lines[-2], msg)
- self.assertEqual("#Completed by nova", new_lines[-1], msg)
-
- def test_iptables_top_order(self):
- # Test iptables_top_regex
- current_lines = list(self.sample_filter)
- current_lines[12:12] = ['[0:0] -A FORWARD -j iptables-top-rule']
- self.flags(iptables_top_regex='-j iptables-top-rule')
- new_lines = self.manager._modify_rules(current_lines,
- self.manager.ipv4['filter'],
- 'filter')
- self.assertEqual(current_lines, new_lines)
-
- def test_iptables_bottom_order(self):
- # Test iptables_bottom_regex
- current_lines = list(self.sample_filter)
- current_lines[26:26] = ['[0:0] -A FORWARD -j iptables-bottom-rule']
- self.flags(iptables_bottom_regex='-j iptables-bottom-rule')
- new_lines = self.manager._modify_rules(current_lines,
- self.manager.ipv4['filter'],
- 'filter')
- self.assertEqual(current_lines, new_lines)
-
- def test_iptables_preserve_order(self):
- # Test both iptables_top_regex and iptables_bottom_regex
- current_lines = list(self.sample_filter)
- current_lines[12:12] = ['[0:0] -A FORWARD -j iptables-top-rule']
- current_lines[27:27] = ['[0:0] -A FORWARD -j iptables-bottom-rule']
- self.flags(iptables_top_regex='-j iptables-top-rule')
- self.flags(iptables_bottom_regex='-j iptables-bottom-rule')
- new_lines = self.manager._modify_rules(current_lines,
- self.manager.ipv4['filter'],
- 'filter')
- self.assertEqual(current_lines, new_lines)
diff --git a/nova/tests/unit/test_ipv6.py b/nova/tests/unit/test_ipv6.py
deleted file mode 100644
index 7314d128e7..0000000000
--- a/nova/tests/unit/test_ipv6.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (c) 2011 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Test suite for IPv6."""
-
-from nova import ipv6
-from nova import test
-
-
-class IPv6RFC2462TestCase(test.NoDBTestCase):
- """Unit tests for IPv6 rfc2462 backend operations."""
- def setUp(self):
- super(IPv6RFC2462TestCase, self).setUp()
- self.flags(ipv6_backend='rfc2462')
- ipv6.reset_backend()
-
- def test_to_global(self):
- addr = ipv6.to_global('2001:db8::', '02:16:3e:33:44:55', 'test')
- self.assertEqual(addr, '2001:db8::16:3eff:fe33:4455')
-
- def test_to_mac(self):
- mac = ipv6.to_mac('2001:db8::216:3eff:fe33:4455')
- self.assertEqual(mac, '00:16:3e:33:44:55')
-
- def test_to_global_with_bad_mac(self):
- bad_mac = '02:16:3e:33:44:5Z'
- expected_msg = 'Bad mac for to_global_ipv6: %s' % bad_mac
- err = self.assertRaises(TypeError, ipv6.to_global,
- '2001:db8::', bad_mac, 'test')
- self.assertEqual(expected_msg, str(err))
-
- def test_to_global_with_bad_prefix(self):
- bad_prefix = '2001::1::2'
- expected_msg = 'Bad prefix for to_global_ipv6: %s' % bad_prefix
- err = self.assertRaises(TypeError, ipv6.to_global,
- bad_prefix,
- '02:16:3e:33:44:55',
- 'test')
- self.assertEqual(expected_msg, str(err))
-
-
-class IPv6AccountIdentiferTestCase(test.NoDBTestCase):
- """Unit tests for IPv6 account_identifier backend operations."""
- def setUp(self):
- super(IPv6AccountIdentiferTestCase, self).setUp()
- self.flags(ipv6_backend='account_identifier')
- ipv6.reset_backend()
-
- def test_to_global(self):
- addr = ipv6.to_global('2001:db8::', '02:16:3e:33:44:55', 'test')
- self.assertEqual(addr, '2001:db8::a94a:8fe5:ff33:4455')
-
- def test_to_mac(self):
- mac = ipv6.to_mac('2001:db8::a94a:8fe5:ff33:4455')
- self.assertEqual(mac, '02:16:3e:33:44:55')
-
- def test_to_global_with_bad_mac(self):
- bad_mac = '02:16:3e:33:44:5Z'
- expected_msg = 'Bad mac for to_global_ipv6: %s' % bad_mac
- err = self.assertRaises(TypeError, ipv6.to_global,
- '2001:db8::', bad_mac, 'test')
- self.assertEqual(expected_msg, str(err))
-
- def test_to_global_with_bad_prefix(self):
- bad_prefix = '2001::1::2'
- expected_msg = 'Bad prefix for to_global_ipv6: %s' % bad_prefix
- err = self.assertRaises(TypeError, ipv6.to_global,
- bad_prefix,
- '02:16:3e:33:44:55',
- 'test')
- self.assertEqual(expected_msg, str(err))
diff --git a/nova/tests/unit/test_profiler.py b/nova/tests/unit/test_profiler.py
index 7b5e64dad6..4cffd53345 100644
--- a/nova/tests/unit/test_profiler.py
+++ b/nova/tests/unit/test_profiler.py
@@ -55,12 +55,7 @@ class TestProfiler(test.NoDBTestCase):
'nova.conductor.rpcapi.ComputeTaskAPI',
'nova.conductor.rpcapi.ConductorAPI',
'nova.image.api.API',
- 'nova.network.api.API',
- 'nova.network.manager.FlatDHCPManager',
- 'nova.network.manager.FlatManager',
- 'nova.network.manager.VlanManager',
'nova.network.neutronv2.api.ClientWrapper',
- 'nova.network.rpcapi.NetworkAPI',
'nova.scheduler.manager.SchedulerManager',
'nova.scheduler.rpcapi.SchedulerAPI',
'nova.virt.libvirt.vif.LibvirtGenericVIFDriver',
diff --git a/nova/tests/unit/utils.py b/nova/tests/unit/utils.py
index d3752ffe8d..eb306c2ea4 100644
--- a/nova/tests/unit/utils.py
+++ b/nova/tests/unit/utils.py
@@ -27,7 +27,6 @@ import nova.context
from nova.db import api as db
from nova import exception
from nova.image import glance
-from nova.network import minidns
from nova.network import model as network_model
from nova import objects
from nova.objects import base as obj_base
@@ -135,8 +134,6 @@ FAKE_VIF_MAC = 'de:ad:be:ef:ca:fe'
def get_test_network_info(count=1):
- ipv6 = CONF.use_ipv6
-
def current():
subnet_4 = network_model.Subnet(
cidr=FAKE_NETWORK_IP4_CIDR,
@@ -155,9 +152,7 @@ def get_test_network_info(count=1):
network_model.IP(FAKE_NETWORK_IP6_ADDR3)],
routes=None,
version=6)
- subnets = [subnet_4]
- if ipv6:
- subnets.append(subnet_6)
+ subnets = [subnet_4, subnet_6]
network = network_model.Network(
id=FAKE_NETWORK_UUID,
bridge=FAKE_NETWORK_BRIDGE,
@@ -187,23 +182,6 @@ def is_linux():
return platform.system() == 'Linux'
-test_dns_managers = []
-
-
-def dns_manager():
- global test_dns_managers
- manager = minidns.MiniDNS()
- test_dns_managers.append(manager)
- return manager
-
-
-def cleanup_dns_managers():
- global test_dns_managers
- for manager in test_dns_managers:
- manager.delete_dns_file()
- test_dns_managers = []
-
-
def killer_xml_body():
return (("""<!DOCTYPE x [
<!ENTITY a "%(a)s">
diff --git a/nova/utils.py b/nova/utils.py
index 72665fe891..914d5516ff 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -53,7 +53,6 @@ from six.moves import range
import nova.conf
from nova import exception
from nova.i18n import _, _LE, _LW
-import nova.network
from nova import safe_utils
profiler = importutils.try_import('osprofiler.profiler')
@@ -63,8 +62,6 @@ CONF = nova.conf.CONF
LOG = logging.getLogger(__name__)
-_IS_NEUTRON = None
-
synchronized = lockutils.synchronized_with_prefix('nova-')
SM_IMAGE_PROP_PREFIX = "image_"
@@ -709,16 +706,6 @@ def is_none_string(val):
return val.lower() == 'none'
-def is_neutron():
- global _IS_NEUTRON
-
- if _IS_NEUTRON is not None:
- return _IS_NEUTRON
-
- _IS_NEUTRON = nova.network.is_neutron()
- return _IS_NEUTRON
-
-
def is_auto_disk_config_disabled(auto_disk_config_raw):
auto_disk_config_disabled = False
if auto_disk_config_raw is not None:
diff --git a/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml b/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml
index 843cebd2f1..bdf9bf0d3e 100644
--- a/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml
+++ b/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml
@@ -61,4 +61,76 @@ upgrade:
* ``[DEFAULT] firewall_driver``
* ``[DEFAULT] allow_same_net_traffic``
+ * ``[DEFAULT] flat_network_bridge``
+ * ``[DEFAULT] flat_network_dns``
+ * ``[DEFAULT] flat_interface``
+ * ``[DEFAULT] vlan_interface``
+ * ``[DEFAULT] vlan_start``
+ * ``[DEFAULT] num_networks``
+ * ``[DEFAULT] vpn_ip``
+ * ``[DEFAULT] vpn_start``
+ * ``[DEFAULT] network_size``
+ * ``[DEFAULT] fixed_range_v6``
+ * ``[DEFAULT] gateway``
+ * ``[DEFAULT] gateway_v6``
+ * ``[DEFAULT] cnt_vpn_clients``
+ * ``[DEFAULT] fixed_ip_disassociate_timeout``
+ * ``[DEFAULT] create_unique_mac_address_attempts``
+ * ``[DEFAULT] teardown_unused_network_gateway``
+ * ``[DEFAULT] l3_lib``
+ * ``[DEFAULT] network_driver``
+ * ``[DEFAULT] network_manager``
+ * ``[DEFAULT] multi_host``
+ * ``[DEFAULT] force_dhcp_release``
+ * ``[DEFAULT] update_dns_entries``
+ * ``[DEFAULT] dns_update_periodic_interval``
+ * ``[DEFAULT] dhcp_domain``
+ * ``[DEFAULT] use_neutron``
+ * ``[DEFAULT] auto_assign_floating_ip``
+ * ``[DEFAULT] floating_ip_dns_manager``
+ * ``[DEFAULT] instance_dns_manager``
+ * ``[DEFAULT] instance_dns_domain``
+ * ``[DEFAULT] default_floating_pool``
+ * ``[DEFAULT] ipv6_backend``
+ * ``[DEFAULT] metadata_host``
+ * ``[DEFAULT] metadata_port``
+ * ``[DEFAULT] iptables_top_regex``
+ * ``[DEFAULT] iptables_bottom_regex``
+ * ``[DEFAULT] iptables_drop_action``
+ * ``[DEFAULT] ldap_dns_url``
+ * ``[DEFAULT] ldap_dns_user``
+ * ``[DEFAULT] ldap_dns_password``
+ * ``[DEFAULT] ldap_dns_soa_hostmaster``
+ * ``[DEFAULT] ldap_dns_servers``
+ * ``[DEFAULT] ldap_dns_base_dn``
+ * ``[DEFAULT] ldap_dns_soa_refresh``
+ * ``[DEFAULT] ldap_dns_soa_retry``
+ * ``[DEFAULT] ldap_dns_soa_expiry``
+ * ``[DEFAULT] ldap_dns_soa_minimum``
+ * ``[DEFAULT] dhcpbridge_flagfile``
+ * ``[DEFAULT] dhcpbridge``
+ * ``[DEFAULT] dhcp_lease_time``
+ * ``[DEFAULT] dns_server``
+ * ``[DEFAULT] use_network_dns_servers``
+ * ``[DEFAULT] dnsmasq_config_file``
+ * ``[DEFAULT] ebtables_exec_attempts``
+ * ``[DEFAULT] ebtables_retry_interval``
+ * ``[DEFAULT] fake_network``
+ * ``[DEFAULT] send_arp_for_ha``
+ * ``[DEFAULT] send_arp_for_ha_count``
+ * ``[DEFAULT] dmz_cidr``
+ * ``[DEFAULT] force_snat_range``
+ * ``[DEFAULT] linuxnet_interface_driver``
+ * ``[DEFAULT] linuxnet_ovs_integration_bridge``
+ * ``[DEFAULT] use_single_default_gateway``
+ * ``[DEFAULT] forward_bridge_interface``
+ * ``[DEFAULT] ovs_vsctl_timeout``
+ * ``[DEFAULT] networks_path``
+ * ``[DEFAULT] public_interface``
+ * ``[DEFAULT] routing_source_ip``
+ * ``[DEFAULT] use_ipv6``
+ * ``[DEFAULT] allow_same_net_traffic``
+ * ``[DEFAULT] defer_iptables_apply``
+ * ``[DEFAULT] share_dhcp_address``
+ * ``[upgrade_levels] network``
* ``[vmware] vlan_interface``
diff --git a/setup.cfg b/setup.cfg
index afc8b5d1d8..b9b8f8eeea 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -36,31 +36,21 @@ packages =
[entry_points]
oslo.config.opts =
nova.conf = nova.conf.opts:list_opts
-
oslo.config.opts.defaults =
nova.conf = nova.middleware:set_defaults
-
oslo.policy.enforcer =
nova = nova.policy:get_enforcer
-
oslo.policy.policies =
# The sample policies will be ordered by entry point and then by list
# returned from that entry point. If more control is desired split out each
# list_rules method into a separate entry point rather than using the
# aggregate method.
nova = nova.policies:list_rules
-
nova.compute.monitors.cpu =
virt_driver = nova.compute.monitors.cpu.virt_driver:Monitor
-
-nova.ipv6_backend =
- rfc2462 = nova.ipv6.rfc2462
- account_identifier = nova.ipv6.account_identifier
-
nova.scheduler.driver =
filter_scheduler = nova.scheduler.filter_scheduler:FilterScheduler
fake_scheduler = nova.tests.unit.scheduler.fakes:FakeScheduler
-
console_scripts =
nova-api = nova.cmd.api:main
nova-api-metadata = nova.cmd.api_metadata:main
@@ -76,7 +66,6 @@ console_scripts =
nova-serialproxy = nova.cmd.serialproxy:main
nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main
nova-status = nova.cmd.status:main
-
wsgi_scripts =
nova-api-wsgi = nova.api.openstack.compute.wsgi:init_application
nova-metadata-wsgi = nova.api.metadata.wsgi:init_application
diff --git a/test-requirements.txt b/test-requirements.txt
index aae938f1c2..44df4e47a9 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -7,7 +7,6 @@ coverage!=4.4,>=4.0 # Apache-2.0
ddt>=1.0.1 # MIT
fixtures>=3.0.0 # Apache-2.0/BSD
mock>=3.0.0 # BSD
-mox3>=0.20.0 # Apache-2.0
psycopg2>=2.7 # LGPL/ZPL
PyMySQL>=0.7.6 # MIT License
pycodestyle>=2.0.0 # MIT License