def setUpSecurityGroupVnic(macAddr, portId): hooking.log('Setting up vNIC (portId %s) security groups' % portId) brName = devName("qbr", portId) # TODO: Remove this check after bz 1045626 is fixed if not deviceExists(brName): executeOrExit([EXT_BRCTL, 'addbr', brName]) executeOrExit([EXT_BRCTL, 'setfd', brName, '0']) executeOrExit([EXT_BRCTL, 'stp', brName, 'off']) vethBr = devName("qvb", portId) vethOvs = devName("qvo", portId) # TODO: Remove this check after bz 1045626 is fixed if not deviceExists(vethOvs): executeOrExit([EXT_IP, 'link', 'add', vethBr, 'type', 'veth', 'peer', 'name', vethOvs]) for dev in [vethBr, vethOvs]: executeOrExit([EXT_IP, 'link', 'set', dev, 'up']) executeOrExit([EXT_IP, 'link', 'set', dev, 'promisc', 'on']) executeOrExit([EXT_IP, 'link', 'set', brName, 'up']) executeOrExit([EXT_BRCTL, 'addif', brName, vethBr]) executeOrExit([ovs_vsctl.cmd, '--', '--may-exist', 'add-port', INTEGRATION_BRIDGE, vethOvs, '--', 'set', 'Interface', vethOvs, 'external-ids:iface-id=%s' % portId, 'external-ids:iface-status=active', 'external-ids:attached-mac=%s' % macAddr])
def ovs_networks_stats(stats): """ Get OVS networks from RunningConfig and assign them network stats dictionaries from underlying devices. Fake bridges and bonds already have stats with their names. """ ovs_networks_stats = {} running_config = RunningConfig() for network, attrs in running_config.networks.items(): if is_ovs_network(attrs): vlan = attrs.get('vlan') iface = attrs.get('nic') or attrs.get('bonding') if vlan is None: # Untagged networks use OVS bridge as their bridge, but Engine # expects a bridge with 'network-name' name. create a copy of # top underlying device stats and save it as bridge's stats. # NOTE: copy stats of ovsbr0? (now we repots iface's stats) ovs_networks_stats[network] = stats[iface] else: # Engine expects stats entries for vlans named 'iface.id' vlan_name = '%s.%s' % (iface, vlan) ovs_networks_stats[vlan_name] = stats[network] ovs_networks_stats[vlan_name]['name'] = vlan_name hooking.log('Updating network stats with OVS networks: %s' % ovs_networks_stats) return ovs_networks_stats
def configure_ip(nets, init_nets): ip_config_to_set = {} ip_config_to_remove = {} for net, attrs in nets.items(): if net in init_nets: init_attrs = init_nets[net] init_top_dev = net if 'vlan' in init_attrs else BRIDGE_NAME ipv4 = _get_ipv4_model(init_attrs) ipv6 = _get_ipv6_model(init_attrs) ip_config_to_remove[init_top_dev] = ipv4, ipv6 if 'remove' not in attrs: top_dev = net if 'vlan' in attrs else BRIDGE_NAME ipv4 = _get_ipv4_model(attrs) ipv6 = _get_ipv6_model(attrs) port = attrs.get('nic') or attrs.get('bonding') if ipv4 or ipv6: ip_config_to_set[top_dev] = ( ipv4, ipv6, port, 'blockingdhcp' in attrs) hooking.log('Remove IP configuration of: %s' % ip_config_to_remove) hooking.log('Set IP configuration: %s' % ip_config_to_set) for iface, (ipv4, ipv6) in ip_config_to_remove.iteritems(): _remove_ip_config(iface, ipv4, ipv6) for iface, (ipv4, ipv6, blockingdhcp, port) in ip_config_to_set.items(): _set_ip_config(iface, ipv4, ipv6, blockingdhcp, port)
def setUpSecurityGroupVnic(macAddr, portId): hooking.log('Setting up vNIC (portId %s) security groups' % portId) brName = devName("qbr", portId) # TODO: Remove this check after bz 1045626 is fixed if not deviceExists(brName): executeOrExit([EXT_BRCTL, 'addbr', brName]) executeOrExit([EXT_BRCTL, 'setfd', brName, '0']) executeOrExit([EXT_BRCTL, 'stp', brName, 'off']) vethBr = devName("qvb", portId) vethOvs = devName("qvo", portId) # TODO: Remove this check after bz 1045626 is fixed if not deviceExists(vethOvs): executeOrExit([ EXT_IP, 'link', 'add', vethBr, 'type', 'veth', 'peer', 'name', vethOvs ]) for dev in [vethBr, vethOvs]: executeOrExit([EXT_IP, 'link', 'set', dev, 'up']) executeOrExit([EXT_IP, 'link', 'set', dev, 'promisc', 'on']) executeOrExit([EXT_IP, 'link', 'set', brName, 'up']) executeOrExit([EXT_BRCTL, 'addif', brName, vethBr]) executeOrExit([ ovs_vsctl.cmd, '--', '--may-exist', 'add-port', INTEGRATION_BRIDGE, vethOvs, '--', 'set', 'Interface', vethOvs, 'external-ids:iface-id=%s' % portId, 'external-ids:iface-status=active', 'external-ids:attached-mac=%s' % macAddr ])
def _remove_redundant_ovs_bridge(running_config): """ Remove OVS Bridge if there is no OVS net/bond anymore. """ for net, attr in iter_ovs_nets(running_config.networks): return for bond, attr in iter_ovs_bonds(running_config.bonds): return hooking.log('Removing redundant OVS bridge') destroy_ovs_bridge()
def _run_commands(commands): """ If there are any needed changes in OVS network listed in commands, apply them. Otherwise do nothing. """ if commands: commands = [EXT_OVS_VSCTL, '--', '--may-exist', 'add-br', BRIDGE_NAME] + commands hooking.log('Executing commands: %s' % ' '.join(commands)) rc, _, err = hooking.execCmd(commands) if rc != 0: raise Exception('Executing commands failed: %s' % '\n'.join(err))
def increase_devices_boot_order(devices): xmldevices = [e for e in devices.childNodes if e.nodeType == e.ELEMENT_NODE] for d in xmldevices: boots = d.getElementsByTagName("boot") for boot in boots: if boot.hasAttribute("order"): try: boot.setAttribute("order", str(int(boot.getAttribute("order")) + 1)) except ValueError: hooking.log("httpsisoboot: unable to manipulate the boot order: " + d.toxml()) raise
def _get_open_vswitch_hostname(): """ Returns the external_ids:hostname of the table Open_vSwitch from Open vSwitch's database. This value is used by the OpenStack agents of neutron's OVS and OVN plugin to identify the host. """ rc, out, err = _get_ovs_external_id('hostname') if rc == 0: return out[0].decode('utf-8').replace('"', '') hooking.log('Failed to get Open vSwitch hostname. err = %s' % (err)) return None
def configure(nets, bonds, running_config, in_rollback): initial_config = deepcopy(running_config) commands, libvirt_create, libvirt_remove = prepare_ovs( nets, bonds, running_config) with _rollback(running_config, initial_config, in_rollback): configure_ovs(commands, libvirt_create, libvirt_remove, running_config) configure_mtu(running_config) configure_ip(nets, initial_config.networks) hooking.log('Saving running configuration: %s %s' % (running_config.networks, running_config.bonds)) running_config.save()
def _get_open_vswitch_hostname(): """ Returns the external_ids:hostname of the table Open_vSwitch from Open vSwitch's database. This value is used by the OpenStack agents of neutron's OVS and OVN plugin to identify the host. """ rc, out, err = _get_ovs_external_id('hostname') if rc == 0: return out[0].replace('"', '') if _is_ovs_service_running(): hooking.log('Failed to get Open vSwitch hostname. err = %s' % (err)) return None
def main(): """ Create lists of running networks and networks to be (un)configured as FCoE or removed. """ existing_fcoe_networks = _all_configured_fcoe_networks() changed_fcoe = {} changed_non_fcoe = {} removed_networks = {} custom_parameters = {} setup_nets_config = hooking.read_json() changed_all = setup_nets_config['request']['networks'] for net, net_attr in six.iteritems(changed_all): custom_parameters_string = net_attr.get('custom', {}).get('fcoe', '') custom_parameters[net] = _parse_custom(custom_parameters_string) if _has_fcoe(net_attr): changed_fcoe[net] = net_attr.get('nic') elif hooking.tobool(net_attr.get('remove')): removed_networks[net] = net_attr.get('nic') else: changed_non_fcoe[net] = net_attr.get('nic') removed_service_restart_required = _unconfigure_removed( existing_fcoe_networks, removed_networks ) non_fcoe_service_restart_required = _unconfigure_non_fcoe( existing_fcoe_networks, changed_non_fcoe ) reconfigure_service_restart_required = _reconfigure_fcoe( existing_fcoe_networks, changed_fcoe, custom_parameters ) if ( removed_service_restart_required or non_fcoe_service_restart_required or reconfigure_service_restart_required ): # TODO If services are failed to start restore previous configuration # and notify user ret, _, err = hooking.execCmd(['/bin/systemctl', 'restart', 'lldpad']) if ret: hooking.log('Failed to restart lldpad service. err = %s' % (err)) ret, _, err = hooking.execCmd(['/bin/systemctl', 'restart', 'fcoe']) if ret: hooking.log('Failed to restart fcoe service. err = %s' % (err))
def increase_devices_boot_order(devices): xmldevices = [ e for e in devices.childNodes if e.nodeType == e.ELEMENT_NODE ] for d in xmldevices: boots = d.getElementsByTagName('boot') for boot in boots: if boot.hasAttribute('order'): try: boot.setAttribute('order', str(int(boot.getAttribute('order')) + 1)) except ValueError: hooking.log( 'httpsisoboot: unable to manipulate the boot order: ' + d.toxml()) raise
def _all_configured_fcoe_networks(): """ Return a mapping of configured fcoe networks in format (network_name, nic_name) """ existing_fcoe_networks = {} config = RunningConfig() for net, net_attr in six.iteritems(config.networks): if _has_fcoe(net_attr): nic = net_attr.get('nic') if nic: existing_fcoe_networks[net] = nic else: hooking.log("WARNING: Invalid FCoE configuration of %s " "detected. Please check documentation" % (net)) return existing_fcoe_networks
def _process_network(network, attrs): """Applies ethtool_options to the network if necessary""" options = attrs['custom'].get('ethtool_opts') if options is not None: nics = _net_nics(attrs) for subcmd in _parse_into_subcommands(options.split()): if subcmd.device == ALL_SLAVES: expanded_nics = nics else: _validate_dev_ownership(nics, network, subcmd) expanded_nics = (subcmd.device,) for nic in expanded_nics: try: _set_ethtool_opts(network, [subcmd.name, nic] + subcmd.flags) except EthtoolError as ee: hooking.log(ee.message)
def _process_network(network, attrs): """Applies ethtool_options to the network if necessary""" options = attrs['custom'].get('ethtool_opts') if options is not None: nics = _net_nics(attrs) for subcmd in _parse_into_subcommands(options.split()): if subcmd.device == ALL_SLAVES: expanded_nics = nics else: _validate_dev_ownership(nics, network, subcmd) expanded_nics = (subcmd.device, ) for nic in expanded_nics: try: _set_ethtool_opts(network, [subcmd.name, nic] + subcmd.flags) except EthtoolError as ee: hooking.log(str(ee))
def main(): setup_nets_config = hooking.read_json() hooking.log('Hook started, handling: %s' % setup_nets_config) running_config = RunningConfig() networks = setup_nets_config['request']['networks'] bondings = setup_nets_config['request']['bondings'] inRollback = setup_nets_config['request']['options'].get('_inRollback', False) ovs_nets, non_ovs_nets, ovs_bonds, non_ovs_bonds = \ _separate_ovs_nets_bonds(networks, bondings, running_config) configure(ovs_nets, ovs_bonds, running_config, inRollback) setup_nets_config['request']['bondings'] = non_ovs_bonds setup_nets_config['request']['networks'] = non_ovs_nets hooking.log('Hook finished, returning non-OVS networks and bondings back ' 'to VDSM: %s' % setup_nets_config) hooking.write_json(setup_nets_config)
def main(): """ Create lists of running networks and networks to be (un)configured as FCoE or removed. """ existing_fcoe_networks = _all_configured_fcoe_networks() changed_fcoe = {} changed_non_fcoe = {} removed_networks = {} custom_parameters = {} setup_nets_config = hooking.read_json() changed_all = setup_nets_config['request']['networks'] for net, net_attr in six.iteritems(changed_all): custom_parameters_string = net_attr.get('custom', {}).get('fcoe', '') custom_parameters[net] = _parse_custom(custom_parameters_string) if _has_fcoe(net_attr): changed_fcoe[net] = net_attr.get('nic') elif hooking.tobool(net_attr.get('remove')): removed_networks[net] = net_attr.get('nic') else: changed_non_fcoe[net] = net_attr.get('nic') _unconfigure_removed(existing_fcoe_networks, removed_networks) _unconfigure_non_fcoe(existing_fcoe_networks, changed_non_fcoe) _reconfigure_fcoe(existing_fcoe_networks, changed_fcoe, custom_parameters) # TODO If services are failed to start restore previous configuration # and notify user ret, _, err = hooking.execCmd(['/bin/systemctl', 'restart', 'lldpad']) if ret: hooking.log('Failed to restart lldpad service. err = %s' % (err)) ret, _, err = hooking.execCmd(['/bin/systemctl', 'restart', 'fcoe']) if ret: hooking.log('Failed to restart fcoe service. err = %s' % (err))
def _rollback(running_config, initial_config, in_rollback): try: yield except: if in_rollback: hooking.log('Failed while trying to rollback:') else: hooking.log('Configuration failed. Entering rollback.') rollback(running_config, initial_config) hooking.log('Rollback finished. Initial error:') raise
def _run_dhclient(iface, blockingdhcp, default_route, family): dhclient = DhcpClient(iface, family, default_route) rc = dhclient.start(blockingdhcp) if blockingdhcp and rc: hooking.log('failed to start dhclient%s on iface %s' % (family, iface))
def log(message, tag="OVS: "): hooking.log("%s%s" % (tag, message))
def allocate_random_network(interface): net = _get_random_network() _change_assigned_network(interface, net) hooking.log('allocating random network: %s' % (net,))
def log(message, tag='OVS: '): hooking.log('%s%s' % (tag, message))
def allocate_random_network(interface): net = _get_random_network() _change_assigned_network(interface, net) hooking.log('allocating random network: %s' % (net, ))