Skip to content

Commit 5ae94a3

Browse files
authored
Revert IPv6 conversion fixture (#11995)
* Revert "[image_download] Add ipv6 only mgmt image download test (#11936)" This reverts commit f5cdac4. * Revert "[IPv6 only]Add a fixture to convert the DUT to IPv6 only, and enhance the connection plugin to retry with IPv6 addr if IPv4 addr is unavailable (#11957)" This reverts commit afd7fce. Approach What is the motivation for this PR? There's a performance impact introduced by the IPv6 fixture, the test time is getting longer. Revert and will create another PR after the performance issue is resolved.
1 parent d1820dd commit 5ae94a3

5 files changed

Lines changed: 4 additions & 273 deletions

File tree

ansible/plugins/connection/multi_passwd_ssh.py

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import imp
22
import os
3-
import logging
43

54
from functools import wraps
6-
from ansible.errors import AnsibleAuthenticationFailure, AnsibleConnectionFailure
5+
from ansible.errors import AnsibleAuthenticationFailure
76
from ansible.plugins import connection
87

9-
logger = logging.getLogger(__name__)
108

119
# HACK: workaround to import the SSH connection plugin
1210
_ssh_mod = os.path.join(os.path.dirname(connection.__file__), "ssh.py")
@@ -28,16 +26,8 @@
2826
vars:
2927
- name: ansible_altpasswords
3028
- name: ansible_ssh_altpasswords
31-
hostv6:
32-
description: IPv6 address
33-
vars:
34-
- name: ansible_hostv6
3529
""".lstrip("\n")
3630

37-
# A sample error message that host unreachable:
38-
# 'Failed to connect to the host via ssh: ssh: connect to host 192.168.0.2 port 22: Connection timed out'
39-
CONNECTION_TIMEOUT_ERR_FLAG = "Connection timed out"
40-
4131

4232
def _password_retry(func):
4333
"""
@@ -47,38 +37,6 @@ def _password_retry(func):
4737
"""
4838
@wraps(func)
4939
def wrapped(self, *args, **kwargs):
50-
51-
# If the host have an IPv6 address, try connect IPv4 address first,
52-
# If IPv4 host unavailable, fall back to use IPv6 address
53-
try:
54-
hostv6 = self.get_option("hostv6")
55-
except KeyError:
56-
hostv6 = None
57-
58-
if hostv6:
59-
try:
60-
return func(self, *args, **kwargs)
61-
except AnsibleConnectionFailure as e:
62-
logger.info("First connection failed: {}".format(str(e)))
63-
if CONNECTION_TIMEOUT_ERR_FLAG in e.message:
64-
self._play_context.remote_addr = hostv6
65-
# args sample:
66-
# ( [b'sshpass', b'-d18', b'ssh', b'-o', b'ControlMaster=auto', b'-o', b'ControlPersist=120s', b'-o', b'UserKnownHostsFile=/dev/null', b'-o', b'StrictHostKeyChecking=no', b'-o', b'StrictHostKeyChecking=no', b'-o', b'User="admin"', b'-o', b'ConnectTimeout=60', b'-o', b'ControlPath="/home/user/.ansible/cp/376bdcc730"', 'fc00:1234:5678:abcd::2', b'/bin/sh -c \'echo PLATFORM; uname; echo FOUND; command -v \'"\'"\'python3.10\'"\'"\'; command -v \'"\'"\'python3.9\'"\'"\'; command -v \'"\'"\'python3.8\'"\'"\'; command -v \'"\'"\'python3.7\'"\'"\'; command -v \'"\'"\'python3.6\'"\'"\'; command -v \'"\'"\'python3.5\'"\'"\'; command -v \'"\'"\'/usr/bin/python3\'"\'"\'; command -v \'"\'"\'/usr/libexec/platform-python\'"\'"\'; command -v \'"\'"\'python2.7\'"\'"\'; command -v \'"\'"\'/usr/bin/python\'"\'"\'; command -v \'"\'"\'python\'"\'"\'; echo ENDFOUND && sleep 0\''], None) # noqa: E501
67-
# args[0] are the parameters of ssh connection
68-
ssh_args = args[0]
69-
# Change the IPv4 host in the ssh_args to IPv6
70-
for idx in range(len(ssh_args)):
71-
if type(ssh_args[idx]) == bytes and ssh_args[idx].decode() == self.host:
72-
ssh_args[idx] = hostv6
73-
self.host = hostv6
74-
self.set_option("host", hostv6)
75-
except BaseException as e:
76-
# Only catch the connection error, won't block the multi-password functionality
77-
logger.info("First connection failed: {}".format(str(e)))
78-
79-
# Reset the sshpass_pipe for the new connections to be created
80-
self.sshpass_pipe = os.pipe()
81-
8240
password = self.get_option("password") or self._play_context.password
8341
conn_passwords = [password]
8442
altpassword = self.get_option("altpassword")

tests/common/devices/duthosts.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,9 @@ def __init__(self, ansible_adhoc, tbinfo, duts):
5454
DUTs in the testbed should be used
5555
5656
"""
57-
self.ansible_adhoc = ansible_adhoc
58-
self.tbinfo = tbinfo
59-
self.duts = duts
60-
self.__initialize_nodes()
61-
62-
def __initialize_nodes(self):
6357
# TODO: Initialize the nodes in parallel using multi-threads?
64-
self.nodes = self._Nodes([MultiAsicSonicHost(self.ansible_adhoc, hostname, self, self.tbinfo['topo']['type'])
65-
for hostname in self.tbinfo["duts"] if hostname in self.duts])
58+
self.nodes = self._Nodes([MultiAsicSonicHost(ansible_adhoc, hostname, self, tbinfo['topo']['type'])
59+
for hostname in tbinfo["duts"] if hostname in duts])
6660
self.supervisor_nodes = self._Nodes([node for node in self.nodes if node.is_supervisor_node()])
6761
self.frontend_nodes = self._Nodes([node for node in self.nodes if node.is_frontend_node()])
6862

@@ -131,6 +125,3 @@ def config_facts(self, *module_args, **complex_args):
131125
complex_args['host'] = node.hostname
132126
result[node.hostname] = node.config_facts(*module_args, **complex_args)['ansible_facts']
133127
return result
134-
135-
def reset(self):
136-
self.__initialize_nodes()

tests/common/fixtures/duthost_utils.py

Lines changed: 1 addition & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
from typing import Dict, List
2-
31
import pytest
42
import logging
53
import itertools
64
import collections
75
import ipaddress
86
import time
97
import json
10-
11-
from tests.common import config_reload
128
from tests.common.helpers.assertions import pytest_assert
139
from tests.common.utilities import wait_until
1410
from jinja2 import Template
15-
from netaddr import valid_ipv4, valid_ipv6
11+
from netaddr import valid_ipv4
1612

1713

1814
logger = logging.getLogger(__name__)
@@ -602,131 +598,3 @@ def check_bgp_router_id(duthost, mgFacts):
602598
return False
603599
except Exception as e:
604600
logger.error("Error loading BGP routerID - {}".format(e))
605-
606-
607-
@pytest.fixture(scope="module")
608-
def convert_and_restore_config_db_to_ipv6_only(duthosts):
609-
"""Back up the existing config_db.json file and restore it once the test ends.
610-
611-
Some cases will update the running config during the test and save the config
612-
to be recovered after reboot. In such a case we need to backup config_db.json before
613-
the test starts and then restore it after the test ends.
614-
"""
615-
config_db_file = "/etc/sonic/config_db.json"
616-
config_db_bak_file = "/etc/sonic/config_db.json.before_ipv6_only"
617-
618-
# Sample MGMT_INTERFACE:
619-
# "MGMT_INTERFACE": {
620-
# "eth0|192.168.0.2/24": {
621-
# "forced_mgmt_routes": [
622-
# "192.168.1.1/24"
623-
# ],
624-
# "gwaddr": "192.168.0.1"
625-
# },
626-
# "eth0|fc00:1234:5678:abcd::2/64": {
627-
# "gwaddr": "fc00:1234:5678:abcd::1",
628-
# "forced_mgmt_routes": [
629-
# "fc00:1234:5678:abc1::1/64"
630-
# ]
631-
# }
632-
# }
633-
634-
# duthost_name: config_db_modified
635-
config_db_modified: Dict[str, bool] = {duthost.hostname: False
636-
for duthost in duthosts.nodes}
637-
# duthost_name: [ip_addr]
638-
ipv4_address: Dict[str, List] = {duthost.hostname: []
639-
for duthost in duthosts.nodes}
640-
ipv6_address: Dict[str, List] = {duthost.hostname: []
641-
for duthost in duthosts.nodes}
642-
# Check IPv6 mgmt-ip is set, otherwise the DUT will lose control after v4 mgmt-ip is removed
643-
for duthost in duthosts.nodes:
644-
mgmt_interface = json.loads(duthost.shell(f"jq '.MGMT_INTERFACE' {config_db_file}",
645-
module_ignore_errors=True)["stdout"])
646-
# Use list() to make a copy of mgmt_interface.keys() to avoid
647-
# "RuntimeError: dictionary changed size during iteration" error
648-
for key in list(mgmt_interface):
649-
ip_addr = key.split("|")[1]
650-
ip_addr_without_mask = ip_addr.split('/')[0]
651-
if ip_addr:
652-
is_ipv6 = valid_ipv6(ip_addr_without_mask)
653-
if is_ipv6:
654-
logger.info(f"Host[{duthost.hostname}] IPv6[{ip_addr}]")
655-
ipv6_address[duthost.hostname].append(ip_addr_without_mask)
656-
pytest_assert(len(ipv6_address[duthost.hostname]) > 0,
657-
f"{duthost.hostname} doesn't have IPv6 Management IP address")
658-
659-
# Remove IPv4 mgmt-ip
660-
for duthost in duthosts.nodes:
661-
logger.info(f"Backup {config_db_file} to {config_db_bak_file} on {duthost.hostname}")
662-
duthost.shell(f"cp {config_db_file} {config_db_bak_file}")
663-
mgmt_interface = json.loads(duthost.shell(f"jq '.MGMT_INTERFACE' {config_db_file}",
664-
module_ignore_errors=True)["stdout"])
665-
666-
# Use list() to make a copy of mgmt_interface.keys() to avoid
667-
# "RuntimeError: dictionary changed size during iteration" error
668-
for key in list(mgmt_interface):
669-
ip_addr = key.split("|")[1]
670-
ip_addr_without_mask = ip_addr.split('/')[0]
671-
if ip_addr:
672-
is_ipv4 = valid_ipv4(ip_addr_without_mask)
673-
if is_ipv4:
674-
ipv4_address[duthost.hostname].append(ip_addr_without_mask)
675-
logger.info(f"Removing host[{duthost.hostname}] IPv4[{ip_addr}]")
676-
duthost.shell(f"""jq 'del(."MGMT_INTERFACE"."{key}")' {config_db_file} > temp.json"""
677-
f"""&& mv temp.json {config_db_file}""", module_ignore_errors=True)
678-
config_db_modified[duthost.hostname] = True
679-
config_reload(duthost, wait=120)
680-
duthosts.reset()
681-
682-
# Verify mgmt-interface status
683-
mgmt_intf_name = "eth0"
684-
for duthost in duthosts.nodes:
685-
logger.info(f"Checking host[{duthost.hostname}] mgmt interface[{mgmt_intf_name}]")
686-
mgmt_intf_ifconfig = duthost.shell(f"ifconfig {mgmt_intf_name}", module_ignore_errors=True)["stdout"]
687-
assert_addr_in_ifconfig(addr_set=ipv4_address, hostname=duthost.hostname,
688-
expect_exists=False, ifconfig_output=mgmt_intf_ifconfig)
689-
assert_addr_in_ifconfig(addr_set=ipv6_address, hostname=duthost.hostname,
690-
expect_exists=True, ifconfig_output=mgmt_intf_ifconfig)
691-
692-
yield
693-
694-
# Recover IPv4 mgmt-ip
695-
for duthost in duthosts.nodes:
696-
if config_db_modified[duthost.hostname]:
697-
logger.info(f"Restore {config_db_file} with {config_db_bak_file} on {duthost.hostname}")
698-
duthost.shell(f"mv {config_db_bak_file} {config_db_file}")
699-
config_reload(duthost, safe_reload=True)
700-
duthosts.reset()
701-
702-
# Verify mgmt-interface status
703-
for duthost in duthosts.nodes:
704-
logger.info(f"Checking host[{duthost.hostname}] mgmt interface[{mgmt_intf_name}]")
705-
mgmt_intf_ifconfig = duthost.shell(f"ifconfig {mgmt_intf_name}", module_ignore_errors=True)["stdout"]
706-
assert_addr_in_ifconfig(addr_set=ipv4_address, hostname=duthost.hostname,
707-
expect_exists=True, ifconfig_output=mgmt_intf_ifconfig)
708-
assert_addr_in_ifconfig(addr_set=ipv6_address, hostname=duthost.hostname,
709-
expect_exists=True, ifconfig_output=mgmt_intf_ifconfig)
710-
711-
712-
def assert_addr_in_ifconfig(addr_set: Dict[str, List], hostname: str, expect_exists: bool, ifconfig_output: str):
713-
"""
714-
Assert the address status in the ifconfig output,
715-
if status not as expected, assert as failure
716-
717-
@param addr_set: addr_set, key is dut hostname, value is the list of ip addresses
718-
@param hostname: hostname
719-
@param expect_exists: Expectation of the ip,
720-
True means expect all ip addresses in addr_set appears in the output of ifconfig
721-
False means expect no ip addresses in addr_set appears in the output of ifconfig
722-
@param ifconfig_output: output of 'ifconfig'
723-
"""
724-
for addr in addr_set[hostname]:
725-
if expect_exists:
726-
pytest_assert(addr in ifconfig_output,
727-
f"{addr} not appeared in {hostname} mgmt interface")
728-
logger.info(f"{addr} exists in the output of ifconfig")
729-
else:
730-
pytest_assert(addr not in ifconfig_output,
731-
f"{hostname} mgmt interface still with addr {addr}")
732-
logger.info(f"{addr} not exists in the output of ifconfig which is expected")

tests/common/plugins/conditional_mark/tests_mark_conditions.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -759,12 +759,6 @@ ip/test_ip_packet.py::TestIPPacket::test_forward_ip_packet_with_0xffff_chksum_to
759759
conditions:
760760
- "asic_type in ['mellanox'] or asic_subtype in ['broadcom-dnx']"
761761

762-
ip/test_mgmt_ipv6_only.py::test_image_download_ipv6_only:
763-
skip:
764-
reason: "Skipping mgmt ipv6 test for mgmt topo"
765-
conditions:
766-
- "topo_type in ['m0', 'mx']"
767-
768762
#######################################
769763
##### ipfwd #####
770764
#######################################

tests/ip/test_mgmt_ipv6_only.py

Lines changed: 0 additions & 80 deletions
This file was deleted.

0 commit comments

Comments
 (0)