Beispiel #1
0
    def test_from_json_defroute(self):
        data = '{"type": "interface", "name": "em1", "use_dhcp": true}'
        interface1 = objects.object_from_json(json.loads(data))
        data = """{
"type": "interface",
"name": "em1",
"use_dhcp": true,
"defroute": false
}
"""
        interface2 = objects.object_from_json(json.loads(data))
        self.assertTrue(interface1.defroute)
        self.assertFalse(interface2.defroute)
Beispiel #2
0
    def test_from_json_with_addresses(self):
        data = """{
"type": "interface",
"name": "em1",
"use_dhcp": false,
"mtu": 1501,
"addresses": [{
    "ip_netmask": "192.0.2.1/24"
}],
"routes": [{
    "next_hop": "192.0.2.1",
    "ip_netmask": "192.0.2.1/24"
}]
}
"""
        interface = objects.object_from_json(json.loads(data))
        self.assertEqual("em1", interface.name)
        self.assertEqual(False, interface.use_dhcp)
        self.assertEqual(False, interface.use_dhcpv6)
        self.assertEqual(1501, interface.mtu)
        address1 = interface.v4_addresses()[0]
        self.assertEqual("192.0.2.1", address1.ip)
        self.assertEqual("255.255.255.0", address1.netmask)
        route1 = interface.routes[0]
        self.assertEqual("192.0.2.1", route1.next_hop)
        self.assertEqual("192.0.2.1/24", route1.ip_netmask)
Beispiel #3
0
 def test_from_json_dhcp(self):
     data = '{"type": "vlan", "device": "em1", "vlan_id": 16,' \
            '"use_dhcp": true}'
     vlan = objects.object_from_json(json.loads(data))
     self.assertEqual("em1", vlan.device)
     self.assertEqual(16, vlan.vlan_id)
     self.assertEqual(True, vlan.use_dhcp)
