diff --git a/zaza/openstack/configure/network.py b/zaza/openstack/configure/network.py index 68965d9..55bcdf3 100755 --- a/zaza/openstack/configure/network.py +++ b/zaza/openstack/configure/network.py @@ -212,12 +212,23 @@ def setup_gateway_ext_port(network_config, keystone_session=None): else: net_id = None + # If we're using netplan, we need to add the new interface to the guest + current_release = openstack_utils.get_os_release() + bionic_queens = openstack_utils.get_os_release('bionic_queens') + if current_release >= bionic_queens: + logging.warn("Adding second interface for dataport to guest netplan " + "for bionic-queens and later") + add_dataport_to_netplan = True + else: + add_dataport_to_netplan = False + logging.info("Configuring network for OpenStack undercloud/provider") openstack_utils.configure_gateway_ext_port( nova_client, neutron_client, dvr_mode=network_config.get("dvr_enabled", False), - net_id=net_id) + net_id=net_id, + add_dataport_to_netplan=add_dataport_to_netplan) def run_from_cli(**kwargs): diff --git a/zaza/openstack/utilities/openstack.py b/zaza/openstack/utilities/openstack.py index 1c3789b..26b6aaf 100644 --- a/zaza/openstack/utilities/openstack.py +++ b/zaza/openstack/utilities/openstack.py @@ -55,6 +55,7 @@ import sys import tempfile import tenacity import urllib +import textwrap from zaza import model from zaza.openstack.utilities import ( @@ -488,8 +489,67 @@ def get_admin_net(neutron_client): return net +def add_interface_to_netplan(server_name, mac_address, dvr_mode=None): + """In guest server_name, add nic with mac_address to netplan. + + :param server_name: Hostname of instance + :type server_name: string + :param mac_address: mac address of nic to be added to netplan + :type mac_address: string + :param dvr_mode: Using DVR mode or not + :type dvr_mode: boolean + """ + if dvr_mode: + application_name = 'neutron-openvswitch' + else: + application_name = 'neutron-gateway' + + unit_name = juju_utils.get_unit_name_from_host_name( + server_name, application_name) + + run_cmd_nic = "ip -f link -br -o addr|grep {}".format(mac_address) + interface = model.run_on_unit(unit_name, run_cmd_nic) + interface = interface['Stdout'].split(' ')[0] + + run_cmd_netplan = """sudo egrep -iR '{}|{}$' /etc/netplan/ + """.format(mac_address, interface) + + netplancfg = model.run_on_unit(unit_name, run_cmd_netplan) + + if (mac_address in str(netplancfg)) or (interface in str(netplancfg)): + logging.warn("mac address {} or nic {} already exists in " + "/etc/netplan".format(mac_address, interface)) + return + body_value = textwrap.dedent("""\ + network: + ethernets: + {0}: + dhcp4: false + dhcp6: true + optional: true + match: + macaddress: {1} + set-name: {0} + version: 2 + """.format(interface, mac_address)) + logging.debug("plumb guest interface debug info:") + logging.debug("body_value: {}\nunit_name: {}\ninterface: {}\nmac_address:" + "{}\nserver_name: {}".format(body_value, unit_name, + interface, mac_address, + server_name)) + with tempfile.NamedTemporaryFile(mode="w") as netplan_file: + netplan_file.write(body_value) + netplan_file.flush() + model.scp_to_unit(unit_name, netplan_file.name, + '/home/ubuntu/60-dataport.yaml', user="ubuntu") + run_cmd_mv = "sudo mv /home/ubuntu/60-dataport.yaml /etc/netplan/" + model.run_on_unit(unit_name, run_cmd_mv) + model.run_on_unit(unit_name, "sudo netplan apply") + + def configure_gateway_ext_port(novaclient, neutronclient, - dvr_mode=None, net_id=None): + dvr_mode=None, net_id=None, + add_dataport_to_netplan=False): """Configure the neturong-gateway external port. :param novaclient: Authenticated novaclient @@ -536,6 +596,10 @@ def configure_gateway_ext_port(novaclient, neutronclient, port = neutronclient.create_port(body=body_value) server.interface_attach(port_id=port['port']['id'], net_id=None, fixed_ip=None) + if add_dataport_to_netplan: + add_interface_to_netplan(server.name, + mac_address=port['mac_address'], + dvr_mode=dvr_mode) ext_br_macs = [] for port in neutronclient.list_ports(network_id=net_id)['ports']: if 'ext-port' in port['name']: