def __init__(self, net_info, inRollback=False): is_unipersistence = config.get('vars', 'net_persistence') == 'unified' super(Ifcfg, self).__init__(ConfigWriter(), net_info, is_unipersistence, inRollback) self.runningConfig = RunningConfig()
def _copy_persistent_over_running_config(): pconfig = PersistentConfig() rconfig = RunningConfig() rconfig.delete() rconfig.networks = pconfig.networks rconfig.bonds = pconfig.bonds rconfig.save()
def __init__(self, inRollback=False): self.unifiedPersistence = \ config.get('vars', 'net_persistence') == 'unified' super(Ifcfg, self).__init__(ConfigWriter(self.unifiedPersistence), inRollback) if self.unifiedPersistence: self.runningConfig = RunningConfig()
def generate_state(networks, bondings): """ Generate a new nmstate state given VDSM setup state format """ rconfig = RunningConfig() current_ifaces_state = get_interfaces(state_show()) ovs_nets, linux_br_nets = split_switch_type(networks, rconfig.networks) ovs_bonds, linux_br_bonds = split_switch_type(bondings, rconfig.bonds) ovs_requested = ovs_nets or ovs_bonds linux_br_requested = linux_br_nets or linux_br_bonds bond_ifstates = Bond.generate_state(bondings, rconfig.bonds) if ovs_requested: net_ifstates, routes_state, dns_state = ovs_generate_state( networks, rconfig.networks, current_ifaces_state ) else: net_ifstates, routes_state, dns_state = LinuxBrNet.generate_state( networks, rconfig.networks, current_ifaces_state ) ifstates = _merge_bond_and_net_ifaces_states(bond_ifstates, net_ifstates) if linux_br_requested: _set_vlans_base_mtu(ifstates, current_ifaces_state) _set_bond_slaves_mtu(ifstates, current_ifaces_state) return _merge_state(ifstates, routes_state, dns_state)
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. Note, that it takes some time for a new device to appear in stats, so we first check if the device we got from running_config is already reported. """ ovs_networks_stats = {} running_config = RunningConfig() for network, attrs in six.iteritems(running_config.networks): if is_ovs_network(attrs): vlan = attrs.get('vlan') iface = attrs.get('nic') or attrs.get('bonding') if vlan is None and iface in stats: # 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] ovs_networks_stats[network]['name'] = network elif network in stats: # 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 return ovs_networks_stats
def main(): setup_nets_config = hooking.read_json() log('Hook started, handling: %s' % setup_nets_config) running_config = RunningConfig() networks = setup_nets_config['request']['networks'] bondings = setup_nets_config['request']['bondings'] in_ovs_rollback = setup_nets_config['request']['options'].get( '_inOVSRollback') if in_ovs_rollback: log('OVS rollback is to be done.') _rollback(running_config) _set_nets_bonds(setup_nets_config['request'], {}, {}) log('OVS rollback finished, returning empty networks and bondings ' 'configuration back to VDSM.') else: ovs_nets, non_ovs_nets, ovs_bonds, non_ovs_bonds = \ _separate_ovs_nets_bonds(networks, bondings, running_config) if ovs_nets or ovs_bonds: _configure(ovs_nets, ovs_bonds, running_config) _set_nets_bonds(setup_nets_config['request'], non_ovs_nets, non_ovs_bonds) log('Hook finished, returning non-OVS networks and bondings back to ' 'VDSM: %s' % setup_nets_config) hooking.write_json(setup_nets_config)
def netinfo(vdsmnets=None, compatibility=None): # TODO: Version requests by engine to ease handling of compatibility. _netinfo = netinfo_get(vdsmnets, compatibility) if _is_ovs_service_running(): try: ovs_netinfo = ovs_info.get_netinfo() except ne.OvsDBConnectionError: _is_ovs_service_running.invalidate() raise running_networks = RunningConfig().networks bridgeless_ovs_nets = [ net for net, attrs in six.iteritems(running_networks) if attrs['switch'] == 'ovs' and not attrs['bridged'] ] ovs_info.fake_bridgeless(ovs_netinfo, _netinfo, bridgeless_ovs_nets) for type, entries in six.iteritems(ovs_netinfo): _netinfo[type].update(entries) _set_bond_type_by_usage(_netinfo) return _netinfo
def _validate_default_route(default_route_nets, no_default_route_nets): for net, attrs in six.iteritems(RunningConfig().networks): if attrs['defaultRoute'] and net not in no_default_route_nets: default_route_nets.add(net) if len(default_route_nets) > 1: raise ne.ConfigNetworkError( ne.ERR_BAD_PARAMS, 'Only a single default route network is allowed.')
def _generate_networks_state(networks, ifstates): rconfig = RunningConfig() for netname, netattrs in six.viewitems(networks): if netattrs.get('remove'): _remove_network(netname, ifstates, rconfig) else: _create_network(ifstates, netattrs)
def main(): running_config = RunningConfig() caps = hooking.read_json() caps['networks'].update(networks_caps(running_config)) caps['bridges'].update(bridges_caps(running_config)) caps['vlans'].update(vlans_caps(running_config)) caps['bondings'].update(bondings_caps(running_config)) _update_expected_ip_info(caps, running_config) hooking.write_json(caps)
def netinfo(vdsmnets=None, compatibility=None): # TODO: Version requests by engine to ease handling of compatibility. running_config = RunningConfig() _netinfo = netinfo_get(vdsmnets, compatibility) if _is_ovs_service_running(): state = nmstate.state_show() nmstate.ovs_netinfo(_netinfo, running_config.networks, state) _set_bond_type_by_usage(_netinfo) return _netinfo
def _clean_running_config_from_removed_nets(self): # Cleanup running config from networks that have been actually # removed but not yet removed from running config. running_config = RunningConfig() nets2remove = (six.viewkeys(running_config.networks) - six.viewkeys(self.runningConfig.networks)) for net in nets2remove: running_config.removeNetwork(net) running_config.save()
def rollback(self): """ returns None when all the nets were successfully rolled back, a vdsm.netoconfpersistence.Config object with the not yet rolled back networks and bonds. """ # self.runningConfig will have all the changes that were applied before # we needed to rollback. return RunningConfig().diffFrom(self.runningConfig)
def net2northbound(network_name): nb_device = network_name # Using RunningConfig avoids the need to require root access. net_attr = RunningConfig().networks.get(network_name) is_legacy = net_attr['switch'] == legacy_switch.SWITCH_TYPE if not net_attr['bridged'] and is_legacy: nb_device = get_net_iface_from_config(network_name, net_attr) return nb_device
def _update_running_config(networks, bonds): """ Recreate RunningConfig so that following setSafeNetworkConfig will persist a valid configuration. """ running_config = RunningConfig() for net, net_attr in six.viewitems(networks): running_config.setNetwork(net, net_attr) for bonding, bonding_attr in six.viewitems(bonds): running_config.setBonding(bonding, bonding_attr) running_config.save()
def transaction(in_rollback, nets, bonds): # FIXME: This and _update_running_config are temporary functions handling # only positive flows. running_config = RunningConfig() try: yield except: raise finally: _update_running_config(nets, bonds, running_config) running_config.save()
def _persist(networks, bondings): runningConfig = RunningConfig() runningConfig.delete() for network, attributes in networks.iteritems(): runningConfig.setNetwork(network, attributes) for bond, attributes in bondings.iteritems(): runningConfig.setBonding(bond, attributes) runningConfig.save() runningConfig.store()
def start(self): if _JSONRPC_ENABLED: requestQueues = config.get('addresses', 'request_queues') requestQueue = requestQueues.split(",")[0] self.vdscli = jsonrpcvdscli.connect(requestQueue, xml_compat=False) else: self.vdscli = vdscli.connect() self.netinfo = self._get_netinfo() if config.get('vars', 'net_persistence') == 'unified': self.config = RunningConfig() else: self.config = None
def _set_bond_type_by_usage(_netinfo): """ Engine uses bond switch type to indicate what switch type implementation the bond belongs to (as each is implemented and managed differently). In both cases, the bond used is a linux bond. Therefore, even though the bond is detected as a 'legacy' one, it is examined against the running config for the switch that uses it and updates its switch type accordingly. """ for bond_name, bond_attrs in six.iteritems(RunningConfig().bonds): if (bond_attrs['switch'] == ovs_switch.SWITCH_TYPE and bond_name in _netinfo['bondings']): _netinfo['bondings'][bond_name]['switch'] = ovs_switch.SWITCH_TYPE
def generate_state(networks, bondings): """ Generate a new nmstate state given VDSM setup state format """ rconfig = RunningConfig() bond_ifstates = Bond.generate_state(bondings, rconfig.bonds) net_ifstates, routes_state, dns_state = Network.generate_state( networks, rconfig.networks) for ifname, ifstate in six.viewitems(bond_ifstates): if ifstate.get(Interface.STATE) != InterfaceState.ABSENT: ifstate.update(net_ifstates.get(ifname, {})) net_ifstates.update(bond_ifstates) return _merge_state(net_ifstates, routes_state, dns_state)
def networks_northbound_ifaces(): rconfig = RunningConfig() ifaces = [] for netname, net_attrs in six.viewitems(rconfig.networks): if net_attrs['bridged']: ifaces.append(netname) else: iface = net_attrs.get('bonding') or net_attrs.get('nic') vlan = net_attrs.get('vlan') if vlan: iface = '.'.join([iface, str(vlan)]) ifaces.append(iface) return ifaces
def _bond_hwaddr_should_be_enforced(bondname): """ Bond MAC address is to be enforced under these conditions: - Bond device exists already. - One of these conditions exists (OR): - Unowned by VDSM (not in running config). - Owned by VDSM and HWADDR is specified in the config. """ bond_dev = bond.Bond(bondname) if bond_dev.exists(): running_bonds = RunningConfig().bonds bondattr = running_bonds.get(bondname) return not bondattr or bondattr.get('hwaddr') return False
def netinfo(vdsmnets=None, compatibility=None): # TODO: Version requests by engine to ease handling of compatibility. running_config = RunningConfig() _netinfo = netinfo_get(vdsmnets, compatibility) ovs_nets, _ = util.split_switch_type(running_config.networks, running_config={}) ovs_bonds = util.split_switch_type(running_config.bonds, running_config={}) if ovs_nets or ovs_bonds: state = nmstate.state_show() nmstate.ovs_netinfo(_netinfo, running_config.networks, state) _set_bond_type_by_usage(_netinfo, running_config.bonds) return _netinfo
def ifaceUsed(iface): """Lightweight implementation of bool(Netinfo.ifaceUsers()) that does not require a NetInfo object.""" if os.path.exists(os.path.join(netinfo.NET_PATH, iface, 'brport')): return True # Is it a port for linkDict in nl_link.iter_links(): if linkDict['name'] == iface and 'master' in linkDict: # Is it a slave return True if linkDict.get('device') == iface and linkDict.get('type') == 'vlan': return True # it backs a VLAN for net_name, net_attr in six.viewitems(RunningConfig().networks): if get_net_iface_from_config(net_name, net_attr) == iface: return True return False
def _upgrade_volatile_running_config(rconfig): """ Relocate the volatile version of running config (if exists) to the persisted version. This procedure is required in order to support upgrades to the new persisted version of running config. """ if not rconfig.config_exists(): volatile_rconfig = RunningConfig(volatile=True) if volatile_rconfig.config_exists(): rconfig.networks = volatile_rconfig.networks rconfig.bonds = volatile_rconfig.bonds rconfig.save() volatile_rconfig.delete()
def setupNetworks(self, networks, bonds, options): try: api.setupNetworks(networks, bonds, options) caps = api.network_caps() self.netinfo = CachingNetInfo(caps) self.config = RunningConfig() except errors.ConfigNetworkError as e: status = e.errCode msg = e.message else: status = SUCCESS msg = '' return status, msg
def _networks_report(vdsmnets, routes, ipaddrs, devices_info): if vdsmnets is None: running_nets = RunningConfig().networks nets_info = networks_base_info(running_nets, routes, ipaddrs) else: nets_info = vdsmnets for network_info in six.itervalues(nets_info): network_info.update(LEGACY_SWITCH) _update_net_southbound_info(network_info, devices_info) report_network_qos(nets_info, devices_info) return nets_info
def generate_state(networks, bondings): """ Generate a new nmstate state given VDSM setup state format """ rconfig = RunningConfig() current_ifaces_state = show_interfaces() bond_ifstates = Bond.generate_state(bondings, rconfig.bonds) net_ifstates, routes_state, dns_state = Network.generate_state( networks, rconfig.networks, current_ifaces_state) ifstates = _merge_bond_and_net_ifaces_states(bond_ifstates, net_ifstates) _set_vlans_base_mtu(ifstates, current_ifaces_state) _set_bond_slaves_mtu(ifstates, current_ifaces_state) return _merge_state(ifstates, routes_state, dns_state)
def _networks_report(vdsmnets, routes, ipaddrs, devices_info): if vdsmnets is None: running_nets = RunningConfig().networks nets_info = networks_base_info(running_nets, routes, ipaddrs) else: nets_info = vdsmnets ifaces = {net_info['iface'] for net_info in six.itervalues(nets_info)} dhcp_info = dhclient.dhcp_info(ifaces) for network_info in six.itervalues(nets_info): network_info.update(dhcp_info[network_info['iface']]) network_info.update(LEGACY_SWITCH) report_network_qos(nets_info, devices_info) return nets_info
def _generate_networks_state(networks, ifstates, route_states): rconfig = RunningConfig() for netname, netattrs in six.viewitems(networks): if _is_remove(netattrs): _remove_network(netname, ifstates, route_states, rconfig) else: network_states = _create_network(netname, netattrs) for ifstate in network_states[Interface.KEY]: ifname = ifstate[Interface.NAME] if ifname in ifstates: ifstates[ifname].update(ifstate) else: ifstates[ifname] = ifstate net_routes_state = network_states[Route.KEY] if net_routes_state: route_states.append(net_routes_state)