Beispiel #4
0
    def test_from_json_primary_interface(self):
        data = """{
"type": "ovs_bridge",
"name": "br-foo",
"use_dhcp": true,
"members": [
    {
    "type": "interface",
    "name": "em1",
    "primary": "true"
    },
    {
    "type": "interface",
    "name": "em2"
    }]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("br-foo", bridge.name)
        self.assertEqual(True, bridge.use_dhcp)
        self.assertEqual("em1", bridge.primary_interface_name)
        interface1 = bridge.members[0]
        self.assertEqual("em1", interface1.name)
        self.assertEqual(True, interface1.ovs_port)
        self.assertEqual(True, interface1.primary)
        self.assertEqual("br-foo", interface1.bridge_name)
        interface2 = bridge.members[1]
        self.assertEqual("em2", interface2.name)
        self.assertEqual(True, interface2.ovs_port)
        self.assertEqual("br-foo", interface2.bridge_name)
Beispiel #5
0
    def test_from_json(self):
        data = """{
"type": "ovs_bridge",
"name": "br-foo",
"members": [{
    "type": "ovs_tunnel",
    "name": "tun0",
    "tunnel_type": "gre",
    "ovs_options": [
        "remote_ip=192.168.1.1"
    ],
    "ovs_extra": [
        "ovs extra"
    ]
}]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("br-foo", bridge.name)
        tun0 = bridge.members[0]
        self.assertEqual("tun0", tun0.name)
        self.assertFalse(tun0.ovs_port)
        self.assertEqual("br-foo", tun0.bridge_name)
        self.assertEqual("gre", tun0.tunnel_type)
        self.assertEqual(
            ["options:remote_ip=192.168.1.1"],
            tun0.ovs_options)
        self.assertEqual(
            ["ovs extra"],
            tun0.ovs_extra)
Beispiel #6
0
    def test_from_json_dhcp_with_nic1_nic2(self):

        def test_numbered_nics():
            return {"nic1": "em1", "nic2": "em2"}
        self.stubs.Set(objects, '_numbered_nics', test_numbered_nics)

        data = """{
"type": "ovs_bond",
"name": "bond1",
"use_dhcp": true,
"members": [
    {
    "type": "interface",
    "name": "nic1"
    },
    {
    "type": "interface",
    "name": "nic2"
    }
]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("bond1", bridge.name)
        self.assertEqual(True, bridge.use_dhcp)
        interface1 = bridge.members[0]
        self.assertEqual("em1", interface1.name)
        interface2 = bridge.members[1]
        self.assertEqual("em2", interface2.name)
Beispiel #7
0
    def test_from_json_dhcp_nic1(self):
        def test_numbered_nics():
            return {"nic1": "em3"}
        self.stubs.Set(objects, '_numbered_nics', test_numbered_nics)

        data = '{"type": "interface", "name": "nic1", "use_dhcp": true}'
        interface = objects.object_from_json(json.loads(data))
        self.assertEqual("em3", interface.name)
        self.assertEqual(True, interface.use_dhcp)
Beispiel #8
0
    def test_from_json_dns_servers(self):
        data = """{
"type": "interface",
"name": "em1",
"use_dhcp": true,
"dns_servers": ["1.2.3.4"]
}
"""
        interface1 = objects.object_from_json(json.loads(data))
        self.assertEqual(["1.2.3.4"], interface1.dns_servers)
Beispiel #9
0
    def test_from_json_dhclient_args(self):
        data = """{
"type": "interface",
"name": "em1",
"use_dhcp": true,
"dhclient_args": "--foobar"
}
"""
        interface1 = objects.object_from_json(json.loads(data))
        self.assertEqual("--foobar", interface1.dhclient_args)
Beispiel #10
0
    def test_from_json_dhcp_nic1(self):
        def test_numbered_nics():
            return {"nic1": "em4"}
        self.stubs.Set(objects, '_numbered_nics', test_numbered_nics)

        data = '{"type": "vlan", "device": "nic1", "vlan_id": 16,' \
               '"use_dhcp": true}'
        vlan = objects.object_from_json(json.loads(data))
        self.assertEqual("em4", vlan.device)
        self.assertEqual(16, vlan.vlan_id)
        self.assertEqual(True, vlan.use_dhcp)
Beispiel #11
0
    def test_interface_from_json(self):
        data = """{
"type": "ivs_bridge",
"members": [{
    "type": "interface",
    "name": "nic2"
}]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("ivs", bridge.name)
        interface1 = bridge.members[0]
        self.assertEqual("nic2", interface1.name)
        self.assertEqual(False, interface1.ovs_port)
        self.assertEqual("ivs", interface1.ivs_bridge_name)
Beispiel #12
0
def main(argv=sys.argv):
    opts = parse_opts(argv)
    configure_logger(opts.verbose, opts.debug)
    logger.info('Using config file at: %s' % opts.config_file)
    iface_array = []

    provider = None
    if opts.provider:
        if opts.provider == 'ifcfg':
            provider = impl_ifcfg.IfcfgNetConfig()
        elif opts.provider == 'eni':
            provider = impl_eni.ENINetConfig()
        elif opts.provider == 'iproute':
            provider = impl_iproute.IPRouteNetConfig()
        else:
            logger.error('Invalid provider specified.')
            return 1
    else:
        if os.path.exists('/etc/sysconfig/network-scripts/'):
            provider = impl_ifcfg.IfcfgNetConfig()
        elif os.path.exists('/etc/network/'):
            provider = impl_eni.ENINetConfig()
        else:
            logger.error('Unable to set provider for this operating system.')
            return 1

    if os.path.exists(opts.config_file):
        with open(opts.config_file) as cf:
            iface_array = yaml.load(cf.read()).get("network_config")
            logger.debug('network_config JSON: %s' % str(iface_array))
    else:
        logger.error('No config file exists at: %s' % opts.config_file)
        return 1
    if not isinstance(iface_array, list):
        logger.error('No interfaces defined in config: %s' % opts.config_file)
        return 1
    for iface_json in iface_array:
        obj = objects.object_from_json(iface_json)
        provider.add_object(obj)
    files_changed = provider.apply(noop=opts.noop, cleanup=opts.cleanup)
    if opts.noop:
        for location, data in files_changed.iteritems():
            print "File: %s\n" % location
            print data
            print "----"
    return 0
Beispiel #13
0
    def test_from_json_dhcp(self):
        data = """{
"type": "linux_bridge",
"name": "br-foo",
"use_dhcp": true,
"members": [{
    "type": "interface",
    "name": "em1"
}]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("br-foo", bridge.name)
        self.assertTrue(bridge.use_dhcp)
        interface1 = bridge.members[0]
        self.assertEqual("em1", interface1.name)
        self.assertFalse(interface1.ovs_port)
        self.assertEqual("br-foo", interface1.linux_bridge_name)
Beispiel #14
0
    def test_from_json_dhcp_with_nic1(self):
        def test_numbered_nics():
            return {"nic1": "em5"}
        self.stubs.Set(objects, '_numbered_nics', test_numbered_nics)

        data = """{
"type": "ovs_bridge",
"name": "br-foo",
"use_dhcp": true,
"members": [{
    "type": "interface",
    "name": "nic1"
}]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("br-foo", bridge.name)
        self.assertEqual(True, bridge.use_dhcp)
        interface1 = bridge.members[0]
        self.assertEqual("em5", interface1.name)
        self.assertEqual(True, interface1.ovs_port)
        self.assertEqual("br-foo", interface1.bridge_name)
Beispiel #15
0
    def test_from_json_dhcp(self):
        data = """{
"type": "ovs_bond",
"name": "bond1",
"use_dhcp": true,
"members": [
    {
    "type": "interface",
    "name": "em1"
    },
    {
    "type": "interface",
    "name": "em2"
    }
]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("bond1", bridge.name)
        self.assertEqual(True, bridge.use_dhcp)
        interface1 = bridge.members[0]
        self.assertEqual("em1", interface1.name)
        interface2 = bridge.members[1]
        self.assertEqual("em2", interface2.name)
Beispiel #16
0
    def test_from_json_dhcp(self):
        data = """{
"type": "linux_bond",
"name": "bond1",
"use_dhcp": true,
"members": [
    {
    "type": "interface",
    "name": "em1"
    },
    {
    "type": "interface",
    "name": "em2"
    }
]
}
"""
        bridge = objects.object_from_json(json.loads(data))
        self.assertEqual("bond1", bridge.name)
        self.assertTrue(bridge.use_dhcp)
        interface1 = bridge.members[0]
        self.assertEqual("em1", interface1.name)
        interface2 = bridge.members[1]
        self.assertEqual("em2", interface2.name)
Beispiel #17
0
def main(argv=sys.argv, main_logger=None):
    opts = parse_opts(argv)
    if not main_logger:
        main_logger = common.configure_logger(log_file=not opts.noop)
    common.logger_level(main_logger, opts.verbose, opts.debug)
    main_logger.info(f"Using config file at: {opts.config_file}")
    iface_array = []
    configure_sriov = False
    sriovpf_member_of_bond_ovs_port_list = []
    provider = None
    if opts.provider:
        if opts.provider == 'ifcfg':
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif opts.provider == 'eni':
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        elif opts.provider == 'iproute':
            provider = impl_iproute.IPRouteNetConfig(noop=opts.noop,
                                                     root_dir=opts.root_dir)
        else:
            main_logger.error("Invalid provider specified.")
            return 1
    else:
        if os.path.exists('%s/etc/sysconfig/network-scripts/' % opts.root_dir):
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif os.path.exists('%s/etc/network/' % opts.root_dir):
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        else:
            main_logger.error("Unable to set provider for this operating "
                              "system.")
            return 1

    # Read the interface mapping file, if it exists
    # This allows you to override the default network naming abstraction
    # mappings by specifying a specific nicN->name or nicN->MAC mapping
    if os.path.exists(opts.mapping_file):
        main_logger.info(f"Using mapping file at: {opts.mapping_file}")
        with open(opts.mapping_file) as cf:
            iface_map = yaml.safe_load(cf.read())
            iface_mapping = iface_map.get("interface_mapping")
            main_logger.debug(f"interface_mapping: {iface_mapping}")
            persist_mapping = opts.persist_mapping
            main_logger.debug(f"persist_mapping: {persist_mapping}")
    else:
        main_logger.info("Not using any mapping file.")
        iface_mapping = None
        persist_mapping = False

    # If --interfaces is specified, either return the real name of the
    # interfaces specified, or return the map of all nic abstractions/names.
    if opts.interfaces is not None:
        reported_nics = {}
        mapped_nics = objects.mapped_nics(iface_mapping)
        retval = 0
        if len(opts.interfaces) > 0:
            for requested_nic in opts.interfaces:
                found = False
                # Check to see if requested iface is a mapped NIC name.
                if requested_nic in mapped_nics:
                    reported_nics[requested_nic] = mapped_nics[requested_nic]
                    found = True
                # Check to see if the requested iface is a real NIC name
                if requested_nic in mapped_nics.values():
                    if found is True:  # Name matches alias and real NIC
                        # (return the mapped NIC, but warn of overlap).
                        main_logger.warning(f"{requested_nic} overlaps with "
                                            "real NIC name.")
                    else:
                        reported_nics[requested_nic] = requested_nic
                        found = True
                if not found:
                    retval = 1
            if reported_nics:
                main_logger.debug("Interface mapping requested for interface: "
                                  "%s" % reported_nics.keys())
        else:
            main_logger.debug("Interface mapping requested for all interfaces")
            reported_nics = mapped_nics
        # Return the report on the mapped NICs. If all NICs were found, exit
        # cleanly, otherwise exit with status 1.
        main_logger.debug("Interface report requested, exiting after report.")
        print(json.dumps(reported_nics))
        return retval

    # Read config file containing network configs to apply
    if os.path.exists(opts.config_file):
        try:
            with open(opts.config_file) as cf:
                iface_array = yaml.safe_load(cf.read()).get("network_config")
                main_logger.debug(f"network_config: {iface_array}")
        except IOError:
            main_logger.error(f"Error reading file: {opts.config_file}")
            return 1
    else:
        main_logger.error(f"No config file exists at: {opts.config_file}")
        return 1

    if not isinstance(iface_array, list):
        main_logger.error("No interfaces defined in config: "
                          f"{opts.config_file}")
        return 1

    for iface_json in iface_array:
        if iface_json.get('type') != 'route_table':
            iface_json.update({'nic_mapping': iface_mapping})
            iface_json.update({'persist_mapping': persist_mapping})

    validation_errors = validator.validate_config(iface_array)
    if validation_errors:
        if opts.exit_on_validation_errors:
            main_logger.error('\n'.join(validation_errors))
            return 1
        else:
            main_logger.warning('\n'.join(validation_errors))

    # Look for the presence of SriovPF types in the first parse of the json
    # if SriovPFs exists then PF devices needs to be configured so that the VF
    # devices are created.
    # The VFs will not be available now and an exception
    # SriovVfNotFoundException will be raised while fetching the device name.
    # After the first parse the SR-IOV PF devices would be configured and the
    # VF devices would be created.
    # In the second parse, all other objects shall be added
    for iface_json in iface_array:
        try:
            obj = objects.object_from_json(iface_json)
        except utils.SriovVfNotFoundException:
            continue
        if isinstance(obj, objects.SriovPF):
            configure_sriov = True
            provider.add_object(obj)
        elif hasattr(obj, 'members') and obj.members is not None:
            if check_configure_sriov(obj):
                configure_sriov = True
                provider.add_object(obj)

                sriovpf_member_of_bond_ovs_port_list.extend(
                    get_sriovpf_member_of_bond_ovs_port(obj))

    # After reboot, shared_block for pf interface in switchdev mode will be
    # missing in case IPv6 is enabled on the slaves of the bond and that bond
    # is an ovs port. This is due to the fact that OVS assumes another entity
    # manages the slaves.
    # So as a workaround for that case we are disabling IPv6 over pfs so that
    # OVS creates the shared_blocks ingress
    if sriovpf_member_of_bond_ovs_port_list:
        disable_ipv6_for_netdevs(sriovpf_member_of_bond_ovs_port_list)

    if configure_sriov:
        # Apply the ifcfgs for PFs now, so that NM_CONTROLLED=no is applied
        # for each of the PFs before configuring the numvfs for the PF device.
        # This step allows the network manager to unmanage the created VFs.
        # In the second parse, when these ifcfgs for PFs are encountered,
        # os-net-config skips the ifup <ifcfg-pfs>, since the ifcfgs for PFs
        # wouldn't have changed.
        pf_files_changed = provider.apply(cleanup=opts.cleanup,
                                          activate=not opts.no_activate)
        if not opts.noop:
            restart_ovs = bool(sriovpf_member_of_bond_ovs_port_list)
            # Avoid ovs restart for os-net-config re-runs, which will
            # dirupt the offload configuration
            if os.path.exists(utils._SRIOV_CONFIG_SERVICE_FILE):
                restart_ovs = False

            utils.configure_sriov_pfs(
                execution_from_cli=True,
                restart_openvswitch=restart_ovs)

    for iface_json in iface_array:
        # All objects other than the sriov_pf will be added here.
        # The VFs are expected to be available now and an exception
        # SriovVfNotFoundException shall be raised if not available.
        try:
            obj = objects.object_from_json(iface_json)
        except utils.SriovVfNotFoundException:
            if not opts.noop:
                raise
        if not isinstance(obj, objects.SriovPF):
            provider.add_object(obj)

    if configure_sriov and not opts.noop:
        utils.configure_sriov_vfs()

    files_changed = provider.apply(cleanup=opts.cleanup,
                                   activate=not opts.no_activate)
    if opts.noop:
        if configure_sriov:
            files_changed.update(pf_files_changed)
        for location, data in files_changed.items():
            print("File: %s\n" % location)
            print(data)
            print("----")

    if opts.detailed_exit_codes and len(files_changed) > 0:
        return 2

    return 0
Beispiel #18
0
def main(argv=sys.argv):
    opts = parse_opts(argv)
    configure_logger(opts.verbose, opts.debug)
    logger.info('Using config file at: %s' % opts.config_file)
    iface_array = []
    configure_sriov = False

    provider = None
    if opts.provider:
        if opts.provider == 'ifcfg':
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif opts.provider == 'eni':
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        elif opts.provider == 'iproute':
            provider = impl_iproute.IPRouteNetConfig(noop=opts.noop,
                                                     root_dir=opts.root_dir)
        else:
            logger.error('Invalid provider specified.')
            return 1
    else:
        if os.path.exists('%s/etc/sysconfig/network-scripts/' % opts.root_dir):
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif os.path.exists('%s/etc/network/' % opts.root_dir):
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        else:
            logger.error('Unable to set provider for this operating system.')
            return 1

    # Read the interface mapping file, if it exists
    # This allows you to override the default network naming abstraction
    # mappings by specifying a specific nicN->name or nicN->MAC mapping
    if os.path.exists(opts.mapping_file):
        logger.info('Using mapping file at: %s' % opts.mapping_file)
        with open(opts.mapping_file) as cf:
            iface_map = yaml.safe_load(cf.read())
            iface_mapping = iface_map.get("interface_mapping")
            logger.debug('interface_mapping JSON: %s' % str(iface_mapping))
            persist_mapping = opts.persist_mapping
            logger.debug('persist_mapping: %s' % persist_mapping)
    else:
        logger.info('Not using any mapping file.')
        iface_mapping = None
        persist_mapping = False

    # If --interfaces is specified, either return the real name of the
    # interfaces specified, or return the map of all nic abstractions/names.
    if opts.interfaces is not None:
        reported_nics = {}
        mapped_nics = objects.mapped_nics(iface_mapping)
        retval = 0
        if len(opts.interfaces) > 0:
            for requested_nic in opts.interfaces:
                found = False
                # Check to see if requested iface is a mapped NIC name.
                if requested_nic in mapped_nics:
                    reported_nics[requested_nic] = mapped_nics[requested_nic]
                    found = True
                # Check to see if the requested iface is a real NIC name
                if requested_nic in mapped_nics.values():
                    if found is True:  # Name matches alias and real NIC
                        # (return the mapped NIC, but warn of overlap).
                        logger.warning('"%s" overlaps with real NIC name.' %
                                       (requested_nic))
                    else:
                        reported_nics[requested_nic] = requested_nic
                        found = True
                if not found:
                    retval = 1
            if reported_nics:
                logger.debug("Interface mapping requested for interface: "
                             "%s" % reported_nics.keys())
        else:
            logger.debug("Interface mapping requested for all interfaces")
            reported_nics = mapped_nics
        # Return the report on the mapped NICs. If all NICs were found, exit
        # cleanly, otherwise exit with status 1.
        logger.debug("Interface report requested, exiting after report.")
        print(reported_nics)
        return retval

    # Read config file containing network configs to apply
    if os.path.exists(opts.config_file):
        try:
            with open(opts.config_file) as cf:
                iface_array = yaml.safe_load(cf.read()).get("network_config")
                logger.debug('network_config JSON: %s' % str(iface_array))
        except IOError:
            logger.error("Error reading file: %s" % opts.config_file)
            return 1
    else:
        logger.error('No config file exists at: %s' % opts.config_file)
        return 1

    if not isinstance(iface_array, list):
        logger.error('No interfaces defined in config: %s' % opts.config_file)
        return 1

    for iface_json in iface_array:
        if iface_json.get('type') != 'route_table':
            iface_json.update({'nic_mapping': iface_mapping})
            iface_json.update({'persist_mapping': persist_mapping})

    validation_errors = validator.validate_config(iface_array)
    if validation_errors:
        if opts.exit_on_validation_errors:
            logger.error('\n'.join(validation_errors))
            return 1
        else:
            logger.warning('\n'.join(validation_errors))

    # Look for the presence of SriovPF types in the first parse of the json
    # if SriovPFs exists then PF devices needs to be configured so that the VF
    # devices are created.
    # The VFs will not be available now and an exception
    # SriovVfNotFoundException will be raised while fetching the device name.
    # After the first parse the SR-IOV PF devices would be configured and the
    # VF devices would be created.
    # In the second parse, all other objects shall be added
    for iface_json in iface_array:
        try:
            obj = objects.object_from_json(iface_json)
        except utils.SriovVfNotFoundException:
            continue
        if isinstance(obj, objects.SriovPF):
            configure_sriov = True
            provider.add_object(obj)
        elif hasattr(obj, 'members') and obj.members is not None:
            if check_configure_sriov(obj):
                configure_sriov = True
                provider.add_object(obj)

    if configure_sriov:
        # Apply the ifcfgs for PFs now, so that NM_CONTROLLED=no is applied
        # for each of the PFs before configuring the numvfs for the PF device.
        # This step allows the network manager to unmanage the created VFs.
        # In the second parse, when these ifcfgs for PFs are encountered,
        # os-net-config skips the ifup <ifcfg-pfs>, since the ifcfgs for PFs
        # wouldn't have changed.
        pf_files_changed = provider.apply(cleanup=opts.cleanup,
                                          activate=not opts.no_activate)
        if not opts.noop:
            utils.configure_sriov_pfs()

    for iface_json in iface_array:
        # All objects other than the sriov_pf will be added here.
        # The VFs are expected to be available now and an exception
        # SriovVfNotFoundException shall be raised if not available.
        try:
            obj = objects.object_from_json(iface_json)
        except utils.SriovVfNotFoundException:
            if not opts.noop:
                raise
        if not isinstance(obj, objects.SriovPF):
            provider.add_object(obj)

    if configure_sriov and not opts.noop:
        utils.configure_sriov_vfs()

    files_changed = provider.apply(cleanup=opts.cleanup,
                                   activate=not opts.no_activate)
    if opts.noop:
        if configure_sriov:
            files_changed.update(pf_files_changed)
        for location, data in files_changed.items():
            print("File: %s\n" % location)
            print(data)
            print("----")

    if opts.detailed_exit_codes and len(files_changed) > 0:
        return 2

    return 0
Beispiel #19
0
def main(argv=sys.argv):
    opts = parse_opts(argv)
    configure_logger(opts.verbose, opts.debug)
    logger.info('Using config file at: %s' % opts.config_file)
    if opts.mapping_file:
        logger.info('Using mapping file at: %s' % opts.mapping_file)
    iface_array = []

    provider = None
    if opts.provider:
        if opts.provider == 'ifcfg':
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif opts.provider == 'eni':
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        elif opts.provider == 'iproute':
            provider = impl_iproute.IPRouteNetConfig(noop=opts.noop,
                                                     root_dir=opts.root_dir)
        else:
            logger.error('Invalid provider specified.')
            return 1
    else:
        if os.path.exists('%s/etc/sysconfig/network-scripts/' % opts.root_dir):
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif os.path.exists('%s/etc/network/' % opts.root_dir):
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        else:
            logger.error('Unable to set provider for this operating system.')
            return 1

    # Read config file containing network configs to apply
    if os.path.exists(opts.config_file):
        with open(opts.config_file) as cf:
            iface_array = yaml.load(cf.read()).get("network_config")
            logger.debug('network_config JSON: %s' % str(iface_array))
    else:
        logger.error('No config file exists at: %s' % opts.config_file)
        return 1

    if not isinstance(iface_array, list):
        logger.error('No interfaces defined in config: %s' % opts.config_file)
        return 1

    # Read the interface mapping file, if it exists
    # This allows you to override the default network naming abstraction
    # mappings by specifying a specific nicN->name or nicN->MAC mapping
    if os.path.exists(opts.mapping_file):
        with open(opts.mapping_file) as cf:
            iface_map = yaml.load(cf.read())
            iface_mapping = iface_map.get("interface_mapping")
            logger.debug('interface_mapping JSON: %s' % str(iface_mapping))
            persist_mapping = opts.persist_mapping
            logger.debug('persist_mapping: %s' % persist_mapping)
    else:
        iface_mapping = None
        persist_mapping = False

    for iface_json in iface_array:
        iface_json.update({'nic_mapping': iface_mapping})
        iface_json.update({'persist_mapping': persist_mapping})

    validation_errors = validator.validate_config(iface_array)
    if validation_errors:
        if opts.exit_on_validation_errors:
            logger.error('\n'.join(validation_errors))
            return 1
        else:
            logger.warning('\n'.join(validation_errors))

    for iface_json in iface_array:
        obj = objects.object_from_json(iface_json)
        provider.add_object(obj)
    files_changed = provider.apply(cleanup=opts.cleanup,
                                   activate=not opts.no_activate)
    if opts.noop:
        for location, data in files_changed.items():
            print("File: %s\n" % location)
            print(data)
            print("----")

    if opts.detailed_exit_codes and len(files_changed) > 0:
        return 2

    return 0
Beispiel #20
0
 def test_from_json_dhcp(self):
     data = '{"type": "interface", "name": "em1", "use_dhcp": true}'
     interface = objects.object_from_json(json.loads(data))
     self.assertEqual("em1", interface.name)
     self.assertEqual(True, interface.use_dhcp)
Beispiel #21
0
def generate_ifcfg_activate_ports():
    """Generate ifcfg and restart ports.

    :returns: an object of IfcfgNetConfig,
        a list of ivs physical uplinks,
        and a list of ivs internal ports.
    """
    provider = impl_ifcfg.IfcfgNetConfig(noop=True, root_dir='')
    intfs = []
    if os.path.exists(NET_CONF_PATH):
        try:
            json_data = open(NET_CONF_PATH).read()
            intfs = jsonutils.loads(json_data).get("network_config")
        except:
            LOG.error('Fail to load file at: %s' % NET_CONF_PATH)
            return 1
    for intf in intfs:
        obj = objects.object_from_json(intf)
        provider.add_object(obj)

    # store the route on physical nics
    route_dict = {}

    # store the ovs internal port ifcfg
    internal_port_dict = {}
    internal_ports = []

    # store uplink ifcfg
    phy_link_dict = {}
    uplinks = []

    for intf, data in provider.interface_data.iteritems():
        # ivs does not need bond
        if "bond" in intf:
            match = re.search('BOND_IFACES="(.+?)"', data)
            if match:
                uplinks = match.group(1).split()
            continue

        # if route is assigned to physical port
        if ("vlan" not in intf and "ivs" not in intf):
            route_data = provider.route_data.get(intf, '')
            route_path = provider.root_dir + impl_ifcfg.route_config_path(intf)
            route_dict[route_path] = route_data

        intf_path = provider.root_dir + impl_ifcfg.ifcfg_config_path(intf)
        # update data for internal port
        if "TYPE=OVSIntPort" in data:
            # delete all lines starts with OVS_
            d = re.sub("OVS_.*?\n", '', data, flags=re.DOTALL)
            # replace all ovs with ivs
            d = re.sub("ovs", 'ivs', d, flags=re.DOTALL)
            # replace all OVS with IVS
            d = re.sub("OVS", 'IVS', d, flags=re.DOTALL)
            internal_port_dict[intf_path] = d
            internal_ports.append(intf)
        else: # update data for physical port
            phy_link_dict[intf_path] = data

    # make sure noop is turned off for ifdown and ifup
    provider.noop = False

    # write route
    for location, data in route_dict.iteritems():
        provider.write_config(location, data)

    # write internal port config
    for location, data in internal_port_dict.iteritems():
        provider.write_config(location, data)

    # write physical ports config, restart uplinks
    for uplink in uplinks:
        provider.ifdown(uplink)
    for location, data in phy_link_dict.iteritems():
        provider.write_config(location, data)
    for uplink in uplinks:
        provider.ifup(uplink)

    LOG.info("IVS uplinks: %s" % ','.join(uplinks))
    LOG.info("IVS internal_ports %s" % ','.join(internal_ports))
    return provider, uplinks, internal_ports
Beispiel #22
0
 def test_from_json_dhcp(self):
     data = '{"type": "interface", "name": "em1", "use_dhcp": true}'
     interface = objects.object_from_json(json.loads(data))
     self.assertEqual("em1", interface.name)
     self.assertTrue(interface.use_dhcp)
    def apply(self):
        self.configure_logger(self.verbose, self.debug)
        logger.info('Using config: %s' % self.network_config)
        iface_array = []
        configure_sriov = False
        provider = None

        if self.provider:
            if self.provider == 'ifcfg':
                provider = impl_ifcfg.IfcfgNetConfig(noop=self.noop,
                                                     root_dir=self.root_dir)
            elif self.provider == 'eni':
                provider = impl_eni.ENINetConfig(noop=self.noop,
                                                 root_dir=self.root_dir)
            elif self.provider == 'iproute':
                provider = impl_iproute.IPRouteNetConfig(
                    noop=self.noop, root_dir=self.root_dir)
            else:
                logger.error('Invalid provider specified.')
                return 1
        else:
            ifcfg_dir = "/etc/sysconfig/network-scripts/"
            if os.path.exists('%s%s' % (self.root_dir, ifcfg_dir)):
                provider = impl_ifcfg.IfcfgNetConfig(noop=self.noop,
                                                     root_dir=self.root_dir)
            elif os.path.exists('%s/etc/network/' % self.root_dir):
                provider = impl_eni.ENINetConfig(noop=self.noop,
                                                 root_dir=self.root_dir)
            else:
                logger.error('Unable to set provider for this \
                operating system.')
                return 1

        iface_array = self.network_config

        if not isinstance(iface_array, list):
            logger.error('No interfaces defined in config: %s' %
                         self.network_config)
            return 1

        validation_errors = validator.validate_config(iface_array)
        if validation_errors:
            if self.exit_on_validation_errors:
                logger.error('\n'.join(validation_errors))
                return 1
            else:
                logger.warning('\n'.join(validation_errors))

        # Look for the presence of SriovPF types in the first parse of the json
        # if SriovPFs exists then PF devices needs to be configured so that the
        # VF devices are created.
        # The VFs will not be available now and an exception
        # SriovVfNotFoundException will be raised while fetching the device
        # name.
        # After the first parse the SR-IOV PF devices would be configured and
        # the VF devices would be created.
        # In the second parse, all other objects shall be added
        for iface_json in iface_array:
            try:
                obj = objects.object_from_json(iface_json)
            except utils.SriovVfNotFoundException:
                continue
            if isinstance(obj, objects.SriovPF):
                configure_sriov = True
                provider.add_object(obj)
            elif hasattr(obj, 'members') and obj.members is not None:
                if check_configure_sriov(obj):
                    configure_sriov = True
                    provider.add_object(obj)

        if configure_sriov:
            # Apply the ifcfgs for PFs now, so that NM_CONTROLLED=no is applied
            # for each of the PFs before configuring the numvfs for the PF
            # device.
            # This step allows the network manager to unmanage the created VFs.
            # In the second parse, when these ifcfgs for PFs are encountered,
            # os-net-config skips the ifup <ifcfg-pfs>, since the ifcfgs for
            # PFs wouldn't have changed.
            pf_files_changed = provider.apply(cleanup=self.cleanup,
                                              activate=not self.no_activate)
            if not self.noop:
                utils.configure_sriov_pfs()

        for iface_json in iface_array:
            # All objects other than the sriov_pf will be added here.
            # The VFs are expected to be available now and an exception
            # SriovVfNotFoundException shall be raised if not available.
            try:
                obj = objects.object_from_json(iface_json)
            except utils.SriovVfNotFoundException:
                if not self.noop:
                    raise
            if not isinstance(obj, objects.SriovPF):
                provider.add_object(obj)

        if configure_sriov and not self.noop:
            utils.configure_sriov_vfs()

        files_changed = provider.apply(cleanup=self.cleanup,
                                       activate=not self.no_activate)

        logger.info("files_changed: %s" %
                    [k for k, v in files_changed.items()])

        if self.noop:
            if configure_sriov:
                files_changed.update(pf_files_changed)
            for location, data in files_changed.items():
                print("File: %s\n" % location)
                print(data)
                print("----")

        if self.detailed_exit_codes and len(files_changed) > 0:
            return 2

        return 0
Beispiel #24
0
def main(argv=sys.argv):
    opts = parse_opts(argv)
    configure_logger(opts.verbose, opts.debug)
    logger.info('Using config file at: %s' % opts.config_file)
    if opts.mapping_file:
        logger.info('Using mapping file at: %s' % opts.mapping_file)
    iface_array = []

    provider = None
    if opts.provider:
        if opts.provider == 'ifcfg':
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif opts.provider == 'eni':
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        elif opts.provider == 'iproute':
            provider = impl_iproute.IPRouteNetConfig(noop=opts.noop,
                                                     root_dir=opts.root_dir)
        else:
            logger.error('Invalid provider specified.')
            return 1
    else:
        if os.path.exists('%s/etc/sysconfig/network-scripts/' % opts.root_dir):
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif os.path.exists('%s/etc/network/' % opts.root_dir):
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        else:
            logger.error('Unable to set provider for this operating system.')
            return 1

    # Read config file containing network configs to apply
    if os.path.exists(opts.config_file):
        with open(opts.config_file) as cf:
            iface_array = yaml.load(cf.read()).get("network_config")
            logger.debug('network_config JSON: %s' % str(iface_array))
    else:
        logger.error('No config file exists at: %s' % opts.config_file)
        return 1

    if not isinstance(iface_array, list):
        logger.error('No interfaces defined in config: %s' % opts.config_file)
        return 1

    # Read the interface mapping file, if it exists
    # This allows you to override the default network naming abstraction
    # mappings by specifying a specific nicN->name or nicN->MAC mapping
    if os.path.exists(opts.mapping_file):
        with open(opts.mapping_file) as cf:
            iface_map = yaml.load(cf.read())
            iface_mapping = iface_map.get("interface_mapping")
            logger.debug('interface_mapping JSON: %s' % str(iface_mapping))
            persist_mapping = opts.persist_mapping
            logger.debug('persist_mapping: %s' % persist_mapping)
    else:
        iface_mapping = None
        persist_mapping = False

    for iface_json in iface_array:
        iface_json.update({'nic_mapping': iface_mapping})
        iface_json.update({'persist_mapping': persist_mapping})
        obj = objects.object_from_json(iface_json)
        provider.add_object(obj)
    files_changed = provider.apply(cleanup=opts.cleanup,
                                   activate=not opts.no_activate)
    if opts.noop:
        for location, data in files_changed.iteritems():
            print("File: %s\n" % location)
            print(data)
            print("----")

    if opts.detailed_exit_codes and len(files_changed) > 0:
        return 2

    return 0
Beispiel #25
0
def main(argv=sys.argv):
    opts = parse_opts(argv)
    configure_logger(opts.verbose, opts.debug)
    logger.info('Using config file at: %s' % opts.config_file)
    iface_array = []
    configure_sriov = False

    provider = None
    if opts.provider:
        if opts.provider == 'ifcfg':
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif opts.provider == 'eni':
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        elif opts.provider == 'iproute':
            provider = impl_iproute.IPRouteNetConfig(noop=opts.noop,
                                                     root_dir=opts.root_dir)
        else:
            logger.error('Invalid provider specified.')
            return 1
    else:
        if os.path.exists('%s/etc/sysconfig/network-scripts/' % opts.root_dir):
            provider = impl_ifcfg.IfcfgNetConfig(noop=opts.noop,
                                                 root_dir=opts.root_dir)
        elif os.path.exists('%s/etc/network/' % opts.root_dir):
            provider = impl_eni.ENINetConfig(noop=opts.noop,
                                             root_dir=opts.root_dir)
        else:
            logger.error('Unable to set provider for this operating system.')
            return 1

    # Read the interface mapping file, if it exists
    # This allows you to override the default network naming abstraction
    # mappings by specifying a specific nicN->name or nicN->MAC mapping
    if os.path.exists(opts.mapping_file):
        logger.info('Using mapping file at: %s' % opts.mapping_file)
        with open(opts.mapping_file) as cf:
            iface_map = yaml.safe_load(cf.read())
            iface_mapping = iface_map.get("interface_mapping")
            logger.debug('interface_mapping JSON: %s' % str(iface_mapping))
            persist_mapping = opts.persist_mapping
            logger.debug('persist_mapping: %s' % persist_mapping)
    else:
        logger.info('Not using any mapping file.')
        iface_mapping = None
        persist_mapping = False

    # If --interfaces is specified, either return the real name of the
    # interfaces specified, or return the map of all nic abstractions/names.
    if opts.interfaces is not None:
        reported_nics = {}
        mapped_nics = objects.mapped_nics(iface_mapping)
        retval = 0
        if len(opts.interfaces) > 0:
            for requested_nic in opts.interfaces:
                found = False
                # Check to see if requested iface is a mapped NIC name.
                if requested_nic in mapped_nics:
                    reported_nics[requested_nic] = mapped_nics[requested_nic]
                    found = True
                # Check to see if the requested iface is a real NIC name
                if requested_nic in mapped_nics.values():
                    if found is True:  # Name matches alias and real NIC
                        # (return the mapped NIC, but warn of overlap).
                        logger.warning('"%s" overlaps with real NIC name.'
                                       % (requested_nic))
                    else:
                        reported_nics[requested_nic] = requested_nic
                        found = True
                if not found:
                    retval = 1
            if reported_nics:
                logger.debug("Interface mapping requested for interface: "
                             "%s" % reported_nics.keys())
        else:
            logger.debug("Interface mapping requested for all interfaces")
            reported_nics = mapped_nics
        # Return the report on the mapped NICs. If all NICs were found, exit
        # cleanly, otherwise exit with status 1.
        logger.debug("Interface report requested, exiting after report.")
        print(reported_nics)
        return retval

    # Read config file containing network configs to apply
    if os.path.exists(opts.config_file):
        try:
            with open(opts.config_file) as cf:
                iface_array = yaml.safe_load(cf.read()).get("network_config")
                logger.debug('network_config JSON: %s' % str(iface_array))
        except IOError:
            logger.error("Error reading file: %s" % opts.config_file)
            return 1
    else:
        logger.error('No config file exists at: %s' % opts.config_file)
        return 1

    if not isinstance(iface_array, list):
        logger.error('No interfaces defined in config: %s' % opts.config_file)
        return 1

    for iface_json in iface_array:
        if iface_json.get('type') != 'route_table':
            iface_json.update({'nic_mapping': iface_mapping})
            iface_json.update({'persist_mapping': persist_mapping})

    validation_errors = validator.validate_config(iface_array)
    if validation_errors:
        if opts.exit_on_validation_errors:
            logger.error('\n'.join(validation_errors))
            return 1
        else:
            logger.warning('\n'.join(validation_errors))

    # Look for the presence of SriovPF types in the first parse of the json
    # if SriovPFs exists then PF devices needs to be configured so that the VF
    # devices are created.
    # The VFs will not be available now and an exception
    # SriovVfNotFoundException will be raised while fetching the device name.
    # After the first parse the SR-IOV PF devices would be configured and the
    # VF devices would be created.
    # In the second parse, all other objects shall be added
    for iface_json in iface_array:
        try:
            obj = objects.object_from_json(iface_json)
        except utils.SriovVfNotFoundException:
            continue
        if isinstance(obj, objects.SriovPF):
            configure_sriov = True
            provider.add_object(obj)
        elif hasattr(obj, 'members') and obj.members is not None:
            if check_configure_sriov(obj):
                configure_sriov = True
                provider.add_object(obj)

    if configure_sriov:
        # Apply the ifcfgs for PFs now, so that NM_CONTROLLED=no is applied
        # for each of the PFs before configuring the numvfs for the PF device.
        # This step allows the network manager to unmanage the created VFs.
        # In the second parse, when these ifcfgs for PFs are encountered,
        # os-net-config skips the ifup <ifcfg-pfs>, since the ifcfgs for PFs
        # wouldn't have changed.
        pf_files_changed = provider.apply(cleanup=opts.cleanup,
                                          activate=not opts.no_activate)
        if not opts.noop:
            utils.configure_sriov_pfs()

    for iface_json in iface_array:
        # All objects other than the sriov_pf will be added here.
        # The VFs are expected to be available now and an exception
        # SriovVfNotFoundException shall be raised if not available.
        try:
            obj = objects.object_from_json(iface_json)
        except utils.SriovVfNotFoundException:
            if not opts.noop:
                raise
        if not isinstance(obj, objects.SriovPF):
            provider.add_object(obj)

    if configure_sriov and not opts.noop:
        utils.configure_sriov_vfs()

    files_changed = provider.apply(cleanup=opts.cleanup,
                                   activate=not opts.no_activate)
    if opts.noop:
        if configure_sriov:
            files_changed.update(pf_files_changed)
        for location, data in files_changed.items():
            print("File: %s\n" % location)
            print(data)
            print("----")

    if opts.detailed_exit_codes and len(files_changed) > 0:
        return 2

    return 0