Add support for specific network configuration
The networkconfig plugin can now handle custom NetworkDetails objects that contain data like IP address, gateway, broadcast etc. Change-Id: Ife3f8f62b47704e7f25e0304b15953d6f06e8620
This commit is contained in:
parent
c1a3f38e80
commit
8befa6c833
@ -1,5 +1,3 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 Cloudbase Solutions Srl
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -14,13 +12,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import abc
|
||||
import collections
|
||||
import time
|
||||
import warnings
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from cloudbaseinit.openstack.common import log as logging
|
||||
|
||||
|
||||
opts = [
|
||||
cfg.IntOpt('retry_count', default=5,
|
||||
help='Max. number of attempts for fetching metadata in '
|
||||
@ -35,6 +37,20 @@ CONF.register_opts(opts)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# Both the custom service(s) and the networking plugin
|
||||
# should know about the entries of these kind of objects.
|
||||
NetworkDetails = collections.namedtuple(
|
||||
"NetworkDetails",
|
||||
[
|
||||
"mac",
|
||||
"address",
|
||||
"netmask",
|
||||
"broadcast",
|
||||
"gateway",
|
||||
"dnsnameservers",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class NotExistingMetadataException(Exception):
|
||||
pass
|
||||
@ -82,6 +98,7 @@ class BaseMetadataService(object):
|
||||
pass
|
||||
|
||||
def get_content(self, name):
|
||||
# this will also be deprecated due to `get_network_config`
|
||||
pass
|
||||
|
||||
def get_user_data(self):
|
||||
@ -94,7 +111,17 @@ class BaseMetadataService(object):
|
||||
pass
|
||||
|
||||
def get_network_config(self):
|
||||
pass
|
||||
"""Deprecated, use `get_network_details` instead."""
|
||||
warnings.warn("deprecated method, use `get_network_details`",
|
||||
DeprecationWarning)
|
||||
|
||||
def get_network_details(self):
|
||||
"""Return a list of `NetworkDetails` objects.
|
||||
|
||||
These objects provide details regarding static
|
||||
network configuration, details which can be found
|
||||
in the namedtuple defined above.
|
||||
"""
|
||||
|
||||
def get_admin_password(self):
|
||||
pass
|
||||
|
@ -70,7 +70,7 @@ class BaseOSUtils(object):
|
||||
def get_network_adapters(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def set_static_network_config(self, adapter_name, address, netmask,
|
||||
def set_static_network_config(self, mac_address, address, netmask,
|
||||
broadcast, gateway, dnsnameservers):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 Cloudbase Solutions Srl
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -15,33 +13,33 @@
|
||||
# under the License.
|
||||
|
||||
import ctypes
|
||||
from ctypes import wintypes
|
||||
import os
|
||||
import re
|
||||
import six
|
||||
import time
|
||||
|
||||
import six
|
||||
from six.moves import winreg
|
||||
from win32com import client
|
||||
import win32process
|
||||
import win32security
|
||||
import wmi
|
||||
|
||||
from ctypes import windll
|
||||
from ctypes import wintypes
|
||||
from six.moves import winreg
|
||||
from win32com import client
|
||||
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.openstack.common import log as logging
|
||||
from cloudbaseinit.osutils import base
|
||||
from cloudbaseinit.utils.windows import network
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
advapi32 = windll.advapi32
|
||||
kernel32 = windll.kernel32
|
||||
netapi32 = windll.netapi32
|
||||
userenv = windll.userenv
|
||||
iphlpapi = windll.iphlpapi
|
||||
Ws2_32 = windll.Ws2_32
|
||||
setupapi = windll.setupapi
|
||||
advapi32 = ctypes.windll.advapi32
|
||||
kernel32 = ctypes.windll.kernel32
|
||||
netapi32 = ctypes.windll.netapi32
|
||||
userenv = ctypes.windll.userenv
|
||||
iphlpapi = ctypes.windll.iphlpapi
|
||||
Ws2_32 = ctypes.windll.Ws2_32
|
||||
setupapi = ctypes.windll.setupapi
|
||||
msvcrt = ctypes.cdll.msvcrt
|
||||
|
||||
|
||||
@ -454,7 +452,7 @@ class WindowsUtils(base.BaseOSUtils):
|
||||
raise exception.CloudbaseInitException("Cannot set host name")
|
||||
|
||||
def get_network_adapters(self):
|
||||
l = []
|
||||
"""Return available adapters as a list of tuples of (name, mac)."""
|
||||
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||
# Get Ethernet adapters only
|
||||
wql = ('SELECT * FROM Win32_NetworkAdapter WHERE '
|
||||
@ -464,9 +462,7 @@ class WindowsUtils(base.BaseOSUtils):
|
||||
wql += ' AND PhysicalAdapter = True'
|
||||
|
||||
q = conn.query(wql)
|
||||
for r in q:
|
||||
l.append(r.Name)
|
||||
return l
|
||||
return [(r.Name, r.MACAddress) for r in q]
|
||||
|
||||
def get_dhcp_hosts_in_use(self):
|
||||
dhcp_hosts = []
|
||||
@ -524,14 +520,12 @@ class WindowsUtils(base.BaseOSUtils):
|
||||
'value "%(mtu)s" failed' % {'mac_address': mac_address,
|
||||
'mtu': mtu})
|
||||
|
||||
def set_static_network_config(self, adapter_name, address, netmask,
|
||||
def set_static_network_config(self, mac_address, address, netmask,
|
||||
broadcast, gateway, dnsnameservers):
|
||||
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||
|
||||
adapter_name_san = self._sanitize_wmi_input(adapter_name)
|
||||
q = conn.query('SELECT * FROM Win32_NetworkAdapter WHERE '
|
||||
'MACAddress IS NOT NULL AND '
|
||||
'Name = \'%s\'' % adapter_name_san)
|
||||
q = conn.query("SELECT * FROM Win32_NetworkAdapter WHERE "
|
||||
"MACAddress = '{}'".format(mac_address))
|
||||
if not len(q):
|
||||
raise exception.CloudbaseInitException(
|
||||
"Network adapter not found")
|
||||
|
@ -1,5 +1,3 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012 Cloudbase Solutions Srl
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -14,75 +12,132 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import re
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.metadata.services import base as service_base
|
||||
from cloudbaseinit.openstack.common import log as logging
|
||||
from cloudbaseinit.osutils import factory as osutils_factory
|
||||
from cloudbaseinit.plugins import base
|
||||
from cloudbaseinit.plugins import base as plugin_base
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('network_adapter', default=None, help='Network adapter to '
|
||||
'configure. If not specified, the first available ethernet '
|
||||
'adapter will be chosen'),
|
||||
'adapter will be chosen.\n'
|
||||
'WARNING: This option is deprecated and will be removed soon.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(opts)
|
||||
|
||||
|
||||
class NetworkConfigPlugin(base.BasePlugin):
|
||||
class NetworkConfigPlugin(plugin_base.BasePlugin):
|
||||
|
||||
def execute(self, service, shared_data):
|
||||
network_config = service.get_network_config()
|
||||
if not network_config:
|
||||
return (base.PLUGIN_EXECUTION_DONE, False)
|
||||
|
||||
if 'content_path' not in network_config:
|
||||
return (base.PLUGIN_EXECUTION_DONE, False)
|
||||
|
||||
content_path = network_config['content_path']
|
||||
content_name = content_path.rsplit('/', 1)[-1]
|
||||
debian_network_conf = service.get_content(content_name)
|
||||
|
||||
LOG.debug('network config content:\n%s' % debian_network_conf)
|
||||
|
||||
# TODO(alexpilotti): implement a proper grammar
|
||||
m = re.search(r'iface eth0 inet static\s+'
|
||||
r'address\s+(?P<address>[^\s]+)\s+'
|
||||
r'netmask\s+(?P<netmask>[^\s]+)\s+'
|
||||
r'broadcast\s+(?P<broadcast>[^\s]+)\s+'
|
||||
r'gateway\s+(?P<gateway>[^\s]+)\s+'
|
||||
r'dns\-nameservers\s+(?P<dnsnameservers>[^\r\n]+)\s+',
|
||||
debian_network_conf)
|
||||
if not m:
|
||||
raise exception.CloudbaseInitException(
|
||||
"network_config format not recognized")
|
||||
|
||||
address = m.group('address')
|
||||
netmask = m.group('netmask')
|
||||
broadcast = m.group('broadcast')
|
||||
gateway = m.group('gateway')
|
||||
dnsnameservers = m.group('dnsnameservers').strip().split(' ')
|
||||
# FIXME(cpoieana): `network_config` is deprecated
|
||||
# * refactor all services by providing NetworkDetails objects *
|
||||
# Also, the old method is not supporting multiple NICs.
|
||||
|
||||
osutils = osutils_factory.get_os_utils()
|
||||
network_details = service.get_network_details()
|
||||
if not network_details:
|
||||
network_config = service.get_network_config()
|
||||
if not network_config:
|
||||
return (plugin_base.PLUGIN_EXECUTION_DONE, False)
|
||||
|
||||
network_adapter_name = CONF.network_adapter
|
||||
if not network_adapter_name:
|
||||
# Get the first available one
|
||||
available_adapters = osutils.get_network_adapters()
|
||||
if not len(available_adapters):
|
||||
# ---- BEGIN deprecated code ----
|
||||
if not network_details:
|
||||
if 'content_path' not in network_config:
|
||||
return (plugin_base.PLUGIN_EXECUTION_DONE, False)
|
||||
|
||||
content_path = network_config['content_path']
|
||||
content_name = content_path.rsplit('/', 1)[-1]
|
||||
debian_network_conf = service.get_content(content_name)
|
||||
|
||||
LOG.debug('network config content:\n%s' % debian_network_conf)
|
||||
|
||||
# TODO(alexpilotti): implement a proper grammar
|
||||
m = re.search(r'iface eth0 inet static\s+'
|
||||
r'address\s+(?P<address>[^\s]+)\s+'
|
||||
r'netmask\s+(?P<netmask>[^\s]+)\s+'
|
||||
r'broadcast\s+(?P<broadcast>[^\s]+)\s+'
|
||||
r'gateway\s+(?P<gateway>[^\s]+)\s+'
|
||||
r'dns\-nameservers\s+'
|
||||
r'(?P<dnsnameservers>[^\r\n]+)\s+',
|
||||
debian_network_conf)
|
||||
if not m:
|
||||
raise exception.CloudbaseInitException(
|
||||
"No network adapter available")
|
||||
network_adapter_name = available_adapters[0]
|
||||
"network_config format not recognized")
|
||||
|
||||
LOG.info('Configuring network adapter: \'%s\'' % network_adapter_name)
|
||||
mac = None
|
||||
network_adapters = osutils.get_network_adapters()
|
||||
if network_adapters:
|
||||
adapter_name = CONF.network_adapter
|
||||
if adapter_name:
|
||||
# configure with the specified one
|
||||
for network_adapter in network_adapters:
|
||||
if network_adapter[0] == adapter_name:
|
||||
mac = network_adapter[1]
|
||||
break
|
||||
else:
|
||||
# configure with the first one
|
||||
mac = network_adapters[0][1]
|
||||
network_details = [
|
||||
service_base.NetworkDetails(
|
||||
mac,
|
||||
m.group('address'),
|
||||
m.group('netmask'),
|
||||
m.group('broadcast'),
|
||||
m.group('gateway'),
|
||||
m.group('dnsnameservers').strip().split(' ')
|
||||
)
|
||||
]
|
||||
# ---- END deprecated code ----
|
||||
|
||||
reboot_required = osutils.set_static_network_config(
|
||||
network_adapter_name, address, netmask, broadcast,
|
||||
gateway, dnsnameservers)
|
||||
# check NICs' type and save them by MAC
|
||||
macnics = {}
|
||||
for nic in network_details:
|
||||
if not isinstance(nic, service_base.NetworkDetails):
|
||||
raise exception.CloudbaseInitException(
|
||||
"invalid NetworkDetails object {!r}"
|
||||
.format(type(nic))
|
||||
)
|
||||
# assuming that the MAC address is unique
|
||||
macnics[nic.mac] = nic
|
||||
# try configuring all the available adapters
|
||||
adapter_macs = [pair[1] for pair in
|
||||
osutils.get_network_adapters()]
|
||||
if not adapter_macs:
|
||||
raise exception.CloudbaseInitException(
|
||||
"no network adapters available")
|
||||
# configure each one
|
||||
reboot_required = False
|
||||
configured = False
|
||||
for mac in adapter_macs:
|
||||
nic = macnics.pop(mac, None)
|
||||
if not nic:
|
||||
LOG.warn("Missing details for adapter %s", mac)
|
||||
continue
|
||||
LOG.info("Configuring network adapter %s", mac)
|
||||
reboot = osutils.set_static_network_config(
|
||||
mac,
|
||||
nic.address,
|
||||
nic.netmask,
|
||||
nic.broadcast,
|
||||
nic.gateway,
|
||||
nic.dnsnameservers
|
||||
)
|
||||
reboot_required = reboot or reboot_required
|
||||
configured = True
|
||||
for mac in macnics:
|
||||
LOG.warn("Details not used for adapter %s", mac)
|
||||
if not configured:
|
||||
LOG.error("No adapters were configured")
|
||||
|
||||
return (base.PLUGIN_EXECUTION_DONE, reboot_required)
|
||||
return (plugin_base.PLUGIN_EXECUTION_DONE, reboot_required)
|
||||
|
@ -1,5 +1,3 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 Cloudbase Solutions Srl
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -14,16 +12,18 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import importlib
|
||||
import mock
|
||||
import os
|
||||
import six
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
|
||||
from cloudbaseinit import exception
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
@ -517,7 +517,8 @@ class WindowsUtilsTest(unittest.TestCase):
|
||||
|
||||
response = self._winutils.get_network_adapters()
|
||||
conn.return_value.query.assert_called_with(wql)
|
||||
self.assertEqual([mock_response.Name], response)
|
||||
self.assertEqual([(mock_response.Name, mock_response.MACAddress)],
|
||||
response)
|
||||
|
||||
def test_get_network_adapters(self):
|
||||
self._test_get_network_adapters(False)
|
||||
@ -532,7 +533,7 @@ class WindowsUtilsTest(unittest.TestCase):
|
||||
ret_val2=None, ret_val3=None):
|
||||
conn = self._wmi_mock.WMI
|
||||
address = '10.10.10.10'
|
||||
adapter_name = 'adapter_name'
|
||||
mac_address = '54:EE:75:19:F4:61'
|
||||
broadcast = '0.0.0.0'
|
||||
dns_list = ['8.8.8.8']
|
||||
|
||||
@ -540,10 +541,9 @@ class WindowsUtilsTest(unittest.TestCase):
|
||||
self.assertRaises(
|
||||
exception.CloudbaseInitException,
|
||||
self._winutils.set_static_network_config,
|
||||
adapter_name, address, self._NETMASK,
|
||||
mac_address, address, self._NETMASK,
|
||||
broadcast, self._GATEWAY, dns_list)
|
||||
else:
|
||||
mock_sanitize_wmi_input.return_value = adapter_name
|
||||
conn.return_value.query.return_value = adapter
|
||||
adapter_config = adapter[0].associators()[0]
|
||||
adapter_config.EnableStatic.return_value = ret_val1
|
||||
@ -555,26 +555,26 @@ class WindowsUtilsTest(unittest.TestCase):
|
||||
self.assertRaises(
|
||||
exception.CloudbaseInitException,
|
||||
self._winutils.set_static_network_config,
|
||||
adapter_name, address, self._NETMASK,
|
||||
mac_address, address, self._NETMASK,
|
||||
broadcast, self._GATEWAY, dns_list)
|
||||
|
||||
elif ret_val2[0] > 1:
|
||||
self.assertRaises(
|
||||
exception.CloudbaseInitException,
|
||||
self._winutils.set_static_network_config,
|
||||
adapter_name, address, self._NETMASK,
|
||||
mac_address, address, self._NETMASK,
|
||||
broadcast, self._GATEWAY, dns_list)
|
||||
|
||||
elif ret_val3[0] > 1:
|
||||
self.assertRaises(
|
||||
exception.CloudbaseInitException,
|
||||
self._winutils.set_static_network_config,
|
||||
adapter_name, address, self._NETMASK,
|
||||
mac_address, address, self._NETMASK,
|
||||
broadcast, self._GATEWAY, dns_list)
|
||||
|
||||
else:
|
||||
response = self._winutils.set_static_network_config(
|
||||
adapter_name, address, self._NETMASK,
|
||||
mac_address, address, self._NETMASK,
|
||||
broadcast, self._GATEWAY, dns_list)
|
||||
|
||||
if ret_val1[0] or ret_val2[0] or ret_val3[0] == 1:
|
||||
@ -588,14 +588,12 @@ class WindowsUtilsTest(unittest.TestCase):
|
||||
adapter_config.SetDNSServerSearchOrder.assert_called_with(
|
||||
dns_list)
|
||||
|
||||
self._winutils._sanitize_wmi_input.assert_called_with(
|
||||
adapter_name)
|
||||
adapter[0].associators.assert_called_with(
|
||||
wmi_result_class='Win32_NetworkAdapterConfiguration')
|
||||
conn.return_value.query.assert_called_with(
|
||||
'SELECT * FROM Win32_NetworkAdapter WHERE MACAddress IS '
|
||||
'NOT NULL AND Name = \'%(adapter_name_san)s\'' %
|
||||
{'adapter_name_san': adapter_name})
|
||||
"SELECT * FROM Win32_NetworkAdapter WHERE "
|
||||
"MACAddress = '{}'".format(mac_address)
|
||||
)
|
||||
|
||||
def test_set_static_network_config(self):
|
||||
adapter = mock.MagicMock()
|
||||
|
@ -1,5 +1,3 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 Cloudbase Solutions Srl
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -14,21 +12,24 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
|
||||
import re
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
from oslo.config import cfg
|
||||
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.plugins import base
|
||||
from cloudbaseinit.metadata.services import base as service_base
|
||||
from cloudbaseinit.plugins import base as plugin_base
|
||||
from cloudbaseinit.plugins.windows import networkconfig
|
||||
from cloudbaseinit.tests.metadata import fake_json_response
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class NetworkConfigPluginPluginTests(unittest.TestCase):
|
||||
class TestNetworkConfigPlugin(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self._network_plugin = networkconfig.NetworkConfigPlugin()
|
||||
@ -36,50 +37,139 @@ class NetworkConfigPluginPluginTests(unittest.TestCase):
|
||||
'2013-04-04')
|
||||
|
||||
@mock.patch('cloudbaseinit.osutils.factory.get_os_utils')
|
||||
def _test_execute(self, mock_get_os_utils, search_result, no_adapters):
|
||||
CONF.set_override('network_adapter', 'fake adapter')
|
||||
def _test_execute(self, mock_get_os_utils,
|
||||
search_result=mock.MagicMock(),
|
||||
no_adapter_name=False, no_adapters=False,
|
||||
using_content=0, details_list=None,
|
||||
missing_content_path=False):
|
||||
fake_adapter = ("fake_name_0", "fake_mac_0")
|
||||
mock_service = mock.MagicMock()
|
||||
mock_osutils = mock.MagicMock()
|
||||
mock_ndetails = mock.Mock()
|
||||
re.search = mock.MagicMock(return_value=search_result)
|
||||
fake_shared_data = 'fake shared data'
|
||||
network_config = self.fake_data['network_config']
|
||||
mock_service.get_network_config.return_value = network_config
|
||||
mock_service.get_content.return_value = search_result
|
||||
if not details_list:
|
||||
details_list = [None] * 6
|
||||
details_list[0] = fake_adapter[1] # set MAC for matching
|
||||
if no_adapter_name: # nothing provided in the config file
|
||||
CONF.set_override("network_adapter", None)
|
||||
else:
|
||||
CONF.set_override("network_adapter", fake_adapter[0])
|
||||
mock_osutils.get_network_adapters.return_value = [
|
||||
fake_adapter,
|
||||
# and other adapters
|
||||
("name1", "mac1"),
|
||||
("name2", "mac2")
|
||||
]
|
||||
mock_get_os_utils.return_value = mock_osutils
|
||||
mock_osutils.set_static_network_config.return_value = False
|
||||
if search_result is None:
|
||||
# service method setup
|
||||
methods = ["get_network_config", "get_content", "get_network_details"]
|
||||
for method in methods:
|
||||
mock_method = getattr(mock_service, method)
|
||||
mock_method.return_value = None
|
||||
if using_content == 1:
|
||||
mock_service.get_network_config.return_value = network_config
|
||||
mock_service.get_content.return_value = search_result
|
||||
|
||||
elif using_content == 2:
|
||||
mock_service.get_network_details.return_value = [mock_ndetails]
|
||||
# actual tests
|
||||
if search_result is None and using_content == 1:
|
||||
self.assertRaises(exception.CloudbaseInitException,
|
||||
self._network_plugin.execute,
|
||||
mock_service, fake_shared_data)
|
||||
elif no_adapters:
|
||||
CONF.set_override('network_adapter', None)
|
||||
return
|
||||
if no_adapters:
|
||||
mock_osutils.get_network_adapters.return_value = []
|
||||
self.assertRaises(exception.CloudbaseInitException,
|
||||
self._network_plugin.execute,
|
||||
mock_service, fake_shared_data)
|
||||
|
||||
else:
|
||||
return
|
||||
attrs = [
|
||||
"address",
|
||||
"netmask",
|
||||
"broadcast",
|
||||
"gateway",
|
||||
"dnsnameservers",
|
||||
]
|
||||
if using_content == 0:
|
||||
response = self._network_plugin.execute(mock_service,
|
||||
fake_shared_data)
|
||||
|
||||
mock_service.get_network_config.assert_called_once_with()
|
||||
mock_service.get_content.assert_called_once_with(
|
||||
network_config['content_path'])
|
||||
elif using_content == 1:
|
||||
if missing_content_path:
|
||||
mock_service.get_network_config.return_value.pop(
|
||||
"content_path", None
|
||||
)
|
||||
response = self._network_plugin.execute(mock_service,
|
||||
fake_shared_data)
|
||||
if not missing_content_path:
|
||||
mock_service.get_network_config.assert_called_once_with()
|
||||
mock_service.get_content.assert_called_once_with(
|
||||
network_config['content_path'])
|
||||
adapters = mock_osutils.get_network_adapters()
|
||||
if CONF.network_adapter:
|
||||
mac = [pair[1] for pair in adapters
|
||||
if pair == fake_adapter][0]
|
||||
else:
|
||||
mac = adapters[0][1]
|
||||
(
|
||||
address,
|
||||
netmask,
|
||||
broadcast,
|
||||
gateway,
|
||||
dnsnameserver
|
||||
) = map(search_result.group, attrs)
|
||||
dnsnameservers = dnsnameserver.strip().split(" ")
|
||||
elif using_content == 2:
|
||||
with self.assertRaises(exception.CloudbaseInitException):
|
||||
self._network_plugin.execute(mock_service,
|
||||
fake_shared_data)
|
||||
mock_service.get_network_details.reset_mock()
|
||||
mock_ndetails = service_base.NetworkDetails(*details_list)
|
||||
mock_service.get_network_details.return_value = [mock_ndetails]
|
||||
response = self._network_plugin.execute(mock_service,
|
||||
fake_shared_data)
|
||||
mock_service.get_network_details.assert_called_once_with()
|
||||
mac = mock_ndetails.mac
|
||||
(
|
||||
address,
|
||||
netmask,
|
||||
broadcast,
|
||||
gateway,
|
||||
dnsnameservers
|
||||
) = map(lambda attr: getattr(mock_ndetails, attr), attrs)
|
||||
if using_content in (1, 2) and not missing_content_path:
|
||||
mock_osutils.set_static_network_config.assert_called_once_with(
|
||||
'fake adapter', search_result.group('address'),
|
||||
search_result.group('netmask'),
|
||||
search_result.group('broadcast'),
|
||||
search_result.group('gateway'),
|
||||
search_result.group('dnsnameservers').strip().split(' '))
|
||||
self.assertEqual((base.PLUGIN_EXECUTION_DONE, False), response)
|
||||
mac,
|
||||
address,
|
||||
netmask,
|
||||
broadcast,
|
||||
gateway,
|
||||
dnsnameservers
|
||||
)
|
||||
self.assertEqual((plugin_base.PLUGIN_EXECUTION_DONE, False),
|
||||
response)
|
||||
|
||||
def test_execute(self):
|
||||
m = mock.MagicMock()
|
||||
self._test_execute(search_result=m, no_adapters=False)
|
||||
self._test_execute(using_content=1)
|
||||
|
||||
def test_execute_missing_content_path(self):
|
||||
self._test_execute(using_content=1, missing_content_path=True)
|
||||
|
||||
def test_execute_no_debian(self):
|
||||
self._test_execute(search_result=None, no_adapters=False)
|
||||
self._test_execute(search_result=None, using_content=1)
|
||||
|
||||
def test_execute_no_adapters(self):
|
||||
m = mock.MagicMock()
|
||||
self._test_execute(search_result=m, no_adapters=True)
|
||||
def test_execute_no_adapter_name(self):
|
||||
self._test_execute(no_adapter_name=True, using_content=1)
|
||||
|
||||
def test_execute_no_adapter_name_or_adapters(self):
|
||||
self._test_execute(no_adapter_name=True, no_adapters=True,
|
||||
using_content=1)
|
||||
|
||||
def test_execute_network_details(self):
|
||||
self._test_execute(using_content=2)
|
||||
|
||||
def test_execute_no_config_or_details(self):
|
||||
self._test_execute(using_content=0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user