diff options
Diffstat (limited to 'os_net_config/impl_ifcfg.py')
-rw-r--r-- | os_net_config/impl_ifcfg.py | 178 |
1 files changed, 159 insertions, 19 deletions
diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py index 70f5065..0fe6ae1 100644 --- a/os_net_config/impl_ifcfg.py +++ b/os_net_config/impl_ifcfg.py @@ -35,10 +35,18 @@ def bridge_config_path(name): return ifcfg_config_path(name) +def ivs_config_path(): + return "/etc/sysconfig/ivs" + + def route_config_path(name): return "/etc/sysconfig/network-scripts/route-%s" % name +def route6_config_path(name): + return "/etc/sysconfig/network-scripts/route6-%s" % name + + def cleanup_pattern(): return "/etc/sysconfig/network-scripts/ifcfg-*" @@ -49,7 +57,9 @@ class IfcfgNetConfig(os_net_config.NetConfig): def __init__(self, noop=False, root_dir=''): super(IfcfgNetConfig, self).__init__(noop, root_dir) self.interface_data = {} + self.ivsinterface_data = {} self.route_data = {} + self.route6_data = {} self.bridge_data = {} self.linuxbridge_data = {} self.linuxbond_data = {} @@ -84,8 +94,16 @@ class IfcfgNetConfig(os_net_config.NetConfig): data += "VLAN=yes\n" if base_opt.device: data += "PHYSDEV=%s\n" % base_opt.device + else: + if base_opt.linux_bond_name: + data += "PHYSDEV=%s\n" % base_opt.linux_bond_name + elif isinstance(base_opt, objects.IvsInterface): + data += "TYPE=IVSIntPort\n" elif re.match('\w+\.\d+$', base_opt.name): data += "VLAN=yes\n" + if base_opt.ivs_bridge_name: + data += "DEVICETYPE=ivs\n" + data += "IVS_BRIDGE=%s\n" % base_opt.ivs_bridge_name if base_opt.ovs_port: data += "DEVICETYPE=ovs\n" if base_opt.bridge_name: @@ -153,7 +171,8 @@ class IfcfgNetConfig(os_net_config.NetConfig): members = [member.name for member in base_opt.members] self.member_names[base_opt.name] = members for member in members: - self.bond_slaves[member] = base_opt.name + if isinstance(member, objects.Interface): + self.bond_slaves[member] = base_opt.name if base_opt.bonding_options: data += "BONDING_OPTS=\"%s\"\n" % base_opt.bonding_options else: @@ -164,11 +183,11 @@ class IfcfgNetConfig(os_net_config.NetConfig): data += "BOOTPROTO=dhcp\n" elif not base_opt.addresses: data += "BOOTPROTO=none\n" - if base_opt.mtu != 1500: + if base_opt.mtu: data += "MTU=%i\n" % base_opt.mtu if base_opt.use_dhcpv6 or base_opt.v6_addresses(): data += "IPV6INIT=yes\n" - if base_opt.mtu != 1500: + if base_opt.mtu: data += "IPV6_MTU=%i\n" % base_opt.mtu if base_opt.use_dhcpv6: data += "DHCPV6C=yes\n" @@ -211,16 +230,31 @@ class IfcfgNetConfig(os_net_config.NetConfig): logger.info('adding custom route for interface: %s' % interface_name) data = "" first_line = "" + data6 = "" + first_line6 = "" for route in routes: - if route.default: - first_line = "default via %s dev %s\n" % (route.next_hop, - interface_name) + if ":" not in route.next_hop: + # Route is an IPv4 route + if route.default: + first_line = "default via %s dev %s\n" % (route.next_hop, + interface_name) + else: + data += "%s via %s dev %s\n" % (route.ip_netmask, + route.next_hop, + interface_name) else: - data += "%s via %s dev %s\n" % (route.ip_netmask, - route.next_hop, - interface_name) + # Route is an IPv6 route + if route.default: + first_line6 = "default via %s dev %s\n" % (route.next_hop, + interface_name) + else: + data6 += "%s via %s dev %s\n" % (route.ip_netmask, + route.next_hop, + interface_name) self.route_data[interface_name] = first_line + data + self.route6_data[interface_name] = first_line6 + data6 logger.debug('route data: %s' % self.route_data[interface_name]) + logger.debug('ipv6 route data: %s' % self.route6_data[interface_name]) def add_interface(self, interface): """Add an Interface object to the net config object. @@ -251,6 +285,18 @@ class IfcfgNetConfig(os_net_config.NetConfig): if vlan.routes: self._add_routes(vlan.name, vlan.routes) + def add_ivs_interface(self, ivs_interface): + """Add a ivs_interface object to the net config object. + + :param ivs_interface: The ivs_interface object to add. + """ + logger.info('adding ivs_interface: %s' % ivs_interface.name) + data = self._add_common(ivs_interface) + logger.debug('ivs_interface data: %s' % data) + self.ivsinterface_data[ivs_interface.name] = data + if ivs_interface.routes: + self._add_routes(ivs_interface.name, ivs_interface.routes) + def add_bridge(self, bridge): """Add an OvsBridge object to the net config object. @@ -275,6 +321,18 @@ class IfcfgNetConfig(os_net_config.NetConfig): if bridge.routes: self._add_routes(bridge.name, bridge.routes) + def add_ivs_bridge(self, bridge): + """Add a IvsBridge object to the net config object. + + IVS can only support one virtual switch per node, + using "ivs" as its name. As long as the ivs service + is running, the ivs virtual switch will be there. + It is impossible to add multiple ivs virtual switches + per node. + :param bridge: The IvsBridge object to add. + """ + pass + def add_bond(self, bond): """Add an OvsBond object to the net config object. @@ -300,6 +358,26 @@ class IfcfgNetConfig(os_net_config.NetConfig): if bond.routes: self._add_routes(bond.name, bond.routes) + def generate_ivs_config(self, ivs_uplinks, ivs_interfaces): + """Generate configuration content for ivs.""" + + intfs = [] + for intf in ivs_uplinks: + intfs.append(' -u ') + intfs.append(intf) + uplink_str = ''.join(intfs) + + intfs = [] + for intf in ivs_interfaces: + intfs.append(' --internal-port=') + intfs.append(intf) + intf_str = ''.join(intfs) + + data = ("DAEMON_ARGS=\"--hitless --certificate /etc/ivs " + "--inband-vlan 4092%s%s\"" + % (uplink_str, intf_str)) + return data + def apply(self, cleanup=False, activate=True): """Apply the network configuration. @@ -320,62 +398,106 @@ class IfcfgNetConfig(os_net_config.NetConfig): restart_bridges = [] update_files = {} all_file_names = [] + ivs_uplinks = [] # ivs physical uplinks + ivs_interfaces = [] # ivs internal ports for interface_name, iface_data in self.interface_data.iteritems(): route_data = self.route_data.get(interface_name, '') + route6_data = self.route6_data.get(interface_name, '') interface_path = self.root_dir + ifcfg_config_path(interface_name) route_path = self.root_dir + route_config_path(interface_name) + route6_path = self.root_dir + route6_config_path(interface_name) all_file_names.append(interface_path) all_file_names.append(route_path) + if "IVS_BRIDGE" in iface_data: + ivs_uplinks.append(interface_name) + all_file_names.append(route6_path) if (utils.diff(interface_path, iface_data) or - utils.diff(route_path, route_data)): + utils.diff(route_path, route_data) or + utils.diff(route6_path, route6_data)): restart_interfaces.append(interface_name) restart_interfaces.extend(self.child_members(interface_name)) update_files[interface_path] = iface_data update_files[route_path] = route_data + update_files[route6_path] = route6_data + else: logger.info('No changes required for interface: %s' % interface_name) + for interface_name, iface_data in self.ivsinterface_data.iteritems(): + route_data = self.route_data.get(interface_name, '') + interface_path = self.root_dir + ifcfg_config_path(interface_name) + route_path = self.root_dir + route_config_path(interface_name) + all_file_names.append(interface_path) + all_file_names.append(route_path) + ivs_interfaces.append(interface_name) + if (utils.diff(interface_path, iface_data) or + utils.diff(route_path, route_data)): + restart_interfaces.append(interface_name) + restart_interfaces.extend(self.child_members(interface_name)) + update_files[interface_path] = iface_data + update_files[route_path] = route_data + logger.info('No changes required for ivs interface: %s' % + interface_name) + for bridge_name, bridge_data in self.bridge_data.iteritems(): route_data = self.route_data.get(bridge_name, '') + route6_data = self.route6_data.get(bridge_name, '') bridge_path = self.root_dir + bridge_config_path(bridge_name) - bridge_route_path = self.root_dir + route_config_path(bridge_name) + br_route_path = self.root_dir + route_config_path(bridge_name) + br_route6_path = self.root_dir + route6_config_path(bridge_name) all_file_names.append(bridge_path) - all_file_names.append(bridge_route_path) + all_file_names.append(br_route_path) + all_file_names.append(br_route6_path) if (utils.diff(bridge_path, bridge_data) or - utils.diff(bridge_route_path, route_data)): + utils.diff(br_route_path, route_data) or + utils.diff(br_route6_path, route6_data)): restart_bridges.append(bridge_name) restart_interfaces.extend(self.child_members(bridge_name)) update_files[bridge_path] = bridge_data - update_files[bridge_route_path] = route_data + update_files[br_route_path] = route_data + update_files[br_route6_path] = route6_data + else: logger.info('No changes required for bridge: %s' % bridge_name) for bridge_name, bridge_data in self.linuxbridge_data.iteritems(): route_data = self.route_data.get(bridge_name, '') + route6_data = self.route6_data.get(bridge_name, '') bridge_path = self.root_dir + bridge_config_path(bridge_name) - bridge_route_path = self.root_dir + route_config_path(bridge_name) + br_route_path = self.root_dir + route_config_path(bridge_name) + br_route6_path = self.root_dir + route6_config_path(bridge_name) all_file_names.append(bridge_path) - all_file_names.append(bridge_route_path) + all_file_names.append(br_route_path) + all_file_names.append(br_route6_path) if (utils.diff(bridge_path, bridge_data) or - utils.diff(bridge_route_path, route_data)): + utils.diff(br_route_path, route_data) or + utils.diff(br_route6_path, route6_data)): restart_bridges.append(bridge_name) restart_interfaces.extend(self.child_members(bridge_name)) update_files[bridge_path] = bridge_data - update_files[bridge_route_path] = route_data + update_files[br_route_path] = route_data + update_files[br_route6_path] = route6_data + else: logger.info('No changes required for bridge: %s' % bridge_name) for bond_name, bond_data in self.linuxbond_data.iteritems(): route_data = self.route_data.get(bond_name, '') + route6_data = self.route6_data.get(bond_name, '') bond_path = self.root_dir + bridge_config_path(bond_name) bond_route_path = self.root_dir + route_config_path(bond_name) + bond_route6_path = self.root_dir + route6_config_path(bond_name) all_file_names.append(bond_path) all_file_names.append(bond_route_path) + all_file_names.append(bond_route6_path) if (utils.diff(bond_path, bond_data) or - utils.diff(bond_route_path, route_data)): + utils.diff(bond_route_path, route_data) or + utils.diff(bond_route6_path, route6_data)): restart_interfaces.append(bond_name) restart_interfaces.extend(self.child_members(bond_name)) update_files[bond_path] = bond_data update_files[bond_route_path] = route_data + update_files[bond_route6_path] = route6_data + else: logger.info('No changes required for linux bond: %s' % bond_name) @@ -402,6 +524,11 @@ class IfcfgNetConfig(os_net_config.NetConfig): for location, data in update_files.iteritems(): self.write_config(location, data) + if ivs_uplinks or ivs_interfaces: + location = ivs_config_path() + data = self.generate_ivs_config(ivs_uplinks, ivs_interfaces) + self.write_config(location, data) + if activate: for bridge in restart_bridges: self.ifup(bridge, iftype='bridge') @@ -413,4 +540,17 @@ class IfcfgNetConfig(os_net_config.NetConfig): self.ovs_appctl('bond/set-active-slave', bond, self.bond_primary_ifaces[bond]) + if ivs_uplinks or ivs_interfaces: + logger.info("Attach to ivs with " + "uplinks: %s, " + "interfaces: %s" % + (ivs_uplinks, ivs_interfaces)) + for ivs_uplink in ivs_uplinks: + self.ifup(ivs_uplink) + for ivs_interface in ivs_interfaces: + self.ifup(ivs_interface) + msg = "Restart ivs" + self.execute(msg, '/usr/bin/systemctl', + 'restart', 'ivs') + return update_files |