diff options
author | Max Illfelder <illfelder@users.noreply.github.com> | 2019-06-28 16:08:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-28 16:08:25 -0700 |
commit | f9425830058f32c5eee56ed7cb431056da2ea1e6 (patch) | |
tree | 2fedb31cb20bfff7300b405ccca5ff5d0bb4dcf5 /packages/python-google-compute-engine | |
parent | 6e352be28da49f3ca31579552ed56079a4069de5 (diff) | |
download | google-compute-image-packages-f9425830058f32c5eee56ed7cb431056da2ea1e6.tar.gz |
Enable IPv6 on interfaces based on metadata key. (#632)
* Enable IPv6 on interfaces based on metadata key.
Support for FreeBSD and SLES images is still needed.
* Add a timeout to the dhclient command.
Diffstat (limited to 'packages/python-google-compute-engine')
18 files changed, 323 insertions, 64 deletions
diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/tests/utils_test.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/tests/utils_test.py index 6ff9f9c..f714ba8 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/tests/utils_test.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/tests/utils_test.py @@ -26,6 +26,15 @@ class UtilsTest(unittest.TestCase): self.mock_logger = mock.Mock() self.mock_setup = mock.create_autospec(utils.Utils) + @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclientIpv6') + def testEnableIpv6(self, mock_call): + mocks = mock.Mock() + mocks.attach_mock(mock_call, 'call') + + utils.Utils.EnableIpv6(self.mock_setup, ['A', 'B'], self.mock_logger) + expected_calls = [mock.call.call(['A', 'B'], mock.ANY)] + self.assertEqual(mocks.mock_calls, expected_calls) + @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclient') def testEnableNetworkInterfaces(self, mock_call): mocks = mock.Mock() diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/utils.py index 9bdccb8..f58e09d 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_8/utils.py @@ -23,8 +23,17 @@ from google_compute_engine.distro_lib import utils class Utils(utils.Utils): """Utilities used by Linux guest services on Debian 8.""" - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + helpers.CallDhclientIpv6(interfaces, logger) + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/tests/utils_test.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/tests/utils_test.py index 2717f00..fbb9a8e 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/tests/utils_test.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/tests/utils_test.py @@ -26,6 +26,15 @@ class UtilsTest(unittest.TestCase): self.mock_logger = mock.Mock() self.mock_setup = mock.create_autospec(utils.Utils) + @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclientIpv6') + def testEnableIpv6(self, mock_call): + mocks = mock.Mock() + mocks.attach_mock(mock_call, 'call') + + utils.Utils.EnableIpv6(self.mock_setup, ['A', 'B'], self.mock_logger) + expected_calls = [mock.call.call(['A', 'B'], mock.ANY)] + self.assertEqual(mocks.mock_calls, expected_calls) + @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclient') def testEnableNetworkInterfaces(self, mock_call): mocks = mock.Mock() diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/utils.py index 452e02f..11a5cbd 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/debian_9/utils.py @@ -23,8 +23,17 @@ from google_compute_engine.distro_lib import utils class Utils(utils.Utils): """Utilities used by Linux guest services on Debian 9.""" - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + helpers.CallDhclientIpv6(interfaces, logger) + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/tests/utils_test.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/tests/utils_test.py index 539b059..f47f5c7 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/tests/utils_test.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/tests/utils_test.py @@ -29,6 +29,19 @@ class UtilsTest(unittest.TestCase): def tearDown(self): pass + @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclientIpv6') + def testEnableIpv6(self, mock_call): + mocks = mock.Mock() + mocks.attach_mock(mock_call, 'call') + + utils.Utils.EnableIpv6( + self.mock_setup, ['A', 'B'], self.mock_logger, + dhclient_script='test_script') + expected_calls = [ + mock.call.call(['A', 'B'], mock.ANY, dhclient_script='test_script'), + ] + self.assertEqual(mocks.mock_calls, expected_calls) + @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclient') def testEnableNetworkInterfaces(self, mock_call): mocks = mock.Mock() diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/utils.py index 20b8e2f..43b8769 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_6/utils.py @@ -21,10 +21,20 @@ from google_compute_engine.distro_lib import utils class Utils(utils.Utils): - """Utilities used by Linux guest services on Debian 8.""" + """Utilities used by Linux guest services on EL 6.""" - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + helpers.CallDhclientIpv6( + interfaces, logger, dhclient_script=dhclient_script) + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/tests/utils_test.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/tests/utils_test.py index d726c3d..0e096db 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/tests/utils_test.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/tests/utils_test.py @@ -96,6 +96,15 @@ class UtilsTest(unittest.TestCase): ] self.assertEqual(mocks.mock_calls, expected_calls) + @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclientIpv6') + def testEnableIpv6(self, mock_call): + mocks = mock.Mock() + mocks.attach_mock(mock_call, 'call') + + utils.Utils.EnableIpv6(self.mock_setup, ['A', 'B'], self.mock_logger) + expected_calls = [mock.call.call(['A', 'B'], mock.ANY)] + self.assertEqual(mocks.mock_calls, expected_calls) + @mock.patch('google_compute_engine.distro_lib.el_7.utils.os.path.exists') @mock.patch('google_compute_engine.distro_lib.helpers.CallDhclient') def testEnableNetworkInterfaces(self, mock_call, mock_exists): diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/utils.py index b11a98f..062d471 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/el_7/utils.py @@ -30,8 +30,17 @@ class Utils(utils.Utils): network_path = constants.LOCALBASE + '/etc/sysconfig/network-scripts' - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + helpers.CallDhclientIpv6(interfaces, logger) + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/freebsd_11/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/freebsd_11/utils.py index 4a9e706..2734c8f 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/freebsd_11/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/freebsd_11/utils.py @@ -23,8 +23,17 @@ from google_compute_engine.distro_lib import utils class Utils(utils.Utils): """Utilities used by Linux guest services on FreeBSD 11.""" - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + pass + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/helpers.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/helpers.py index 93902b3..cbe810e 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/helpers.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/helpers.py @@ -42,6 +42,29 @@ def CallDhclient( logger.warning('Could not enable interfaces %s.', interfaces) +def CallDhclientIpv6(interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + logger.info('Enabling IPv6 on the Ethernet interfaces %s.', interfaces) + + timeout_command = ['timeout', '5'] + dhclient_command = ['dhclient'] + + if dhclient_script and os.path.exists(dhclient_script): + dhclient_command += ['-sf', dhclient_script] + + try: + subprocess.check_call( + timeout_command + dhclient_command + ['-1', '-6', '-v'] + interfaces) + except subprocess.CalledProcessError: + logger.warning('Could not enable IPv6 on interface %s.', interfaces) + + def CallHwclock(logger): """Sync clock using hwclock. diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_11/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_11/utils.py index 6d1d0f2..623505c 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_11/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_11/utils.py @@ -27,8 +27,17 @@ from google_compute_engine.distro_lib import utils class Utils(utils.Utils): """Utilities used by Linux guest services on SUSE 11.""" - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + pass + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_12/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_12/utils.py index 380df7b..b4a3d00 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_12/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/sles_12/utils.py @@ -29,8 +29,17 @@ class Utils(utils.Utils): network_path = constants.LOCALBASE + '/etc/sysconfig/network' - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Configure the network interfaces for IPv6 using dhclient. + + Args: + interface: string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + pass + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/tests/helpers_test.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/tests/helpers_test.py index 7533b20..7c2c0b6 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/tests/helpers_test.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/tests/helpers_test.py @@ -65,6 +65,45 @@ class HelpersTest(unittest.TestCase): self.assertEqual(mocks.mock_calls, expected_calls) + @mock.patch('google_compute_engine.distro_lib.helpers.os.path.exists') + @mock.patch('google_compute_engine.distro_lib.helpers.subprocess.check_call') + def testCallDhclientIpv6(self, mock_call, mock_exists): + mocks = mock.Mock() + mocks.attach_mock(mock_exists, 'exists') + mocks.attach_mock(mock_call, 'call') + mocks.attach_mock(self.mock_logger, 'logger') + + mock_exists.side_effect = [False, True] + mock_call.side_effect = [ + None, None, None, subprocess.CalledProcessError(1, 'Test'), + ] + + helpers.CallDhclientIpv6(['a', 'b'], self.mock_logger, 'test_script') + helpers.CallDhclientIpv6(['c', 'd'], self.mock_logger, 'test_script') + helpers.CallDhclientIpv6(['e', 'f'], self.mock_logger, None) + helpers.CallDhclientIpv6(['g', 'h'], self.mock_logger, None) + + expected_calls = [ + mock.call.logger.info(mock.ANY, ['a', 'b']), + mock.call.exists('test_script'), + mock.call.call( + ['timeout', '5', 'dhclient', '-1', '-6', '-v', 'a', 'b']), + mock.call.logger.info(mock.ANY, ['c', 'd']), + mock.call.exists('test_script'), + mock.call.call( + ['timeout', '5', 'dhclient', '-sf', 'test_script', '-1', '-6', + '-v', 'c', 'd']), + mock.call.logger.info(mock.ANY, ['e', 'f']), + mock.call.call( + ['timeout', '5', 'dhclient', '-1', '-6', '-v', 'e', 'f']), + mock.call.logger.info(mock.ANY, ['g', 'h']), + mock.call.call( + ['timeout', '5', 'dhclient', '-1', '-6', '-v', 'g', 'h']), + mock.call.logger.warning(mock.ANY, ['g', 'h']), + ] + + self.assertEqual(mocks.mock_calls, expected_calls) + @mock.patch('google_compute_engine.distro_lib.helpers.subprocess.check_call') def testCallHwclock(self, mock_call): command = ['/sbin/hwclock', '--hctosys'] diff --git a/packages/python-google-compute-engine/google_compute_engine/distro_lib/utils.py b/packages/python-google-compute-engine/google_compute_engine/distro_lib/utils.py index 75b656e..df1d45c 100644 --- a/packages/python-google-compute-engine/google_compute_engine/distro_lib/utils.py +++ b/packages/python-google-compute-engine/google_compute_engine/distro_lib/utils.py @@ -27,8 +27,17 @@ class Utils(object): """ self.debug = debug - def EnableNetworkInterfaces( - self, interfaces, logger, dhclient_script=None): + def EnableIpv6(self, interfaces, logger, dhclient_script=None): + """Enable IPv6 on the list of network interfaces. + + Args: + interfaces: list of string, the output device names for enabling IPv6. + logger: logger object, used to write to SysLog and serial port. + dhclient_script: string, the path to a dhclient script used by dhclient. + """ + pass + + def EnableNetworkInterfaces(self, interfaces, logger, dhclient_script=None): """Enable the list of network interfaces. Args: diff --git a/packages/python-google-compute-engine/google_compute_engine/networking/network_daemon.py b/packages/python-google-compute-engine/google_compute_engine/networking/network_daemon.py index 95b190b..ce0dd65 100644 --- a/packages/python-google-compute-engine/google_compute_engine/networking/network_daemon.py +++ b/packages/python-google-compute-engine/google_compute_engine/networking/network_daemon.py @@ -90,6 +90,9 @@ class NetworkDaemon(object): network_interfaces = self._ExtractInterfaceMetadata(result) if self.network_setup_enabled: + default_interface = network_interfaces[0] + if default_interface.ipv6: + self.network_setup.EnableIpv6([default_interface.name]) self.network_setup.EnableNetworkInterfaces( [interface.name for interface in network_interfaces[1:]]) @@ -119,7 +122,9 @@ class NetworkDaemon(object): if self.target_instance_ips: ip_addresses.extend(network_interface.get('targetInstanceIps', [])) interfaces.append(NetworkDaemon.NetworkInterface( - interface, ip_addresses, network_interface.get('ip', []))) + interface, forwarded_ips=ip_addresses, + ip=network_interface.get('ip', None), + ipv6='dhcpv6Refresh' in network_interface.keys())) else: message = 'Network interface not found for MAC address: %s.' self.logger.warning(message, mac_address) @@ -128,10 +133,11 @@ class NetworkDaemon(object): class NetworkInterface(object): """Network interface information extracted from metadata.""" - def __init__(self, name, forwarded_ips=None, ip=None): + def __init__(self, name, forwarded_ips=None, ip=None, ipv6=False): self.name = name self.forwarded_ips = forwarded_ips self.ip = ip + self.ipv6 = ipv6 def main(): diff --git a/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/network_setup.py b/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/network_setup.py index 9166722..f8b3be5 100755 --- a/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/network_setup.py +++ b/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/network_setup.py @@ -26,6 +26,7 @@ class NetworkSetup(object): """Enable network interfaces.""" interfaces = set() + ipv6_interfaces = set() network_interfaces = 'instance/network-interfaces' def __init__(self, dhclient_script=None, dhcp_command=None, debug=False): @@ -43,6 +44,22 @@ class NetworkSetup(object): name='network-setup', debug=debug, facility=facility) self.distro_utils = distro_utils.Utils(debug=debug) + def EnableIpv6(self, interfaces): + """Enable IPv6 on the list of network interfaces. + + Args: + interfaces: list of string, the output device names for enabling IPv6. + """ + if not interfaces or set(interfaces) == self.ipv6_interfaces: + return + + self.logger.info('Enabling IPv6 on Ethernet interface: %s.', interfaces) + self.ipv6_interfaces = set(interfaces) + + # Distro-specific setup for enabling IPv6 on network interfaces. + self.distro_utils.EnableIpv6( + interfaces, self.logger, dhclient_script=self.dhclient_script) + def EnableNetworkInterfaces(self, interfaces): """Enable the list of network interfaces. diff --git a/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/tests/network_setup_test.py b/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/tests/network_setup_test.py index 644510a..c57547e 100644 --- a/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/tests/network_setup_test.py +++ b/packages/python-google-compute-engine/google_compute_engine/networking/network_setup/tests/network_setup_test.py @@ -27,61 +27,79 @@ class NetworkSetupTest(unittest.TestCase): def setUp(self): self.mock_logger = mock.Mock() self.mock_distro_utils = mock.Mock() - self.mock_setup = mock.create_autospec(network_setup.NetworkSetup) - self.mock_setup.logger = self.mock_logger - self.mock_setup.distro_utils = self.mock_distro_utils - self.mock_setup.dhclient_script = '/bin/script' - self.mock_setup.dhcp_command = '' + self.dhclient_script = '/bin/script' + self.dhcp_command = '' + self.setup = network_setup.NetworkSetup( + dhclient_script=self.dhclient_script, dhcp_command=self.dhcp_command, + debug=False) + self.setup.distro_utils = self.mock_distro_utils + self.setup.logger = self.mock_logger - @mock.patch('google_compute_engine.networking.network_setup.network_setup.logger') - def testNetworkSetup(self, mock_logger): - mock_logger_instance = mock.Mock() - mock_logger.Logger.return_value = mock_logger_instance + @mock.patch('google_compute_engine.networking.network_setup.network_setup.subprocess.check_call') + def testEnableIpv6(self, mock_call): mocks = mock.Mock() - mocks.attach_mock(mock_logger, 'logger') - with mock.patch.object( - network_setup.NetworkSetup, 'EnableNetworkInterfaces'): + mocks.attach_mock(mock_call, 'call') + mocks.attach_mock(self.mock_logger, 'logger') + mocks.attach_mock(self.mock_distro_utils.EnableIpv6, 'enable') + mock_call.side_effect = [None, subprocess.CalledProcessError(1, 'Test')] - network_setup.NetworkSetup(['A', 'B'], debug=True) - expected_calls = [ - mock.call.logger.Logger(name=mock.ANY, debug=True, facility=mock.ANY), - ] - self.assertEqual(mocks.mock_calls, expected_calls) + # Return immediately with no interfaces. + network_setup.NetworkSetup.EnableIpv6(self.setup, None) + network_setup.NetworkSetup.EnableIpv6(self.setup, []) + # Enable interfaces. + network_setup.NetworkSetup.EnableIpv6( + self.setup, ['A', 'B']) + self.assertEqual(self.setup.ipv6_interfaces, set(['A', 'B'])) + # Add a new interface. + network_setup.NetworkSetup.EnableIpv6( + self.setup, ['A', 'B', 'C']) + self.assertEqual(self.setup.ipv6_interfaces, set(['A', 'B', 'C'])) + # Interfaces are already enabled. + network_setup.NetworkSetup.EnableIpv6( + self.setup, ['A', 'B', 'C']) + self.assertEqual(self.setup.ipv6_interfaces, set(['A', 'B', 'C'])) + expected_calls = [ + mock.call.logger.info(mock.ANY, ['A', 'B']), + mock.call.enable(['A', 'B'], mock.ANY, dhclient_script='/bin/script'), + mock.call.logger.info(mock.ANY, ['A', 'B', 'C']), + mock.call.enable( + ['A', 'B', 'C'], mock.ANY, dhclient_script='/bin/script'), + ] + self.assertEqual(mocks.mock_calls, expected_calls) @mock.patch('google_compute_engine.networking.network_setup.network_setup.subprocess.check_call') def testEnableNetworkInterfaces(self, mock_call): mocks = mock.Mock() mocks.attach_mock(mock_call, 'call') mocks.attach_mock(self.mock_logger, 'logger') - mocks.attach_mock( - self.mock_setup.distro_utils.EnableNetworkInterfaces, 'enable') + mocks.attach_mock(self.mock_distro_utils.EnableNetworkInterfaces, 'enable') mock_call.side_effect = [None, subprocess.CalledProcessError(1, 'Test')] - # Return immediately with fewer than two interfaces. - network_setup.NetworkSetup.EnableNetworkInterfaces(self.mock_setup, None) - network_setup.NetworkSetup.EnableNetworkInterfaces(self.mock_setup, []) + # Return immediately with no interfaces. + network_setup.NetworkSetup.EnableNetworkInterfaces(self.setup, None) + network_setup.NetworkSetup.EnableNetworkInterfaces(self.setup, []) # Enable interfaces. network_setup.NetworkSetup.EnableNetworkInterfaces( - self.mock_setup, ['A', 'B']) - self.assertEqual(self.mock_setup.interfaces, set(['A', 'B'])) + self.setup, ['A', 'B']) + self.assertEqual(self.setup.interfaces, set(['A', 'B'])) # Add a new interface. network_setup.NetworkSetup.EnableNetworkInterfaces( - self.mock_setup, ['A', 'B', 'C']) - self.assertEqual(self.mock_setup.interfaces, set(['A', 'B', 'C'])) + self.setup, ['A', 'B', 'C']) + self.assertEqual(self.setup.interfaces, set(['A', 'B', 'C'])) # Interfaces are already enabled. network_setup.NetworkSetup.EnableNetworkInterfaces( - self.mock_setup, ['A', 'B', 'C']) - self.assertEqual(self.mock_setup.interfaces, set(['A', 'B', 'C'])) + self.setup, ['A', 'B', 'C']) + self.assertEqual(self.setup.interfaces, set(['A', 'B', 'C'])) # Run a user supplied command successfully. - self.mock_setup.dhcp_command = 'success' + self.setup.dhcp_command = 'success' network_setup.NetworkSetup.EnableNetworkInterfaces( - self.mock_setup, ['D', 'E']) - self.assertEqual(self.mock_setup.interfaces, set(['D', 'E'])) + self.setup, ['D', 'E']) + self.assertEqual(self.setup.interfaces, set(['D', 'E'])) # Run a user supplied command and logger error messages. - self.mock_setup.dhcp_command = 'failure' + self.setup.dhcp_command = 'failure' network_setup.NetworkSetup.EnableNetworkInterfaces( - self.mock_setup, ['F', 'G']) - self.assertEqual(self.mock_setup.interfaces, set(['F', 'G'])) + self.setup, ['F', 'G']) + self.assertEqual(self.setup.interfaces, set(['F', 'G'])) expected_calls = [ mock.call.logger.info(mock.ANY, ['A', 'B']), mock.call.enable(['A', 'B'], mock.ANY, dhclient_script='/bin/script'), diff --git a/packages/python-google-compute-engine/google_compute_engine/networking/tests/network_daemon_test.py b/packages/python-google-compute-engine/google_compute_engine/networking/tests/network_daemon_test.py index acf0371..dd74fdd 100644 --- a/packages/python-google-compute-engine/google_compute_engine/networking/tests/network_daemon_test.py +++ b/packages/python-google-compute-engine/google_compute_engine/networking/tests/network_daemon_test.py @@ -139,8 +139,9 @@ class NetworkDaemonTest(unittest.TestCase): self.mock_setup.ip_forwarding_enabled = True self.mock_setup.network_setup_enabled = True self.mock_setup._ExtractInterfaceMetadata.return_value = [ - network_daemon.NetworkDaemon.NetworkInterface('a'), - network_daemon.NetworkDaemon.NetworkInterface('b'), + network_daemon.NetworkDaemon.NetworkInterface( + 'eth0', forwarded_ips=['a'], ip='1.1.1.1', ipv6=False), + network_daemon.NetworkDaemon.NetworkInterface('eth1'), ] result = mock.Mock() @@ -148,9 +149,36 @@ class NetworkDaemonTest(unittest.TestCase): self.mock_setup, result) expected_calls = [ mock.call.setup._ExtractInterfaceMetadata(result), - mock.call.network_setup.EnableNetworkInterfaces(['b']), - mock.call.forwarding.HandleForwardedIps('a', None, None), - mock.call.forwarding.HandleForwardedIps('b', None, None), + mock.call.network_setup.EnableNetworkInterfaces(['eth1']), + mock.call.forwarding.HandleForwardedIps( + 'eth0', ['a'], '1.1.1.1'), + mock.call.forwarding.HandleForwardedIps('eth1', None, None), + ] + self.assertEqual(mocks.mock_calls, expected_calls) + + def testHandleNetworkInterfacesIpv6(self): + mocks = mock.Mock() + mocks.attach_mock(self.mock_ip_forwarding, 'forwarding') + mocks.attach_mock(self.mock_network_setup, 'network_setup') + mocks.attach_mock(self.mock_setup, 'setup') + self.mock_setup.ip_aliases = None + self.mock_setup.target_instance_ips = None + self.mock_setup.ip_forwarding_enabled = True + self.mock_setup.network_setup_enabled = True + self.mock_setup._ExtractInterfaceMetadata.return_value = [ + network_daemon.NetworkDaemon.NetworkInterface( + 'eth0', forwarded_ips=['a'], ip='1.1.1.1', ipv6=True), + ] + result = mock.Mock() + + network_daemon.NetworkDaemon.HandleNetworkInterfaces( + self.mock_setup, result) + expected_calls = [ + mock.call.setup._ExtractInterfaceMetadata(result), + mock.call.network_setup.EnableIpv6(['eth0']), + mock.call.network_setup.EnableNetworkInterfaces([]), + mock.call.forwarding.HandleForwardedIps( + 'eth0', ['a'], '1.1.1.1'), ] self.assertEqual(mocks.mock_calls, expected_calls) @@ -187,12 +215,15 @@ class NetworkDaemonTest(unittest.TestCase): { 'mac': '1', 'forwardedIps': ['a'], + 'dhcpv6Refresh': 1, }, { 'mac': '2', 'forwardedIps': ['b'], 'ipAliases': ['banana'], 'targetInstanceIps': ['baklava'], + 'ip': '2.2.2.2', + 'dhcpv6Refresh': 2, }, { 'mac': '3', @@ -209,11 +240,13 @@ class NetworkDaemonTest(unittest.TestCase): }, ] expected_interfaces = [ - network_daemon.NetworkDaemon.NetworkInterface('eth0', ['a']), network_daemon.NetworkDaemon.NetworkInterface( - 'eth1', ['b', 'banana', 'baklava']), + 'eth0', forwarded_ips=['a'], ip=None, ipv6=True), + network_daemon.NetworkDaemon.NetworkInterface( + 'eth1', forwarded_ips=['b', 'banana', 'baklava'], ip='2.2.2.2', + ipv6=True), network_daemon.NetworkDaemon.NetworkInterface( - 'eth2', ['cherry', 'cake']), + 'eth2', forwarded_ips=['cherry', 'cake'], ip=None), ] actual_interfaces = network_daemon.NetworkDaemon._ExtractInterfaceMetadata( @@ -221,6 +254,8 @@ class NetworkDaemonTest(unittest.TestCase): for actual, expected in zip(actual_interfaces, expected_interfaces): self.assertEqual(actual.name, expected.name) self.assertEqual(actual.forwarded_ips, expected.forwarded_ips) + self.assertEqual(actual.ip, expected.ip) + self.assertEqual(actual.ipv6, expected.ipv6) def testExtractInterfaceMetadataWithoutOptions(self): self.mock_setup.ip_aliases = None @@ -233,12 +268,15 @@ class NetworkDaemonTest(unittest.TestCase): { 'mac': '1', 'forwardedIps': ['a'], + 'dhcpv6Refresh': 1, }, { 'mac': '2', 'forwardedIps': ['b'], 'ipAliases': ['banana'], 'targetInstanceIps': ['baklava'], + 'ip': '2.2.2.2', + 'dhcpv6Refresh': 2, }, { 'mac': '3', @@ -247,9 +285,12 @@ class NetworkDaemonTest(unittest.TestCase): }, ] expected_interfaces = [ - network_daemon.NetworkDaemon.NetworkInterface('eth0', ['a']), - network_daemon.NetworkDaemon.NetworkInterface('eth1', ['b']), - network_daemon.NetworkDaemon.NetworkInterface('eth2', []), + network_daemon.NetworkDaemon.NetworkInterface( + 'eth0', forwarded_ips=['a'], ip=None, ipv6=True), + network_daemon.NetworkDaemon.NetworkInterface( + 'eth1', forwarded_ips=['b'], ip='2.2.2.2', ipv6=True), + network_daemon.NetworkDaemon.NetworkInterface( + 'eth2', forwarded_ips=[], ip=None, ipv6=False), ] actual_interfaces = network_daemon.NetworkDaemon._ExtractInterfaceMetadata( @@ -257,3 +298,5 @@ class NetworkDaemonTest(unittest.TestCase): for actual, expected in zip(actual_interfaces, expected_interfaces): self.assertEqual(actual.name, expected.name) self.assertEqual(actual.forwarded_ips, expected.forwarded_ips) + self.assertEqual(actual.ip, expected.ip) + self.assertEqual(actual.ipv6, expected.ipv6) |