Black: Enable string normalization

Signed-off-by: Till Maas <opensource@till.name>
This commit is contained in:
Till Maas 2019-12-12 09:00:05 +01:00
parent 03bb579ce2
commit ca3450dc93
89 changed files with 1916 additions and 1919 deletions

View File

@ -37,7 +37,6 @@ Please follow these steps to have your contribution considered by the maintainer
- Nmstate is written primarily in Python, and its coding style should follow
the best practices of Python coding unless otherwise declared.
- Nmstate uses the [black](https://github.com/python/black) code formatter
(except for string normalization).
- PEP8 is holy.
- Tests are holy.
Production code must be covered by unit tests and/or basic integration tests.
@ -58,7 +57,6 @@ Please follow these steps to have your contribution considered by the maintainer
White space between code stanzas are welcome. They help to create breathing
while reading long code.
However, splitting stanzas into helper functions could be even better.
- Prefer single quotes (') whenever possible.
Ref:
https://www.ovirt.org/develop/developer-guide/vdsm/coding-guidelines/

View File

@ -28,11 +28,11 @@ from .prettystate import PrettyState
__all__ = [
'show',
'apply',
'commit',
'rollback',
'error',
'schema',
'PrettyState',
"show",
"apply",
"commit",
"rollback",
"error",
"schema",
"PrettyState",
]

View File

@ -19,20 +19,20 @@
def get_slaves_from_state(state, default=()):
ports = state.get('bridge', {}).get('port')
ports = state.get("bridge", {}).get("port")
if ports is None:
return default
return [p['name'] for p in ports]
return [p["name"] for p in ports]
def set_bridge_ports_metadata(master_state, slave_state):
_set_common_slaves_metadata(master_state, slave_state)
ports = master_state.get('bridge', {}).get('port', [])
port = next(filter(lambda n: n['name'] == slave_state['name'], ports), {})
slave_state['_brport_options'] = port
ports = master_state.get("bridge", {}).get("port", [])
port = next(filter(lambda n: n["name"] == slave_state["name"], ports), {})
slave_state["_brport_options"] = port
def _set_common_slaves_metadata(master_state, slave_state):
slave_state['_master'] = master_state['name']
slave_state['_master_type'] = master_state['type']
slave_state["_master"] = master_state["name"]
slave_state["_master_type"] = master_state["type"]

View File

@ -52,17 +52,17 @@ def minimal_ethtool(interface):
sockfd = sock.fileno()
ecmd = array.array(
'B', struct.pack('I39s', ETHTOOL_GSET, b'\x00' * 39)
"B", struct.pack("I39s", ETHTOOL_GSET, b"\x00" * 39)
)
interface = interface.encode('utf-8')
ifreq = struct.pack('16sP', interface, ecmd.buffer_info()[0])
interface = interface.encode("utf-8")
ifreq = struct.pack("16sP", interface, ecmd.buffer_info()[0])
fcntl.ioctl(sockfd, SIOCETHTOOL, ifreq)
# pylint: disable=no-member
res = ecmd.tobytes() if hasattr(ecmd, 'tobytes') else ecmd.tostring()
res = ecmd.tobytes() if hasattr(ecmd, "tobytes") else ecmd.tostring()
# pylint: enable=no-member
speed, duplex, auto = struct.unpack('12xHB3xB24x', res)
speed, duplex, auto = struct.unpack("12xHB3xB24x", res)
except IOError:
speed, duplex, auto = 65535, 255, 255
finally:
@ -72,9 +72,9 @@ def minimal_ethtool(interface):
speed = 0
if duplex == 255:
duplex = 'unknown'
duplex = "unknown"
else:
duplex = 'full' if bool(duplex) else 'half'
duplex = "full" if bool(duplex) else "half"
if auto == 255:
auto = None

View File

@ -20,7 +20,7 @@
import ipaddress
from libnmstate.error import NmstateValueError
_IPV6_LINK_LOCAL_NETWORK_PREFIXES = ['fe8', 'fe9', 'fea', 'feb']
_IPV6_LINK_LOCAL_NETWORK_PREFIXES = ["fe8", "fe9", "fea", "feb"]
_IPV6_LINK_LOCAL_NETWORK_PREFIX_LENGTH = 10
KERNEL_MAIN_ROUTE_TABLE_ID = 254
@ -35,12 +35,12 @@ def is_ipv6_link_local_addr(ip, prefix):
def is_ipv6_address(addr):
return ':' in addr
return ":" in addr
def to_ip_address_full(ip, prefix=None):
if prefix:
return f'{ip}/{prefix}'
return f"{ip}/{prefix}"
else:
return to_ip_address_full(*ip_address_full_to_tuple(ip))
@ -49,6 +49,6 @@ def ip_address_full_to_tuple(addr):
try:
net = ipaddress.ip_network(addr)
except (ipaddress.AddressValueError, ipaddress.NetmaskValueError) as err:
raise NmstateValueError(f'Invalid IP address, error: {err}')
raise NmstateValueError(f"Invalid IP address, error: {err}")
return f'{net.network_address}', net.prefixlen
return f"{net.network_address}", net.prefixlen

View File

@ -27,13 +27,13 @@ from libnmstate.schema import InterfaceIP
from libnmstate.schema import InterfaceState
BRPORT_OPTIONS = '_brport_options'
MASTER = '_master'
MASTER_TYPE = '_master_type'
ROUTES = '_routes'
DNS_METADATA = '_dns'
DNS_METADATA_PRIORITY = '_priority'
ROUTE_RULES_METADATA = '_route_rules'
BRPORT_OPTIONS = "_brport_options"
MASTER = "_master"
MASTER_TYPE = "_master_type"
ROUTES = "_routes"
DNS_METADATA = "_dns"
DNS_METADATA_PRIORITY = "_priority"
ROUTE_RULES_METADATA = "_route_rules"
def generate_ifaces_metadata(desired_state, current_state):
@ -52,21 +52,21 @@ def generate_ifaces_metadata(desired_state, current_state):
_generate_link_master_metadata(
desired_state.interfaces,
current_state.interfaces,
master_type='bond',
master_type="bond",
get_slaves_func=_get_bond_slaves_from_state,
set_metadata_func=_set_common_slaves_metadata,
)
_generate_link_master_metadata(
desired_state.interfaces,
current_state.interfaces,
master_type='ovs-bridge',
master_type="ovs-bridge",
get_slaves_func=_get_ovs_slaves_from_state,
set_metadata_func=_set_ovs_bridge_ports_metadata,
)
_generate_link_master_metadata(
desired_state.interfaces,
current_state.interfaces,
master_type='linux-bridge',
master_type="linux-bridge",
get_slaves_func=linux_bridge.get_slaves_from_state,
set_metadata_func=linux_bridge.set_bridge_ports_metadata,
)
@ -89,27 +89,27 @@ def remove_ifaces_metadata(ifaces_state):
def _get_bond_slaves_from_state(iface_state, default=()):
return iface_state.get('link-aggregation', {}).get('slaves', default)
return iface_state.get("link-aggregation", {}).get("slaves", default)
def _set_ovs_bridge_ports_metadata(master_state, slave_state):
_set_common_slaves_metadata(master_state, slave_state)
ports = master_state.get('bridge', {}).get('port', [])
port = next(filter(lambda n: n['name'] == slave_state['name'], ports), {})
ports = master_state.get("bridge", {}).get("port", [])
port = next(filter(lambda n: n["name"] == slave_state["name"], ports), {})
slave_state[BRPORT_OPTIONS] = port
def _set_common_slaves_metadata(master_state, slave_state):
slave_state[MASTER] = master_state['name']
slave_state[MASTER_TYPE] = master_state.get('type')
slave_state[MASTER] = master_state["name"]
slave_state[MASTER_TYPE] = master_state.get("type")
def _get_ovs_slaves_from_state(iface_state, default=()):
ports = iface_state.get('bridge', {}).get('port')
ports = iface_state.get("bridge", {}).get("port")
if ports is None:
return default
return [p['name'] for p in ports]
return [p["name"] for p in ports]
def _generate_link_master_metadata(
@ -132,8 +132,8 @@ def _generate_link_master_metadata(
desired_masters = [
(ifname, ifstate)
for ifname, ifstate in ifaces_desired_state.items()
if ifstate.get('type') == master_type
and ifstate.get('state') not in ('down', 'absent')
if ifstate.get("type") == master_type
and ifstate.get("state") not in ("down", "absent")
]
for master_name, master_state in desired_masters:
desired_slaves = get_slaves_func(master_state)
@ -142,8 +142,8 @@ def _generate_link_master_metadata(
set_metadata_func(master_state, ifaces_desired_state[slave])
elif slave in ifaces_current_state:
ifaces_desired_state[slave] = {
'name': slave,
'state': master_state['state'],
"name": slave,
"state": master_state["state"],
}
set_metadata_func(master_state, ifaces_desired_state[slave])
@ -155,19 +155,19 @@ def _generate_link_master_metadata(
slaves2remove = set(current_slaves) - set(desired_slaves)
for slave in slaves2remove:
if slave not in ifaces_desired_state:
ifaces_desired_state[slave] = {'name': slave}
ifaces_desired_state[slave] = {"name": slave}
current_masters = (
(ifname, ifstate)
for ifname, ifstate in ifaces_current_state.items()
if ifstate.get('type') == master_type
if ifstate.get("type") == master_type
)
for master_name, master_state in current_masters:
current_slaves = get_slaves_func(master_state)
for slave in current_slaves:
if slave in ifaces_desired_state:
iface_state = ifaces_desired_state.get(master_name, {})
if iface_state.get('state') not in ('down', 'absent'):
if iface_state.get("state") not in ("down", "absent"):
master_has_no_slaves_specified_in_desired = (
get_slaves_func(iface_state, None) is None
)
@ -265,8 +265,8 @@ def _save_dns_metadata(
family = Interface.IPV4
if not iface_name:
raise NmstateValueError(
'Failed to find suitable interface for saving DNS '
'name servers: %s' % server
"Failed to find suitable interface for saving DNS "
"name servers: %s" % server
)
_include_name_only_iface_state(
@ -391,8 +391,8 @@ def _generate_route_rule_per_stack_metadata(
iface_name = _find_iface_for_route_table(routes, route_table)
if not iface_name:
raise NmstateValueError(
'Failed to find suitable interface for saving route rule: '
'{}'.format(rules[0])
"Failed to find suitable interface for saving route rule: "
"{}".format(rules[0])
)
iface_state = desired_state.interfaces[iface_name]
_attach_route_rule_metadata(iface_state, rules, family)

View File

@ -154,9 +154,9 @@ def _apply_ifaces_state(
if not commit:
return checkpoint
except nm.checkpoint.NMCheckPointPermissionError:
raise NmstatePermissionError('Error creating a check point')
raise NmstatePermissionError("Error creating a check point")
except nm.checkpoint.NMCheckPointCreationError:
raise NmstateConflictError('Error creating a check point')
raise NmstateConflictError("Error creating a check point")
except NmstateError:
# Assume rollback occured, revert IPv6 stack state.
# Checkpoint rollback is async, there is a need to wait for it to
@ -211,14 +211,14 @@ def _setup_providers():
if not success:
nmclient.mainloop(refresh=True)
raise NmstateLibnmError(
'Unexpected failure of libnm when running the mainloop: {}'.format(
"Unexpected failure of libnm when running the mainloop: {}".format(
mainloop.error
)
)
def _add_interfaces(new_interfaces, desired_state):
logging.debug('Adding new interfaces: %s', new_interfaces)
logging.debug("Adding new interfaces: %s", new_interfaces)
ifaces2add = [desired_state.interfaces[name] for name in new_interfaces]
@ -230,13 +230,13 @@ def _add_interfaces(new_interfaces, desired_state):
def _edit_interfaces(state2edit):
logging.debug('Editing interfaces: %s', list(state2edit.interfaces))
logging.debug("Editing interfaces: %s", list(state2edit.interfaces))
ifaces2edit = list(state2edit.interfaces.values())
iface2prepare = list(
filter(
lambda state: state.get('state') not in ('absent', 'down'),
lambda state: state.get("state") not in ("absent", "down"),
ifaces2edit,
)
)
@ -250,7 +250,7 @@ def _edit_interfaces(state2edit):
def _index_by_name(ifaces_state):
return {iface['name']: iface for iface in ifaces_state}
return {iface["name"]: iface for iface in ifaces_state}
def _disable_ipv6(desired_state):
@ -264,5 +264,5 @@ def _disable_ipv6(desired_state):
if ifstate.get(schema.Interface.STATE) != schema.InterfaceState.UP:
continue
ipv6_state = ifstate.get(schema.Interface.IPV6, {})
if ipv6_state.get('enabled') is False:
if ipv6_state.get("enabled") is False:
sysctl.disable_ipv6(ifstate[schema.Interface.NAME])

View File

@ -42,7 +42,7 @@ def show(include_status_data=False):
report = {Constants.INTERFACES: interfaces()}
if include_status_data:
report['capabilities'] = capabilities()
report["capabilities"] = capabilities()
report[Constants.ROUTES] = {
Route.RUNNING: (
@ -92,13 +92,13 @@ def interfaces():
]
for dev, devinfo in devices_info:
type_id = devinfo['type_id']
type_id = devinfo["type_id"]
iface_info = nm.translator.Nm2Api.get_common_device_info(devinfo)
act_con = nm.connection.get_device_active_connection(dev)
iface_info['ipv4'] = nm.ipv4.get_info(act_con)
iface_info['ipv6'] = nm.ipv6.get_info(act_con)
iface_info["ipv4"] = nm.ipv4.get_info(act_con)
iface_info["ipv6"] = nm.ipv6.get_info(act_con)
iface_info.update(nm.wired.get_info(dev))
iface_info.update(nm.user.get_info(dev))
iface_info.update(nm.vlan.get_info(dev))
@ -110,14 +110,14 @@ def interfaces():
iface_info.update(_ifaceinfo_bond(bondinfo))
elif nm.ovs.has_ovs_capability():
if nm.ovs.is_ovs_bridge_type_id(type_id):
iface_info['bridge'] = nm.ovs.get_ovs_info(dev, devices_info)
iface_info["bridge"] = nm.ovs.get_ovs_info(dev, devices_info)
iface_info = _remove_ovs_bridge_unsupported_entries(iface_info)
elif nm.ovs.is_ovs_port_type_id(type_id):
continue
info.append(iface_info)
info.sort(key=itemgetter('name'))
info.sort(key=itemgetter("name"))
return info
@ -125,7 +125,7 @@ def interfaces():
def _ifaceinfo_bond(devinfo):
# TODO: What about unmanaged devices?
bondinfo = nm.translator.Nm2Api.get_bond_info(devinfo)
if 'link-aggregation' in bondinfo:
if "link-aggregation" in bondinfo:
return bondinfo
return {}

View File

@ -26,7 +26,7 @@ from .nmclient import GLib
from .nmclient import NM
NM_MANAGER_ERROR_DOMAIN = 'nm-manager-error-quark'
NM_MANAGER_ERROR_DOMAIN = "nm-manager-error-quark"
class ActivationError(Exception):
@ -88,7 +88,7 @@ class ActiveConnection:
except Exception as e:
if self._mainloop.is_action_canceled(e):
logging.debug(
'Connection deactivation aborted on %s: error=%s',
"Connection deactivation aborted on %s: error=%s",
self._nmdev.get_iface(),
e,
)
@ -102,25 +102,25 @@ class ActiveConnection:
):
success = True
logging.debug(
'Connection is not active on {}, no need to '
'deactivate'.format(self.devname)
"Connection is not active on {}, no need to "
"deactivate".format(self.devname)
)
else:
self._mainloop.quit(
'Connection deactivation failed on {}: '
'error={}'.format(self._nmdev.get_iface(), e)
"Connection deactivation failed on {}: "
"error={}".format(self._nmdev.get_iface(), e)
)
return
if success:
logging.debug(
'Connection deactivation succeeded on %s',
"Connection deactivation succeeded on %s",
self._nmdev.get_iface(),
)
self._mainloop.execute_next_action()
else:
self._mainloop.quit(
'Connection deactivation failed on %s: error=unknown'
"Connection deactivation failed on %s: error=unknown"
% self._nmdev.get_iface()
)

View File

@ -43,11 +43,11 @@ from . import vxlan
from . import wired
MASTER_METADATA = '_master'
MASTER_TYPE_METADATA = '_master_type'
MASTER_METADATA = "_master"
MASTER_TYPE_METADATA = "_master_type"
MASTER_IFACE_TYPES = ovs.BRIDGE_TYPE, bond.BOND_TYPE, LB.TYPE
BRPORT_OPTIONS_METADATA = '_brport_options'
BRPORT_OPTIONS_METADATA = "_brport_options"
def create_new_ifaces(con_profiles):
@ -197,7 +197,7 @@ def set_ifaces_admin_state(ifaces_desired_state, con_profiles=()):
remove_devs_actions[nmdev].append(device.delete_device)
else:
raise NmstateValueError(
'Invalid state {} for interface {}'.format(
"Invalid state {} for interface {}".format(
iface_desired_state[Interface.STATE],
iface_desired_state[Interface.NAME],
)
@ -330,12 +330,12 @@ def prepare_proxy_ifaces_desired_state(ifaces_desired_state):
def _create_ovs_port_iface_desired_state(iface_desired_state, port_options):
return {
'name': ovs.PORT_PROFILE_PREFIX + iface_desired_state[Interface.NAME],
'type': ovs.PORT_TYPE,
'state': iface_desired_state[Interface.STATE],
"name": ovs.PORT_PROFILE_PREFIX + iface_desired_state[Interface.NAME],
"type": ovs.PORT_TYPE,
"state": iface_desired_state[Interface.STATE],
MASTER_METADATA: iface_desired_state[MASTER_METADATA],
MASTER_TYPE_METADATA: iface_desired_state[MASTER_TYPE_METADATA],
'options': port_options,
"options": port_options,
}

View File

@ -22,7 +22,7 @@ from . import nmclient
from libnmstate.error import NmstateValueError
BOND_TYPE = 'bond'
BOND_TYPE = "bond"
def create_setting(options):
@ -31,7 +31,7 @@ def create_setting(options):
success = bond_setting.add_option(option_name, option_value)
if not success:
raise NmstateValueError(
'Invalid bond option: \'{}\'=\'{}\''.format(
"Invalid bond option: '{}'='{}'".format(
option_name, option_value
)
)
@ -47,7 +47,7 @@ def get_bond_info(nm_device):
slaves = get_slaves(nm_device)
options = get_options(nm_device)
if slaves or options:
return {'slaves': slaves, 'options': options}
return {"slaves": slaves, "options": options}
else:
return {}

View File

@ -23,7 +23,7 @@ from libnmstate.nm import nmclient
from libnmstate.schema import LinuxBridge as LB
BRIDGE_TYPE = 'bridge'
BRIDGE_TYPE = "bridge"
def create_setting(options, base_con_profile):

View File

@ -24,13 +24,13 @@ import dbus
import libnmstate.nm.nmclient
DBUS_STD_PROPERTIES_IFNAME = 'org.freedesktop.DBus.Properties'
DBUS_STD_PROPERTIES_IFNAME = "org.freedesktop.DBus.Properties"
CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01
CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02
CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04
NM_PERMISSION_DENIED = 'org.freedesktop.NetworkManager.PermissionDenied'
NM_PERMISSION_DENIED = "org.freedesktop.NetworkManager.PermissionDenied"
_nmdbus_manager = None
@ -62,7 +62,7 @@ def nmdbus_manager():
class _NMDbus:
BUS_NAME = 'org.freedesktop.NetworkManager'
BUS_NAME = "org.freedesktop.NetworkManager"
bus = None
@ -72,8 +72,8 @@ class _NMDbus:
class _NMDbusManager:
IF_NAME = 'org.freedesktop.NetworkManager'
OBJ_PATH = '/org/freedesktop/NetworkManager'
IF_NAME = "org.freedesktop.NetworkManager"
OBJ_PATH = "/org/freedesktop/NetworkManager"
def __init__(self):
mng_proxy = _NMDbus.bus.get_object(
@ -121,7 +121,7 @@ class CheckPoint:
devs, timeout, cp_flags
)
logging.debug(
'Checkpoint %s created for all devices: %s', dbuspath, timeout
"Checkpoint %s created for all devices: %s", dbuspath, timeout
)
self._dbuspath = dbuspath
except dbus.exceptions.DBusException as e:
@ -135,7 +135,7 @@ class CheckPoint:
except dbus.exceptions.DBusException as e:
raise NMCheckPointError(str(e))
logging.debug('Checkpoint %s destroyed', self._dbuspath)
logging.debug("Checkpoint %s destroyed", self._dbuspath)
def rollback(self):
try:
@ -143,7 +143,7 @@ class CheckPoint:
except dbus.exceptions.DBusException as e:
raise NMCheckPointError(str(e))
logging.debug(
'Checkpoint %s rollback executed: %s', self._dbuspath, result
"Checkpoint %s rollback executed: %s", self._dbuspath, result
)
return result

View File

@ -137,7 +137,7 @@ class ConnectionProfile:
elif self.nmdevice:
self.import_by_device()
elif not self.profile:
err_format = 'Missing base properties: profile={}, id={}, dev={}'
err_format = "Missing base properties: profile={}, id={}, dev={}"
err_msg = err_format.format(
self.profile, self.con_id, self.devname
)
@ -151,7 +151,7 @@ class ConnectionProfile:
ac.import_by_device(self.nmdevice)
if ac.is_activating:
logging.debug(
'Connection activation in progress: dev=%s, state=%s',
"Connection activation in progress: dev=%s, state=%s",
ac.devname,
ac.state,
)
@ -188,14 +188,14 @@ class ConnectionProfile:
if self._mainloop.is_action_canceled(e):
logging.debug(
'Connection activation canceled on %s %s: error=%s',
"Connection activation canceled on %s %s: error=%s",
act_type,
act_object,
e,
)
elif self._is_connection_unavailable(e):
logging.warning(
'Connection unavailable on %s %s, retrying',
"Connection unavailable on %s %s, retrying",
act_type,
act_object,
)
@ -204,7 +204,7 @@ class ConnectionProfile:
self.safe_activate_async()
else:
self._mainloop.quit(
'Connection activation failed on {} {}: error={}'.format(
"Connection activation failed on {} {}: error={}".format(
act_type, act_object, e
)
)
@ -213,14 +213,14 @@ class ConnectionProfile:
if nm_act_con is None:
act_type, act_object = self._get_activation_metadata()
self._mainloop.quit(
'Connection activation failed on {} {}: error=unknown'.format(
"Connection activation failed on {} {}: error=unknown".format(
act_type, act_object
)
)
else:
devname = nm_act_con.props.connection.get_interface_name()
logging.debug(
'Connection activation initiated: dev=%s, con-state=%s',
"Connection activation initiated: dev=%s, con-state=%s",
devname,
nm_act_con.props.state,
)
@ -232,7 +232,7 @@ class ConnectionProfile:
self.waitfor_active_connection_async(ac)
else:
self._mainloop.quit(
'Connection activation failed on {}: reason={}'.format(
"Connection activation failed on {}: reason={}".format(
ac.devname, ac.reason
)
)
@ -241,32 +241,32 @@ class ConnectionProfile:
def _is_connection_unavailable(err):
return (
isinstance(err, nmclient.GLib.GError)
and err.domain == 'nm-manager-error-quark'
and err.domain == "nm-manager-error-quark"
and err.code == 2
and 'is not available on the device' in err.message
and "is not available on the device" in err.message
)
def _get_activation_metadata(self):
if self._nmdevice:
activation_type = 'device'
activation_type = "device"
activation_object = self._nmdevice.get_iface()
elif self._con_id:
activation_type = 'connection_id'
activation_type = "connection_id"
activation_object = self._con_id
else:
activation_type = activation_object = 'unknown'
activation_type = activation_object = "unknown"
return activation_type, activation_object
def waitfor_active_connection_async(self, ac):
ac.handlers.add(
ac.nm_active_connection.connect(
'state-changed', self._waitfor_active_connection_callback, ac
"state-changed", self._waitfor_active_connection_callback, ac
)
)
ac.device_handlers.add(
ac.nmdevice.connect(
'state-changed', self._waitfor_device_state_change_callback, ac
"state-changed", self._waitfor_device_state_change_callback, ac
)
)
@ -281,7 +281,7 @@ class ConnectionProfile:
cur_nm_act_conn = get_device_active_connection(self.nmdevice)
if cur_nm_act_conn and cur_nm_act_conn != ac.nm_active_connection:
logging.debug(
'Active connection of device {} has been replaced'.format(
"Active connection of device {} has been replaced".format(
self.devname
)
)
@ -293,8 +293,8 @@ class ConnectionProfile:
self.waitfor_active_connection_async(ac)
if ac.is_active:
logging.debug(
'Connection activation succeeded: dev=%s, con-state=%s, '
'dev-state= %s',
"Connection activation succeeded: dev=%s, con-state=%s, "
"dev-state= %s",
ac.devname,
ac.state,
ac.nmdev_state,
@ -304,7 +304,7 @@ class ConnectionProfile:
elif not ac.is_activating:
ac.remove_handlers()
self._mainloop.quit(
'Connection activation failed on {}: reason={}'.format(
"Connection activation failed on {}: reason={}".format(
ac.devname, ac.reason
)
)
@ -316,16 +316,16 @@ class ConnectionProfile:
con = src_object.add_connection_finish(result)
except Exception as e:
if mainloop.is_action_canceled(e):
logging.debug('Connection adding canceled: error=%s', e)
logging.debug("Connection adding canceled: error=%s", e)
else:
mainloop.quit('Connection adding failed: error={}'.format(e))
mainloop.quit("Connection adding failed: error={}".format(e))
return
if con is None:
mainloop.quit('Connection adding failed: error=unknown')
mainloop.quit("Connection adding failed: error=unknown")
else:
devname = con.get_interface_name()
logging.debug('Connection adding succeeded: dev=%s', devname)
logging.debug("Connection adding succeeded: dev=%s", devname)
mainloop.execute_next_action()
def _delete_connection_callback(self, src_object, result, user_data):
@ -333,17 +333,17 @@ class ConnectionProfile:
success = src_object.delete_finish(result)
except Exception as e:
if self.nmdevice:
target = 'dev/' + str(self.nmdevice.get_iface())
target = "dev/" + str(self.nmdevice.get_iface())
else:
target = 'con/' + str(self.con_id)
target = "con/" + str(self.con_id)
if self._mainloop.is_action_canceled(e):
logging.debug(
'Connection deletion aborted on %s: error=%s', target, e
"Connection deletion aborted on %s: error=%s", target, e
)
else:
self._mainloop.quit(
'Connection deletion failed on {}: error={}'.format(
"Connection deletion failed on {}: error={}".format(
target, e
)
)
@ -351,12 +351,12 @@ class ConnectionProfile:
devname = src_object.get_interface_name()
if success:
logging.debug('Connection deletion succeeded: dev=%s', devname)
logging.debug("Connection deletion succeeded: dev=%s", devname)
self._mainloop.execute_next_action()
else:
self._mainloop.quit(
'Connection deletion failed: '
'dev={}, error=unknown'.format(devname)
"Connection deletion failed: "
"dev={}, error=unknown".format(devname)
)
@staticmethod
@ -366,10 +366,10 @@ class ConnectionProfile:
success = src_object.commit_changes_finish(result)
except Exception as e:
if mainloop.is_action_canceled(e):
logging.debug('Connection update aborted: error=%s', e)
logging.debug("Connection update aborted: error=%s", e)
else:
mainloop.quit(
'Connection update failed: error={}, dev={}/{}'.format(
"Connection update failed: error={}, dev={}/{}".format(
e, nmdev.props.interface, nmdev.props.state
)
)
@ -377,12 +377,12 @@ class ConnectionProfile:
devname = src_object.get_interface_name()
if success:
logging.debug('Connection update succeeded: dev=%s', devname)
logging.debug("Connection update succeeded: dev=%s", devname)
mainloop.execute_next_action()
else:
mainloop.quit(
'Connection update failed: '
'dev={}, error=unknown'.format(devname)
"Connection update failed: "
"dev={}, error=unknown".format(devname)
)
def _reset_profile(self):
@ -405,7 +405,7 @@ class ConnectionSetting:
)
self._setting = con_setting
self._log_connection_info('ConnectionSetting.create')
self._log_connection_info("ConnectionSetting.create")
def import_by_profile(self, con_profile):
base = con_profile.profile.get_setting_connection()
@ -418,7 +418,7 @@ class ConnectionSetting:
new.props.autoconnect_slaves = base.props.autoconnect_slaves
self._setting = new
self._log_connection_info('ConnectionSetting.import_by_profile')
self._log_connection_info("ConnectionSetting.import_by_profile")
def set_master(self, master, slave_type):
if master is not None:
@ -432,15 +432,15 @@ class ConnectionSetting:
def _log_connection_info(self, source):
setting = self._setting
logging.debug(
'Connection settings for %s:\n'
+ '\n'.join(
"Connection settings for %s:\n"
+ "\n".join(
[
'id: %s',
'iface: %s',
'uuid: %s',
'type: %s',
'autoconnect: %s',
'autoconnect_slaves: %s',
"id: %s",
"iface: %s",
"uuid: %s",
"type: %s",
"autoconnect: %s",
"autoconnect_slaves: %s",
]
),
source,

View File

@ -84,7 +84,7 @@ def _wait_for_active_connection_async(dev, connection_profile):
act_conn = ac.ActiveConnection(active_conn)
if act_conn.is_activating:
logging.debug(
'Connection activation in progress: dev=%s, state=%s',
"Connection activation in progress: dev=%s, state=%s",
act_conn.devname,
act_conn.state,
)
@ -103,19 +103,19 @@ def _reapply_callback(src_object, result, user_data):
success = src_object.reapply_finish(result)
except Exception as e:
if mainloop.is_action_canceled(e):
logging.debug('Device reapply aborted on %s: error=%s', devname, e)
logging.debug("Device reapply aborted on %s: error=%s", devname, e)
else:
mainloop.quit(
'Device reapply failed on {}: error={}'.format(devname, e)
"Device reapply failed on {}: error={}".format(devname, e)
)
return
if success:
logging.debug('Device reapply succeeded: dev=%s', devname)
logging.debug("Device reapply succeeded: dev=%s", devname)
mainloop.execute_next_action()
else:
mainloop.quit(
'Device reapply failed: dev={}, error=unknown'.format(devname)
"Device reapply failed: dev={}, error=unknown".format(devname)
)
@ -164,11 +164,11 @@ def _modify_callback(src_object, result, user_data):
success = src_object.reapply_finish(result)
except Exception as e:
if mainloop.is_action_canceled(e):
logging.debug('Device reapply aborted on %s: error=%s', devname, e)
logging.debug("Device reapply aborted on %s: error=%s", devname, e)
else:
logging.debug(
'Device reapply failed on %s: error=%s\n'
'Fallback to device activation',
"Device reapply failed on %s: error=%s\n"
"Fallback to device activation",
devname,
e,
)
@ -176,12 +176,12 @@ def _modify_callback(src_object, result, user_data):
return
if success:
logging.debug('Device reapply succeeded: dev=%s', devname)
logging.debug("Device reapply succeeded: dev=%s", devname)
mainloop.execute_next_action()
else:
logging.debug(
'Device reapply failed, fallback to device activation: dev=%s, '
'error=unknown',
"Device reapply failed, fallback to device activation: dev=%s, "
"error=unknown",
devname,
)
_activate_async(src_object)
@ -189,11 +189,11 @@ def _modify_callback(src_object, result, user_data):
def _requires_activation(dev, connection_profile):
if StrictVersion(nmclient.nm_version()) < StrictVersion(
'1.18'
"1.18"
) and _mtu_changed(dev, connection_profile):
logging.debug(
'Device reapply does not support mtu changes, '
'fallback to device activation: dev=%s',
"Device reapply does not support mtu changes, "
"fallback to device activation: dev=%s",
dev.get_iface(),
)
return True
@ -249,14 +249,14 @@ def _delete_device_callback(src_object, result, user_data):
and nmdev.is_software()
):
logging.debug(
'Device %s has been already deleted: error=%s',
"Device %s has been already deleted: error=%s",
nmdev.get_iface(),
e,
)
mainloop.execute_next_action()
else:
mainloop.quit(
'Device deletion failed on {}: error={}'.format(
"Device deletion failed on {}: error={}".format(
nmdev.get_iface(), e
)
)
@ -264,11 +264,11 @@ def _delete_device_callback(src_object, result, user_data):
except Exception as e:
if mainloop.is_action_canceled(e):
logging.debug(
'Device deletion aborted on %s: error=%s', nmdev.get_iface(), e
"Device deletion aborted on %s: error=%s", nmdev.get_iface(), e
)
else:
mainloop.quit(
'Device deletion failed on {}: error={}'.format(
"Device deletion failed on {}: error={}".format(
nmdev.get_iface(), e
)
)
@ -276,11 +276,11 @@ def _delete_device_callback(src_object, result, user_data):
devname = src_object.get_iface()
if success:
logging.debug('Device deletion succeeded: dev=%s', devname)
logging.debug("Device deletion succeeded: dev=%s", devname)
mainloop.execute_next_action()
else:
mainloop.quit(
'Device deletion failed: dev={}, error=unknown'.format(devname)
"Device deletion failed: dev={}, error=unknown".format(devname)
)
@ -296,8 +296,8 @@ def list_devices():
def get_device_common_info(dev):
return {
'name': dev.get_iface(),
'type_id': dev.get_device_type(),
'type_name': dev.get_type_description(),
'state': dev.get_state(),
"name": dev.get_iface(),
"type_id": dev.get_device_type(),
"type_name": dev.get_type_description(),
"state": dev.get_state(),
}

View File

@ -31,8 +31,8 @@ from libnmstate.schema import Interface
DNS_DEFAULT_PRIORITY_VPN = 50
DNS_DEFAULT_PRIORITY_OTHER = 100
DNS_METADATA = '_dns'
DNS_METADATA_PRIORITY = '_priority'
DNS_METADATA = "_dns"
DNS_METADATA_PRIORITY = "_priority"
DEFAULT_DNS_PRIORITY = 0
# The 40 is chose as default DHCP DNS priority is 100, and VPN DNS priority is
# 50, the static DNS configuration should be list before them.
@ -52,10 +52,10 @@ def get_running():
# For IPv6 link local address, the interface name should be
# appended also.
raise NmstateInternalError(
'Missing interface for IPv6 link-local DNS server '
'entry {}'.format(ns)
"Missing interface for IPv6 link-local DNS server "
"entry {}".format(ns)
)
ns_addr = '{}%{}'.format(ns, iface_name)
ns_addr = "{}%{}".format(ns, iface_name)
else:
ns_addr = ns
dns_state[DNS.SERVER].append(ns_addr)
@ -82,9 +82,9 @@ def get_config(acs_and_ipv4_profiles, acs_and_ipv6_profiles):
tmp_dns_confs.append(
{
'server': ip_profile.props.dns,
'priority': priority,
'search': ip_profile.props.dns_search,
"server": ip_profile.props.dns,
"priority": priority,
"search": ip_profile.props.dns_search,
}
)
# NetworkManager sorts the DNS entries based on various criteria including
@ -93,10 +93,10 @@ def get_config(acs_and_ipv4_profiles, acs_and_ipv6_profiles):
# order in a declarative way, Nmstate only uses the priority to order the
# entries. Reference:
# https://developer.gnome.org/NetworkManager/stable/nm-settings.html#nm-settings.property.ipv4.dns-priority
tmp_dns_confs.sort(key=itemgetter('priority'))
tmp_dns_confs.sort(key=itemgetter("priority"))
for e in tmp_dns_confs:
dns_conf[DNS.SERVER].extend(e['server'])
dns_conf[DNS.SEARCH].extend(e['search'])
dns_conf[DNS.SERVER].extend(e["server"])
dns_conf[DNS.SEARCH].extend(e["search"])
if not dns_conf[DNS.SERVER] and dns_conf[DNS.SEARCH]:
return {}
return dns_conf

View File

@ -48,7 +48,7 @@ def create_setting(config, base_con_profile):
if not setting_ipv4:
setting_ipv4 = nmclient.NM.SettingIP4Config.new()
setting_ipv4.props.dhcp_client_id = 'mac'
setting_ipv4.props.dhcp_client_id = "mac"
setting_ipv4.props.method = nmclient.NM.SETTING_IP4_CONFIG_METHOD_DISABLED
if config and config.get(InterfaceIPv4.ENABLED):
if config.get(InterfaceIPv4.DHCP):
@ -108,7 +108,7 @@ def get_info(active_connection):
nmclient.NM.SETTING_IP4_CONFIG_METHOD_AUTO
)
props = ip_profile.props
if info['dhcp']:
if info["dhcp"]:
info[InterfaceIPv4.AUTO_ROUTES] = not props.ignore_auto_routes
info[InterfaceIPv4.AUTO_GATEWAY] = not props.never_default
info[InterfaceIPv4.AUTO_DNS] = not props.ignore_auto_dns

View File

@ -123,7 +123,7 @@ def create_setting(config, base_con_profile):
setting_ip.props.addr_gen_mode = (
nmclient.NM.SettingIP6ConfigAddrGenMode.EUI64
)
setting_ip.props.dhcp_duid = 'll'
setting_ip.props.dhcp_duid = "ll"
if not config or not config.get(InterfaceIPv6.ENABLED):
try:
@ -173,7 +173,7 @@ def create_setting(config, base_con_profile):
def _set_dynamic(setting_ip, is_dhcp, is_autoconf):
if not is_dhcp and is_autoconf:
raise NmstateNotImplementedError(
'Autoconf without DHCP is not supported yet'
"Autoconf without DHCP is not supported yet"
)
if is_dhcp and is_autoconf:
@ -189,9 +189,9 @@ def _set_static(setting_ip, ip_addresses):
address[InterfaceIPv6.ADDRESS_PREFIX_LENGTH],
):
logging.warning(
'IPv6 link local address '
'{a[ip]}/{a[prefix-length]} is ignored '
'when applying desired state'.format(a=address)
"IPv6 link local address "
"{a[ip]}/{a[prefix-length]} is ignored "
"when applying desired state".format(a=address)
)
else:
naddr = nmclient.NM.IPAddress.new(

View File

@ -23,7 +23,7 @@ import logging
import gi
try:
gi.require_version('NM', '1.0') # NOQA: F402
gi.require_version("NM", "1.0") # NOQA: F402
from gi.repository import NM # pylint: disable=no-name-in-module
except ValueError:
NM = None
@ -39,7 +39,7 @@ GObject
_mainloop = None
_nmclient = None
_can_disable_ipv6 = hasattr(NM, 'SETTING_IP6_CONFIG_METHOD_DISABLED')
_can_disable_ipv6 = hasattr(NM, "SETTING_IP6_CONFIG_METHOD_DISABLED")
def can_disable_ipv6():
@ -59,21 +59,21 @@ def client(refresh=False):
_nmclient = NM.Client.new(None)
if not _nmclient.get_nm_running():
logging.error(
'NetworkManager is not running, please make sure'
'it is installed and running prior to running nmstate.\n'
'Check the documentation for more information.'
"NetworkManager is not running, please make sure"
"it is installed and running prior to running nmstate.\n"
"Check the documentation for more information."
)
raise error.NmstateDependencyError(
'NetworkManager is not running'
"NetworkManager is not running"
)
else:
logging.error(
'Missing introspection data for libnm'
'please make sure to install it prior to running nmstate.\n'
'Check the documentation for more information.'
"Missing introspection data for libnm"
"please make sure to install it prior to running nmstate.\n"
"Check the documentation for more information."
)
raise error.NmstateDependencyError(
'Missing introspection data for libnm'
"Missing introspection data for libnm"
)
return _nmclient
@ -96,24 +96,24 @@ def mainloop(refresh=False):
class _MainLoop:
SUCCESS = True
FAIL = False
RUN_TIMEOUT_ERROR = 'run timeout'
RUN_EXECUTION_ERROR = 'run execution'
RUN_TIMEOUT_ERROR = "run timeout"
RUN_EXECUTION_ERROR = "run execution"
def __init__(self):
self._action_queue = deque()
self._mainloop = GLib.MainLoop()
self._cancellables = []
self.new_cancellable()
self._error = ''
self._error = ""
def execute_next_action(self):
action = self.pop_action()
if action:
func, args, kwargs = action
logging.debug('Executing NM action: func=%s', func.__name__)
logging.debug("Executing NM action: func=%s", func.__name__)
func(*args, **kwargs)
else:
logging.debug('NM action queue exhausted, quiting mainloop')
logging.debug("NM action queue exhausted, quiting mainloop")
self._mainloop.quit()
def push_action(self, func, *args, **kwargs):
@ -165,7 +165,7 @@ class _MainLoop:
def drop_cancellable(self, c):
idx = self._cancellables.index(c)
if idx == 0:
raise error.NmstateInternalError('Cannot drop main cancellable')
raise error.NmstateInternalError("Cannot drop main cancellable")
del self._cancellables[idx]
def _cancel_cancellables(self):
@ -173,7 +173,7 @@ class _MainLoop:
c.cancel()
def quit(self, reason):
logging.error('NM main-loop aborted: %s', reason)
logging.error("NM main-loop aborted: %s", reason)
# In case it was the last action, add a sentinel to fail run.
self.push_action(None)
self._mainloop.quit()
@ -182,7 +182,7 @@ class _MainLoop:
def is_action_canceled(self, err):
return (
isinstance(err, GLib.GError)
and err.domain == 'g-io-error-quark'
and err.domain == "g-io-error-quark"
and err.code == Gio.IOErrorEnum.CANCELLED
)
@ -208,7 +208,7 @@ class _MainLoop:
def _timeout_cb(data):
mainloop, result = data
result.append(1)
logging.warning('NM main-loop timed out.')
logging.warning("NM main-loop timed out.")
mainloop.quit()
return _MainLoop.FAIL

View File

@ -25,23 +25,23 @@ from . import device
from . import nmclient
BRIDGE_TYPE = 'ovs-bridge'
INTERNAL_INTERFACE_TYPE = 'ovs-interface'
PORT_TYPE = 'ovs-port'
PORT_PROFILE_PREFIX = 'ovs-port-'
CAPABILITY = 'openvswitch'
BRIDGE_TYPE = "ovs-bridge"
INTERNAL_INTERFACE_TYPE = "ovs-interface"
PORT_TYPE = "ovs-port"
PORT_PROFILE_PREFIX = "ovs-port-"
CAPABILITY = "openvswitch"
_BRIDGE_OPTION_NAMES = ['fail-mode', 'mcast-snooping-enable', 'rstp', 'stp']
_BRIDGE_OPTION_NAMES = ["fail-mode", "mcast-snooping-enable", "rstp", "stp"]
_PORT_OPTION_NAMES = [
'tag',
'vlan-mode',
'bond-mode',
'lacp',
'bond-updelay',
'bond-downdelay',
"tag",
"vlan-mode",
"bond-mode",
"lacp",
"bond-updelay",
"bond-downdelay",
]
@ -56,18 +56,18 @@ def has_ovs_capability():
def create_bridge_setting(options):
bridge_setting = nmclient.NM.SettingOvsBridge.new()
for option_name, option_value in options.items():
if option_name == 'fail-mode':
if option_name == "fail-mode":
if option_value:
bridge_setting.props.fail_mode = option_value
elif option_name == 'mcast-snooping-enable':
elif option_name == "mcast-snooping-enable":
bridge_setting.props.mcast_snooping_enable = option_value
elif option_name == 'rstp':
elif option_name == "rstp":
bridge_setting.props.rstp_enable = option_value
elif option_name == 'stp':
elif option_name == "stp":
bridge_setting.props.stp_enable = option_value
else:
raise NmstateValueError(
'Invalid OVS bridge option: \'{}\'=\'{}\''.format(
"Invalid OVS bridge option: '{}'='{}'".format(
option_name, option_value
)
)
@ -78,21 +78,21 @@ def create_bridge_setting(options):
def create_port_setting(options):
port_setting = nmclient.NM.SettingOvsPort.new()
for option_name, option_value in options.items():
if option_name == 'tag':
if option_name == "tag":
port_setting.props.tag = option_value
elif option_name == 'vlan-mode':
elif option_name == "vlan-mode":
port_setting.props.vlan_mode = option_value
elif option_name == 'bond-mode':
elif option_name == "bond-mode":
port_setting.props.bond_mode = option_value
elif option_name == 'lacp':
elif option_name == "lacp":
port_setting.props.lacp = option_value
elif option_name == 'bond-updelay':
elif option_name == "bond-updelay":
port_setting.props.bond_updelay = option_value
elif option_name == 'bond-downdelay':
elif option_name == "bond-downdelay":
port_setting.props.bond_downdelay = option_value
else:
raise NmstateValueError(
'Invalid OVS port option: \'{}\'=\'{}\''.format(
"Invalid OVS port option: '{}'='{}'".format(
option_name, option_value
)
)
@ -102,13 +102,13 @@ def create_port_setting(options):
def create_interface_setting():
interface_setting = nmclient.NM.SettingOvsInterface.new()
interface_setting.props.type = 'internal'
interface_setting.props.type = "internal"
return interface_setting
def translate_bridge_options(iface_state):
br_opts = {}
bridge_state = iface_state.get('bridge', {}).get('options', {})
bridge_state = iface_state.get("bridge", {}).get("options", {})
for key in bridge_state.keys() & set(_BRIDGE_OPTION_NAMES):
br_opts[key] = bridge_state[key]
@ -149,7 +149,7 @@ def get_ovs_info(bridge_device, devices_info):
options = _get_bridge_options(bridge_device)
if ports or options:
return {'port': ports, 'options': options}
return {"port": ports, "options": options}
else:
return {}
@ -181,10 +181,10 @@ def _get_bridge_port_info(port_profile, devices_info):
if port_slave_names:
iface_slave_name = port_slave_names[0]
port_info['name'] = iface_slave_name
port_info["name"] = iface_slave_name
if vlan_mode:
port_info['vlan-mode'] = vlan_mode
port_info['access-tag'] = port_setting.props.tag
port_info["vlan-mode"] = vlan_mode
port_info["access-tag"] = port_setting.props.tag
return port_info
@ -195,11 +195,11 @@ def _get_bridge_options(bridge_device):
con.import_by_device(bridge_device)
if con.profile:
bridge_setting = con.profile.get_setting(nmclient.NM.SettingOvsBridge)
bridge_options['stp'] = bridge_setting.props.stp_enable
bridge_options['rstp'] = bridge_setting.props.rstp_enable
bridge_options['fail-mode'] = bridge_setting.props.fail_mode or ''
bridge_options["stp"] = bridge_setting.props.stp_enable
bridge_options["rstp"] = bridge_setting.props.rstp_enable
bridge_options["fail-mode"] = bridge_setting.props.fail_mode or ""
bridge_options[
'mcast-snooping-enable'
"mcast-snooping-enable"
] = bridge_setting.props.mcast_snooping_enable
return bridge_options

View File

@ -30,11 +30,11 @@ from libnmstate.schema import Interface
from libnmstate.schema import Route
from libnmstate.schema import RouteRule
NM_ROUTE_TABLE_ATTRIBUTE = 'table'
IPV4_DEFAULT_GATEWAY_DESTINATION = '0.0.0.0/0'
IPV6_DEFAULT_GATEWAY_DESTINATION = '::/0'
ROUTE_METADATA = '_routes'
ROUTE_RULES_METADATA = '_route_rules'
NM_ROUTE_TABLE_ATTRIBUTE = "table"
IPV4_DEFAULT_GATEWAY_DESTINATION = "0.0.0.0/0"
IPV6_DEFAULT_GATEWAY_DESTINATION = "::/0"
ROUTE_METADATA = "_routes"
ROUTE_RULES_METADATA = "_route_rules"
# NM require route rule priority been set explicitly, use 30,000 when
# desire state instruct to use USE_DEFAULT_PRIORITY
@ -54,7 +54,7 @@ def get_running(acs_and_ip_cfgs):
iface_name = nm_ac.ActiveConnection(active_connection).devname
if not iface_name:
raise NmstateInternalError(
'Got connection {} has not interface name'.format(
"Got connection {} has not interface name".format(
active_connection.get_id()
)
)
@ -88,7 +88,7 @@ def get_config(acs_and_ip_profiles):
iface_name = nm_ac.ActiveConnection(active_connection).devname
if not iface_name:
raise NmstateInternalError(
'Got connection {} has not interface name'.format(
"Got connection {} has not interface name".format(
active_connection.get_id()
)
)
@ -126,10 +126,10 @@ def _get_per_route_table_id(nm_route, default_table_id):
def _nm_route_to_route(nm_route, table_id, iface_name):
dst = '{ip}/{prefix}'.format(
dst = "{ip}/{prefix}".format(
ip=nm_route.get_dest(), prefix=nm_route.get_prefix()
)
next_hop = nm_route.get_next_hop() or ''
next_hop = nm_route.get_next_hop() or ""
metric = int(nm_route.get_metric())
return {
@ -163,9 +163,9 @@ def add_routes(setting_ip, routes):
):
if setting_ip.get_gateway():
raise NmstateNotImplementedError(
'Only a single default gateway is supported due to a '
'limitation of NetworkManager: '
'https://bugzilla.redhat.com/1707396'
"Only a single default gateway is supported due to a "
"limitation of NetworkManager: "
"https://bugzilla.redhat.com/1707396"
)
_add_route_gateway(setting_ip, route)
else:
@ -173,7 +173,7 @@ def add_routes(setting_ip, routes):
def _add_specfic_route(setting_ip, route):
destination, prefix_len = route[Route.DESTINATION].split('/')
destination, prefix_len = route[Route.DESTINATION].split("/")
prefix_len = int(prefix_len)
if iplib.is_ipv6_address(destination):
family = socket.AF_INET6
@ -268,7 +268,7 @@ def _rule_info_to_nm_rule(rule, family):
ip_to = rule.get(RouteRule.IP_TO)
if not ip_from and not ip_to:
raise NmstateValueError(
f'Neither {RouteRule.IP_FROM} or {RouteRule.IP_TO} is defined'
f"Neither {RouteRule.IP_FROM} or {RouteRule.IP_TO} is defined"
)
if ip_from:

View File

@ -22,12 +22,12 @@ import copy
from . import nmclient
IFACE_TYPE_UNKNOWN = 'unknown'
IFACE_TYPE_UNKNOWN = "unknown"
class ApiIfaceAdminState:
DOWN = 'down'
UP = 'up'
DOWN = "down"
UP = "up"
class Api2Nm:
@ -41,18 +41,18 @@ class Api2Nm:
def get_iface_type_map():
if Api2Nm._iface_types_map is None:
Api2Nm._iface_types_map = {
'ethernet': nmclient.NM.SETTING_WIRED_SETTING_NAME,
'bond': nmclient.NM.SETTING_BOND_SETTING_NAME,
'dummy': nmclient.NM.SETTING_DUMMY_SETTING_NAME,
'vlan': nmclient.NM.SETTING_VLAN_SETTING_NAME,
'vxlan': nmclient.NM.SETTING_VXLAN_SETTING_NAME,
'linux-bridge': nmclient.NM.SETTING_BRIDGE_SETTING_NAME,
"ethernet": nmclient.NM.SETTING_WIRED_SETTING_NAME,
"bond": nmclient.NM.SETTING_BOND_SETTING_NAME,
"dummy": nmclient.NM.SETTING_DUMMY_SETTING_NAME,
"vlan": nmclient.NM.SETTING_VLAN_SETTING_NAME,
"vxlan": nmclient.NM.SETTING_VXLAN_SETTING_NAME,
"linux-bridge": nmclient.NM.SETTING_BRIDGE_SETTING_NAME,
}
try:
ovs_types = {
'ovs-bridge': nmclient.NM.SETTING_OVS_BRIDGE_SETTING_NAME,
'ovs-port': nmclient.NM.SETTING_OVS_PORT_SETTING_NAME,
'ovs-interface': (
"ovs-bridge": nmclient.NM.SETTING_OVS_BRIDGE_SETTING_NAME,
"ovs-port": nmclient.NM.SETTING_OVS_PORT_SETTING_NAME,
"ovs-interface": (
nmclient.NM.SETTING_OVS_INTERFACE_SETTING_NAME
),
}
@ -64,12 +64,12 @@ class Api2Nm:
@staticmethod
def get_bond_options(iface_desired_state):
iface_type = Api2Nm.get_iface_type(iface_desired_state['type'])
if iface_type == 'bond':
iface_type = Api2Nm.get_iface_type(iface_desired_state["type"])
if iface_type == "bond":
# Is the mode a must config parameter?
bond_conf = iface_desired_state['link-aggregation']
bond_opts = {'mode': bond_conf['mode']}
bond_opts.update(bond_conf.get('options', {}))
bond_conf = iface_desired_state["link-aggregation"]
bond_opts = {"mode": bond_conf["mode"]}
bond_opts.update(bond_conf.get("options", {}))
else:
bond_opts = {}
@ -81,29 +81,29 @@ class Nm2Api:
@staticmethod
def get_common_device_info(devinfo):
type_name = devinfo['type_name']
if type_name != 'ethernet':
type_name = devinfo["type_name"]
if type_name != "ethernet":
type_name = Nm2Api.get_iface_type(type_name)
return {
'name': devinfo['name'],
'type': type_name,
'state': Nm2Api.get_iface_admin_state(devinfo['state']),
"name": devinfo["name"],
"type": type_name,
"state": Nm2Api.get_iface_admin_state(devinfo["state"]),
}
@staticmethod
def get_bond_info(bondinfo):
bond_options = copy.deepcopy(bondinfo.get('options'))
bond_options = copy.deepcopy(bondinfo.get("options"))
if not bond_options:
return {}
bond_slaves = bondinfo['slaves']
bond_slaves = bondinfo["slaves"]
bond_mode = bond_options['mode']
del bond_options['mode']
bond_mode = bond_options["mode"]
del bond_options["mode"]
return {
'link-aggregation': {
'mode': bond_mode,
'slaves': [slave.props.interface for slave in bond_slaves],
'options': bond_options,
"link-aggregation": {
"mode": bond_mode,
"slaves": [slave.props.interface for slave in bond_slaves],
"options": bond_options,
}
}

View File

@ -30,13 +30,13 @@ NMSTATE_DESCRIPTION = "nmstate.interface.description"
def create_setting(iface_state, base_con_profile):
description = iface_state.get('description')
description = iface_state.get("description")
if not description:
return None
if not nmclient.NM.SettingUser.check_val(description):
raise NmstateValueError('Invalid description')
raise NmstateValueError("Invalid description")
user_setting = None
if base_con_profile:
@ -70,7 +70,7 @@ def get_info(device):
)
description = user_setting.get_data(NMSTATE_DESCRIPTION)
if description:
info['description'] = description
info["description"] = description
except AttributeError:
pass

View File

@ -56,12 +56,12 @@ def get_info(device):
Provides the current active values for a device
"""
if device.get_device_type() == nmclient.NM.DeviceType.VXLAN:
base_iface = ''
base_iface = ""
if device.props.parent:
base_iface = device.props.parent.get_iface()
remote = device.props.group
if not remote:
remote = ''
remote = ""
return {
VXLAN.CONFIG_SUBTREE: {
VXLAN.ID: device.props.id,
@ -83,7 +83,7 @@ def _get_destination_port(device):
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1768388
"""
if nm.nmclient.nm_version() >= StrictVersion('1.20.6'):
if nm.nmclient.nm_version() >= StrictVersion("1.20.6"):
return device.get_dst_port()
else:
con = connection.ConnectionProfile()

View File

@ -24,7 +24,7 @@ from libnmstate.schema import Ethernet
from libnmstate.schema import Interface
ZEROED_MAC = '00:00:00:00:00:00'
ZEROED_MAC = "00:00:00:00:00:00"
class WiredSetting:

View File

@ -32,26 +32,26 @@ def format_desired_current_state_diff(desired_state, current_state):
pretty_desired_state = PrettyState(desired_state).yaml
pretty_current_state = PrettyState(current_state).yaml
diff = ''.join(
diff = "".join(
difflib.unified_diff(
pretty_desired_state.splitlines(True),
pretty_current_state.splitlines(True),
fromfile='desired',
tofile='current',
fromfile="desired",
tofile="current",
n=3,
)
)
return (
'\n'
'desired\n'
'=======\n'
'{}\n'
'current\n'
'=======\n'
'{}\n'
'difference\n'
'==========\n'
'{}\n'.format(pretty_desired_state, pretty_current_state, diff)
"\n"
"desired\n"
"=======\n"
"{}\n"
"current\n"
"=======\n"
"{}\n"
"difference\n"
"==========\n"
"{}\n".format(pretty_desired_state, pretty_current_state, diff)
)
@ -68,7 +68,7 @@ class PrettyState:
@property
def json(self):
return json.dumps(self.state, indent=4, separators=(',', ': '))
return json.dumps(self.state, indent=4, separators=(",", ": "))
def represent_ordereddict(dumper, data):
@ -85,7 +85,7 @@ def represent_ordereddict(dumper, data):
value.append((node_key, node_value))
return yaml.nodes.MappingNode(u'tag:yaml.org,2002:map', value)
return yaml.nodes.MappingNode(u"tag:yaml.org,2002:map", value)
def order_state(state):
@ -96,7 +96,7 @@ def order_state(state):
if iface_states is not None:
state[Constants.INTERFACES] = [
order_iface_state(iface_state)
for iface_state in sorted(iface_states, key=itemgetter('name'))
for iface_state in sorted(iface_states, key=itemgetter("name"))
]
return state
@ -112,14 +112,14 @@ def represent_unicode(_, data):
"""
return yaml.ScalarNode(
tag=u'tag:yaml.org,2002:str', value=data.encode('utf-8')
tag=u"tag:yaml.org,2002:str", value=data.encode("utf-8")
)
def order_iface_state(iface_state):
ordered_state = OrderedDict()
for setting in ('name', 'type', 'state'):
for setting in ("name", "type", "state"):
try:
ordered_state[setting] = iface_state.pop(setting)
except KeyError:

View File

@ -26,62 +26,62 @@ import yaml
def load(schema_name):
return yaml.load(
pkgutil.get_data('libnmstate', 'schemas/' + schema_name + '.yaml'),
pkgutil.get_data("libnmstate", "schemas/" + schema_name + ".yaml"),
Loader=yaml.SafeLoader,
)
ifaces_schema = load('operational-state')
ifaces_schema = load("operational-state")
class Interface:
KEY = 'interfaces'
KEY = "interfaces"
NAME = 'name'
TYPE = 'type'
STATE = 'state'
DESCRIPTION = 'description'
NAME = "name"
TYPE = "type"
STATE = "state"
DESCRIPTION = "description"
IPV4 = 'ipv4'
IPV6 = 'ipv6'
IPV4 = "ipv4"
IPV6 = "ipv6"
MAC = 'mac-address'
MTU = 'mtu'
MAC = "mac-address"
MTU = "mtu"
class Route:
KEY = 'routes'
KEY = "routes"
RUNNING = 'running'
CONFIG = 'config'
STATE = 'state'
STATE_ABSENT = 'absent'
TABLE_ID = 'table-id'
DESTINATION = 'destination'
NEXT_HOP_INTERFACE = 'next-hop-interface'
NEXT_HOP_ADDRESS = 'next-hop-address'
METRIC = 'metric'
RUNNING = "running"
CONFIG = "config"
STATE = "state"
STATE_ABSENT = "absent"
TABLE_ID = "table-id"
DESTINATION = "destination"
NEXT_HOP_INTERFACE = "next-hop-interface"
NEXT_HOP_ADDRESS = "next-hop-address"
METRIC = "metric"
USE_DEFAULT_METRIC = -1
USE_DEFAULT_ROUTE_TABLE = 0
class RouteRule:
KEY = 'route-rules'
CONFIG = 'config'
IP_FROM = 'ip-from'
IP_TO = 'ip-to'
PRIORITY = 'priority'
ROUTE_TABLE = 'route-table'
KEY = "route-rules"
CONFIG = "config"
IP_FROM = "ip-from"
IP_TO = "ip-to"
PRIORITY = "priority"
ROUTE_TABLE = "route-table"
USE_DEFAULT_PRIORITY = -1
USE_DEFAULT_ROUTE_TABLE = 0
class DNS:
KEY = 'dns-resolver'
RUNNING = 'running'
CONFIG = 'config'
SERVER = 'server'
SEARCH = 'search'
KEY = "dns-resolver"
RUNNING = "running"
CONFIG = "config"
SERVER = "server"
SEARCH = "search"
class Constants:
@ -93,25 +93,25 @@ class Constants:
class InterfaceState:
KEY = Interface.STATE
DOWN = 'down'
UP = 'up'
ABSENT = 'absent'
DOWN = "down"
UP = "up"
ABSENT = "absent"
class InterfaceType:
KEY = Interface.TYPE
BOND = 'bond'
DUMMY = 'dummy'
ETHERNET = 'ethernet'
LINUX_BRIDGE = 'linux-bridge'
OVS_BRIDGE = 'ovs-bridge'
OVS_INTERFACE = 'ovs-interface'
OVS_PORT = 'ovs-port'
UNKNOWN = 'unknown'
VLAN = 'vlan'
VXLAN = 'vxlan'
TEAM = 'team'
BOND = "bond"
DUMMY = "dummy"
ETHERNET = "ethernet"
LINUX_BRIDGE = "linux-bridge"
OVS_BRIDGE = "ovs-bridge"
OVS_INTERFACE = "ovs-interface"
OVS_PORT = "ovs-port"
UNKNOWN = "unknown"
VLAN = "vlan"
VXLAN = "vxlan"
TEAM = "team"
VIRT_TYPES = (
BOND,
@ -127,14 +127,14 @@ class InterfaceType:
class InterfaceIP:
ENABLED = 'enabled'
ADDRESS = 'address'
ADDRESS_IP = 'ip'
ADDRESS_PREFIX_LENGTH = 'prefix-length'
DHCP = 'dhcp'
AUTO_DNS = 'auto-dns'
AUTO_GATEWAY = 'auto-gateway'
AUTO_ROUTES = 'auto-routes'
ENABLED = "enabled"
ADDRESS = "address"
ADDRESS_IP = "ip"
ADDRESS_PREFIX_LENGTH = "prefix-length"
DHCP = "dhcp"
AUTO_DNS = "auto-dns"
AUTO_GATEWAY = "auto-gateway"
AUTO_ROUTES = "auto-routes"
class InterfaceIPv4(InterfaceIP):
@ -142,47 +142,47 @@ class InterfaceIPv4(InterfaceIP):
class InterfaceIPv6(InterfaceIP):
AUTOCONF = 'autoconf'
AUTOCONF = "autoconf"
class Bond:
KEY = InterfaceType.BOND
CONFIG_SUBTREE = 'link-aggregation'
CONFIG_SUBTREE = "link-aggregation"
MODE = 'mode'
SLAVES = 'slaves'
OPTIONS_SUBTREE = 'options'
MODE = "mode"
SLAVES = "slaves"
OPTIONS_SUBTREE = "options"
class BondMode:
ROUND_ROBIN = 'balance-rr'
ACTIVE_BACKUP = 'active-backup'
XOR = 'balance-xor'
BROADCAST = 'broadcast'
LACP = '802.3ad'
TLB = 'balance-tlb'
ALB = 'balance-alb'
ROUND_ROBIN = "balance-rr"
ACTIVE_BACKUP = "active-backup"
XOR = "balance-xor"
BROADCAST = "broadcast"
LACP = "802.3ad"
TLB = "balance-tlb"
ALB = "balance-alb"
_NEW_OVSBR_OPTS_MCAST_SNOOP = 'OVSBridge.Options.MCAST_SNOOPING_ENABLED'
_NEW_OVSBR_OPTS_MCAST_SNOOP = "OVSBridge.Options.MCAST_SNOOPING_ENABLED"
DEPRECATED_CONSTANTS = {
'LinuxBridge.GROUP_FORWARD_MASK': 'LinuxBridge.Options.GROUP_FORWARD_MASK',
'LinuxBridge.MAC_AGEING_TIME': 'LinuxBridge.Options.MAC_AGEING_TIME',
'LinuxBridge.MULTICAST_SNOOPING': 'LinuxBridge.Options.MULTICAST_SNOOPING',
'LinuxBridge.PORT_NAME': 'LinuxBridge.Port.NAME',
'LinuxBridge.PORT_STP_HAIRPIN_MODE': 'LinuxBridge.Port.STP_HAIRPIN_MODE',
'LinuxBridge.PORT_STP_PATH_COST': 'LinuxBridge.Port.STP_PATH_COST',
'LinuxBridge.PORT_STP_PRIORITY': 'LinuxBridge.Port.STP_PRIORITY',
'LinuxBridge.STP_ENABLED': 'LinuxBridge.STP.ENABLED',
'LinuxBridge.STP_FORWARD_DELAY': 'LinuxBridge.STP.FORWARD_DELAY',
'LinuxBridge.STP_HELLO_TIME': 'LinuxBridge.STP.HELLO_TIME',
'LinuxBridge.STP_MAX_AGE': 'LinuxBridge.STP.MAX_AGE',
'LinuxBridge.STP_PRIORITY': 'LinuxBridge.STP.PRIORITY',
'OVSBridge.PORT_NAME': 'OVSBridge.Port.NAME',
'OVSBridge.FAIL_MODE': 'OVSBridge.Options.FAIL_MODE',
'OVSBridge.MCAST_SNOOPING_ENABLED': _NEW_OVSBR_OPTS_MCAST_SNOOP,
'OVSBridge.RSTP': 'OVSBridge.Options.RSTP',
'OVSBridge.STP': 'OVSBridge.Options.STP',
"LinuxBridge.GROUP_FORWARD_MASK": "LinuxBridge.Options.GROUP_FORWARD_MASK",
"LinuxBridge.MAC_AGEING_TIME": "LinuxBridge.Options.MAC_AGEING_TIME",
"LinuxBridge.MULTICAST_SNOOPING": "LinuxBridge.Options.MULTICAST_SNOOPING",
"LinuxBridge.PORT_NAME": "LinuxBridge.Port.NAME",
"LinuxBridge.PORT_STP_HAIRPIN_MODE": "LinuxBridge.Port.STP_HAIRPIN_MODE",
"LinuxBridge.PORT_STP_PATH_COST": "LinuxBridge.Port.STP_PATH_COST",
"LinuxBridge.PORT_STP_PRIORITY": "LinuxBridge.Port.STP_PRIORITY",
"LinuxBridge.STP_ENABLED": "LinuxBridge.STP.ENABLED",
"LinuxBridge.STP_FORWARD_DELAY": "LinuxBridge.STP.FORWARD_DELAY",
"LinuxBridge.STP_HELLO_TIME": "LinuxBridge.STP.HELLO_TIME",
"LinuxBridge.STP_MAX_AGE": "LinuxBridge.STP.MAX_AGE",
"LinuxBridge.STP_PRIORITY": "LinuxBridge.STP.PRIORITY",
"OVSBridge.PORT_NAME": "OVSBridge.Port.NAME",
"OVSBridge.FAIL_MODE": "OVSBridge.Options.FAIL_MODE",
"OVSBridge.MCAST_SNOOPING_ENABLED": _NEW_OVSBR_OPTS_MCAST_SNOOP,
"OVSBridge.RSTP": "OVSBridge.Options.RSTP",
"OVSBridge.STP": "OVSBridge.Options.STP",
}
@ -195,7 +195,7 @@ class _DeprecatorType(type):
deprecated_classname = deprecated_class.__name__
deprecated_name = attribute
oldconstant = f'{deprecated_classname}.{deprecated_name}'
oldconstant = f"{deprecated_classname}.{deprecated_name}"
newconstant = DEPRECATED_CONSTANTS.get(oldconstant)
if newconstant:
@ -206,7 +206,7 @@ class _DeprecatorType(type):
stacklevel=3,
)
attributes = newconstant.split('.')
attributes = newconstant.split(".")
new_classname = attributes.pop(0)
new_value = globals()[new_classname]
while attributes:
@ -218,143 +218,143 @@ class _DeprecatorType(type):
class LinuxBridge(metaclass=_DeprecatorType):
TYPE = 'linux-bridge'
CONFIG_SUBTREE = 'bridge'
TYPE = "linux-bridge"
CONFIG_SUBTREE = "bridge"
OPTIONS_SUBTREE = 'options'
OPTIONS_SUBTREE = "options"
STP_SUBTREE = 'stp'
STP_SUBTREE = "stp"
PORT_SUBTREE = 'port'
PORT_SUBTREE = "port"
class Options:
GROUP_FORWARD_MASK = 'group-forward-mask'
MAC_AGEING_TIME = 'mac-ageing-time'
MULTICAST_SNOOPING = 'multicast-snooping'
GROUP_FORWARD_MASK = "group-forward-mask"
MAC_AGEING_TIME = "mac-ageing-time"
MULTICAST_SNOOPING = "multicast-snooping"
class Port:
NAME = 'name'
STP_HAIRPIN_MODE = 'stp-hairpin-mode'
STP_PATH_COST = 'stp-path-cost'
STP_PRIORITY = 'stp-priority'
VLAN_SUBTREE = 'vlan'
NAME = "name"
STP_HAIRPIN_MODE = "stp-hairpin-mode"
STP_PATH_COST = "stp-path-cost"
STP_PRIORITY = "stp-priority"
VLAN_SUBTREE = "vlan"
class Vlan:
ENABLE_NATIVE = 'enable-native'
MODE = 'mode'
TAG = 'tag'
TRUNK_TAGS = 'trunk-tags'
ENABLE_NATIVE = "enable-native"
MODE = "mode"
TAG = "tag"
TRUNK_TAGS = "trunk-tags"
class Mode:
ACCESS = 'access'
TRUNK = 'trunk'
ACCESS = "access"
TRUNK = "trunk"
class TrunkTags:
ID = 'id'
ID_RANGE = 'id-range'
MIN_RANGE = 'min'
MAX_RANGE = 'max'
ID = "id"
ID_RANGE = "id-range"
MIN_RANGE = "min"
MAX_RANGE = "max"
class STP:
ENABLED = 'enabled'
FORWARD_DELAY = 'forward-delay'
HELLO_TIME = 'hello-time'
MAX_AGE = 'max-age'
PRIORITY = 'priority'
ENABLED = "enabled"
FORWARD_DELAY = "forward-delay"
HELLO_TIME = "hello-time"
MAX_AGE = "max-age"
PRIORITY = "priority"
class Ethernet:
TYPE = InterfaceType.ETHERNET
CONFIG_SUBTREE = 'ethernet'
CONFIG_SUBTREE = "ethernet"
AUTO_NEGOTIATION = 'auto-negotiation'
SPEED = 'speed'
DUPLEX = 'duplex'
AUTO_NEGOTIATION = "auto-negotiation"
SPEED = "speed"
DUPLEX = "duplex"
FULL_DUPLEX = 'full'
HALF_DUPLEX = 'half'
FULL_DUPLEX = "full"
HALF_DUPLEX = "half"
SRIOV_SUBTREE = 'sr-iov'
SRIOV_SUBTREE = "sr-iov"
class SRIOV:
TOTAL_VFS = 'total-vfs'
TOTAL_VFS = "total-vfs"
class VLAN:
TYPE = InterfaceType.VLAN
CONFIG_SUBTREE = 'vlan'
CONFIG_SUBTREE = "vlan"
ID = 'id'
BASE_IFACE = 'base-iface'
ID = "id"
BASE_IFACE = "base-iface"
class VXLAN:
TYPE = InterfaceType.VXLAN
CONFIG_SUBTREE = 'vxlan'
CONFIG_SUBTREE = "vxlan"
ID = 'id'
BASE_IFACE = 'base-iface'
REMOTE = 'remote'
DESTINATION_PORT = 'destination-port'
ID = "id"
BASE_IFACE = "base-iface"
REMOTE = "remote"
DESTINATION_PORT = "destination-port"
class OVSBridge(metaclass=_DeprecatorType):
TYPE = 'ovs-bridge'
CONFIG_SUBTREE = 'bridge'
TYPE = "ovs-bridge"
CONFIG_SUBTREE = "bridge"
OPTIONS_SUBTREE = 'options'
OPTIONS_SUBTREE = "options"
class Options:
FAIL_MODE = 'fail-mode'
MCAST_SNOOPING_ENABLED = 'mcast-snooping-enable'
RSTP = 'rstp'
STP = 'stp'
FAIL_MODE = "fail-mode"
MCAST_SNOOPING_ENABLED = "mcast-snooping-enable"
RSTP = "rstp"
STP = "stp"
PORT_SUBTREE = 'port'
PORT_SUBTREE = "port"
class Port:
NAME = 'name'
NAME = "name"
VLAN_SUBTREE = 'vlan'
VLAN_SUBTREE = "vlan"
class Vlan:
TRUNK_TAGS = 'trunk-tags'
TAG = 'tag'
ENABLE_NATIVE = 'enable-native'
MODE = 'mode'
TRUNK_TAGS = "trunk-tags"
TAG = "tag"
ENABLE_NATIVE = "enable-native"
MODE = "mode"
class Mode:
ACCESS = 'access'
TRUNK = 'trunk'
ACCESS = "access"
TRUNK = "trunk"
class TrunkTags:
ID = 'id'
ID_RANGE = 'id-range'
MIN_RANGE = 'min'
MAX_RANGE = 'max'
ID = "id"
ID_RANGE = "id-range"
MIN_RANGE = "min"
MAX_RANGE = "max"
LINK_AGGREGATION_SUBTREE = 'link-aggregation'
LINK_AGGREGATION_SUBTREE = "link-aggregation"
class LinkAggregation:
MODE = 'mode'
SLAVES_SUBTREE = 'slaves'
MODE = "mode"
SLAVES_SUBTREE = "slaves"
class Slave:
NAME = 'name'
NAME = "name"
class Team:
TYPE = InterfaceType.TEAM
CONFIG_SUBTREE = InterfaceType.TEAM
PORT_SUBTREE = 'ports'
RUNNER_SUBTREE = 'runner'
PORT_SUBTREE = "ports"
RUNNER_SUBTREE = "runner"
class Port:
NAME = 'name'
NAME = "name"
class Runner:
NAME = 'name'
NAME = "name"
class RunnerMode:
LOAD_BALANCE = 'loadbalance'
LOAD_BALANCE = "loadbalance"

View File

@ -83,9 +83,9 @@ class StateEntry(metaclass=ABCMeta):
def to_dict(self):
return {
key.replace('_', '-'): value
key.replace("_", "-"): value
for key, value in vars(self).items()
if (not key.startswith('_')) and (value is not None)
if (not key.startswith("_")) and (value is not None)
}
def match(self, other):
@ -117,7 +117,7 @@ class RouteEntry(StateEntry):
if self.metric is None:
self.metric = Route.USE_DEFAULT_METRIC
if self.next_hop_address is None:
self.next_hop_address = ''
self.next_hop_address = ""
def _keys(self):
return (
@ -131,12 +131,12 @@ class RouteEntry(StateEntry):
def __lt__(self, other):
return (
self.table_id or Route.USE_DEFAULT_ROUTE_TABLE,
self.next_hop_interface or '',
self.destination or '',
self.next_hop_interface or "",
self.destination or "",
) < (
other.table_id or Route.USE_DEFAULT_ROUTE_TABLE,
other.next_hop_interface or '',
other.destination or '',
other.next_hop_interface or "",
other.destination or "",
)
@property
@ -154,9 +154,9 @@ class RouteRuleEntry(StateEntry):
def complement_defaults(self):
if self.ip_from is None:
self.ip_from = ''
self.ip_from = ""
if self.ip_to is None:
self.ip_to = ''
self.ip_to = ""
if self.priority is None:
self.priority = RouteRule.USE_DEFAULT_PRIORITY
if (
@ -171,7 +171,7 @@ class RouteRuleEntry(StateEntry):
@property
def absent(self):
raise NmstateNotImplementedError(
'RouteRuleEntry does not support absent property'
"RouteRuleEntry does not support absent property"
)
@ -295,7 +295,7 @@ class State:
If dynamic IP is disabled, all dynamic IP options should be removed.
"""
for iface_state in self.interfaces.values():
for family in ('ipv4', 'ipv6'):
for family in ("ipv4", "ipv6"):
ip = iface_state[family]
if ip.get(InterfaceIP.ENABLED) and (
ip.get(InterfaceIP.DHCP) or ip.get(InterfaceIPv6.AUTOCONF)
@ -501,7 +501,7 @@ class State:
def _index_routes_by_iface(self):
iface_routes = defaultdict(list)
for route in self._config_routes:
iface_name = route.get(Route.NEXT_HOP_INTERFACE, '')
iface_name = route.get(Route.NEXT_HOP_INTERFACE, "")
iface_routes[iface_name].append(RouteEntry(route))
for routes in iface_routes.values():
routes.sort()
@ -538,12 +538,12 @@ class State:
def _sort_lag_slaves(self):
for ifstate in self.interfaces.values():
ifstate.get('link-aggregation', {}).get('slaves', []).sort()
ifstate.get("link-aggregation", {}).get("slaves", []).sort()
def _sort_bridge_ports(self):
for ifstate in self.interfaces.values():
ifstate.get('bridge', {}).get('port', []).sort(
key=itemgetter('name')
ifstate.get("bridge", {}).get("port", []).sort(
key=itemgetter("name")
)
def _canonicalize_ipv6(self):
@ -570,9 +570,9 @@ class State:
def _remove_iface_ipv6_link_local_addr(self):
for ifstate in self.interfaces.values():
ifstate['ipv6'][InterfaceIPv6.ADDRESS] = list(
ifstate["ipv6"][InterfaceIPv6.ADDRESS] = list(
addr
for addr in ifstate['ipv6'][InterfaceIPv6.ADDRESS]
for addr in ifstate["ipv6"][InterfaceIPv6.ADDRESS]
if not iplib.is_ipv6_link_local_addr(
addr[InterfaceIPv6.ADDRESS_IP],
addr[InterfaceIPv6.ADDRESS_PREFIX_LENGTH],
@ -588,7 +588,7 @@ class State:
def _sort_ip_addresses(self):
for ifstate in self.interfaces.values():
for family in ('ipv4', 'ipv6'):
for family in ("ipv4", "ipv6"):
ifstate[family].get(InterfaceIP.ADDRESS, []).sort(
key=itemgetter(InterfaceIP.ADDRESS_IP)
)
@ -601,7 +601,7 @@ class State:
def _remove_empty_description(self):
for ifstate in self.interfaces.values():
if ifstate.get(Interface.DESCRIPTION) == '':
if ifstate.get(Interface.DESCRIPTION) == "":
del ifstate[Interface.DESCRIPTION]
def _assert_interfaces_equal(self, current_state):
@ -676,10 +676,10 @@ def _validate_routes(
continue
iface_enable_state = iface_enable_states.get(iface_name)
if iface_enable_state is None:
raise NmstateValueError('Cannot set route to non-exist interface')
raise NmstateValueError("Cannot set route to non-exist interface")
if iface_enable_state != InterfaceState.UP:
raise NmstateValueError(
'Cannot set route to {} interface'.format(iface_enable_state)
"Cannot set route to {} interface".format(iface_enable_state)
)
# Interface is already check, so the ip enable status should be defined
ipv4_enabled = ipv4_enable_states[iface_name]
@ -688,11 +688,11 @@ def _validate_routes(
if iplib.is_ipv6_address(route_obj.destination):
if not ipv6_enabled:
raise NmstateValueError(
'Cannot set IPv6 route when IPv6 is disabled'
"Cannot set IPv6 route when IPv6 is disabled"
)
elif not ipv4_enabled:
raise NmstateValueError(
'Cannot set IPv4 route when IPv4 is disabled'
"Cannot set IPv4 route when IPv4 is disabled"
)

View File

@ -36,8 +36,8 @@ def disable_ipv6(dev):
def _change_ipv6_state(dev, disable):
try:
with open('/proc/sys/net/ipv6/conf/%s/disable_ipv6' % dev, 'w') as f:
f.write('1' if disable else '0')
with open("/proc/sys/net/ipv6/conf/%s/disable_ipv6" % dev, "w") as f:
f.write("1" if disable else "0")
except IOError as e:
if e.errno == errno.ENOENT and disable:
# IPv6 stack is (already) not available on this device
@ -45,9 +45,9 @@ def _change_ipv6_state(dev, disable):
raise ChangeIpv6StateError(str(e))
def is_disabled_ipv6(dev='default'):
def is_disabled_ipv6(dev="default"):
try:
with open('/proc/sys/net/ipv6/conf/%s/disable_ipv6' % dev) as f:
with open("/proc/sys/net/ipv6/conf/%s/disable_ipv6" % dev) as f:
return int(f.read())
except IOError as e:
if e.errno == errno.ENOENT:

View File

@ -61,7 +61,7 @@ def validate_capabilities(state, capabilities):
def validate_interface_capabilities(ifaces_state, capabilities):
ifaces_types = [iface_state.get('type') for iface_state in ifaces_state]
ifaces_types = [iface_state.get("type") for iface_state in ifaces_state]
has_ovs_capability = nm.ovs.CAPABILITY in capabilities
for iface_type in ifaces_types:
is_ovs_type = iface_type in (
@ -84,16 +84,16 @@ def validate_link_aggregation_state(desired_state, current_state):
available_ifaces = {
ifname
for ifname, ifstate in desired_state.interfaces.items()
if ifstate.get('state') != 'absent'
if ifstate.get("state") != "absent"
}
available_ifaces |= set(current_state.interfaces)
specified_slaves = set()
for iface_state in desired_state.interfaces.values():
if iface_state.get('state') != 'absent':
link_aggregation = iface_state.get('link-aggregation')
if iface_state.get("state") != "absent":
link_aggregation = iface_state.get("link-aggregation")
if link_aggregation:
slaves = set(link_aggregation.get('slaves', []))
slaves = set(link_aggregation.get("slaves", []))
if not (slaves <= available_ifaces):
raise NmstateValueError(
"Link aggregation has missing slave: {}".format(
@ -111,7 +111,7 @@ def validate_link_aggregation_state(desired_state, current_state):
def validate_dhcp(state):
for iface_state in state[Constants.INTERFACES]:
for family in ('ipv4', 'ipv6'):
for family in ("ipv4", "ipv6"):
ip = iface_state.get(family, {})
if (
ip.get(InterfaceIP.ENABLED)
@ -121,7 +121,7 @@ def validate_dhcp(state):
)
):
logging.warning(
'%s addresses are ignored when ' 'dynamic IP is enabled',
"%s addresses are ignored when " "dynamic IP is enabled",
family,
)
@ -136,7 +136,7 @@ def validate_dns(state):
)
if len(dns_servers) > 2:
raise NmstateNotImplementedError(
'Nmstate only support at most 2 DNS name servers'
"Nmstate only support at most 2 DNS name servers"
)
@ -240,7 +240,7 @@ def _assert_vxlan_has_missing_attribute(state, *attributes):
vxlan_config_set = set(vxlan_config)
if not (attributes_set <= vxlan_config_set):
raise NmstateValueError(
'Vxlan tunnel {} has missing {}: {}'.format(
"Vxlan tunnel {} has missing {}: {}".format(
state[schema.Interface.NAME],
attributes_set.difference(vxlan_config_set),
state,
@ -256,11 +256,11 @@ def _assert_vlan_filtering_trunk_tags(ports_state):
if vlan_mode == LB.Port.Vlan.Mode.ACCESS:
if trunk_tags:
raise NmstateValueError('Access port cannot have trunk tags')
raise NmstateValueError("Access port cannot have trunk tags")
elif port_vlan_state:
if not trunk_tags:
raise NmstateValueError(
'A trunk port needs to specify trunk tags'
"A trunk port needs to specify trunk tags"
)
for trunk_tag in trunk_tags:
_assert_vlan_filtering_trunk_tag(trunk_tag)
@ -272,7 +272,7 @@ def _assert_vlan_filtering_trunk_tag(trunk_tag_state):
if vlan_id and vlan_id_range:
raise NmstateValueError(
'Trunk port cannot be configured by both id and range: {}'.format(
"Trunk port cannot be configured by both id and range: {}".format(
trunk_tag_state
)
)
@ -285,7 +285,7 @@ def _assert_vlan_filtering_trunk_tag(trunk_tag_state):
<= set(vlan_id_range)
):
raise NmstateValueError(
'Trunk port range requires min / max keys: {}'.format(
"Trunk port range requires min / max keys: {}".format(
vlan_id_range
)
)

View File

@ -39,7 +39,7 @@ from libnmstate.schema import Route
def main():
logging.basicConfig(
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
format="%(asctime)s %(name)-12s %(levelname)-8s %(message)s",
level=logging.DEBUG,
)
@ -60,100 +60,100 @@ def main():
def setup_subcommand_commit(subparsers):
parser_commit = subparsers.add_parser('commit', help='Commit a change')
parser_commit = subparsers.add_parser("commit", help="Commit a change")
parser_commit.add_argument(
'checkpoint', nargs='?', default=None, help='checkpoint to commit'
"checkpoint", nargs="?", default=None, help="checkpoint to commit"
)
parser_commit.set_defaults(func=commit)
def setup_subcommand_edit(subparsers):
parser_edit = subparsers.add_parser(
'edit', help='Edit network state in EDITOR'
"edit", help="Edit network state in EDITOR"
)
parser_edit.set_defaults(func=edit)
parser_edit.add_argument(
'--json',
help='Edit as JSON',
"--json",
help="Edit as JSON",
default=True,
action='store_false',
dest='yaml',
action="store_false",
dest="yaml",
)
parser_edit.add_argument(
'only',
default='*',
nargs='?',
"only",
default="*",
nargs="?",
metavar=Interface.KEY,
help='Edit only specified interfaces (comma-separated)',
help="Edit only specified interfaces (comma-separated)",
)
parser_edit.add_argument(
'--no-verify',
action='store_false',
dest='verify',
"--no-verify",
action="store_false",
dest="verify",
default=True,
help='Do not verify that the state was completely set and disable '
'rollback to previous state.',
help="Do not verify that the state was completely set and disable "
"rollback to previous state.",
)
def setup_subcommand_rollback(subparsers):
parser_rollback = subparsers.add_parser(
'rollback', help='Rollback a change'
"rollback", help="Rollback a change"
)
parser_rollback.add_argument(
'checkpoint', nargs='?', default=None, help='checkpoint to roll back'
"checkpoint", nargs="?", default=None, help="checkpoint to roll back"
)
parser_rollback.set_defaults(func=rollback)
def setup_subcommand_set(subparsers):
parser_set = subparsers.add_parser('set', help='Set network state')
parser_set = subparsers.add_parser("set", help="Set network state")
parser_set.add_argument(
'file',
help='File containing desired state. '
'stdin is used when no file is specified.',
nargs='*',
"file",
help="File containing desired state. "
"stdin is used when no file is specified.",
nargs="*",
)
parser_set.add_argument(
'--no-verify',
action='store_false',
dest='verify',
"--no-verify",
action="store_false",
dest="verify",
default=True,
help='Do not verify that the state was completely set and disable '
'rollback to previous state',
help="Do not verify that the state was completely set and disable "
"rollback to previous state",
)
parser_set.add_argument(
'--no-commit',
action='store_false',
dest='commit',
"--no-commit",
action="store_false",
dest="commit",
default=True,
help='Do not commit new state after verification',
help="Do not commit new state after verification",
)
parser_set.add_argument(
'--timeout',
"--timeout",
type=int,
default=60,
help='Timeout in seconds before reverting uncommited changes.',
help="Timeout in seconds before reverting uncommited changes.",
)
parser_set.set_defaults(func=apply)
def setup_subcommand_show(subparsers):
parser_show = subparsers.add_parser('show', help='Show network state')
parser_show = subparsers.add_parser("show", help="Show network state")
parser_show.set_defaults(func=show)
parser_show.add_argument(
'--json',
help='Edit as JSON',
"--json",
help="Edit as JSON",
default=True,
action='store_false',
dest='yaml',
action="store_false",
dest="yaml",
)
parser_show.add_argument(
'only',
default='*',
nargs='?',
"only",
default="*",
nargs="?",
metavar=Interface.KEY,
help='Show only specified interfaces (comma-separated)',
help="Show only specified interfaces (comma-separated)",
)
@ -169,23 +169,23 @@ def edit(args):
state = _filter_state(libnmstate.show(), args.only)
if not state[Interface.KEY]:
sys.stderr.write('ERROR: No such interface\n')
sys.stderr.write("ERROR: No such interface\n")
return os.EX_USAGE
pretty_state = PrettyState(state)
if args.yaml:
suffix = '.yaml'
suffix = ".yaml"
txtstate = pretty_state.yaml
else:
suffix = '.json'
suffix = ".json"
txtstate = pretty_state.json
new_state = _get_edited_state(txtstate, suffix, args.yaml)
if not new_state:
return os.EX_DATAERR
print('Applying the following state: ')
print("Applying the following state: ")
print_state(new_state, use_yaml=args.yaml)
libnmstate.apply(new_state, verify_change=args.verify)
@ -207,7 +207,7 @@ def show(args):
def apply(args):
if args.file:
for statefile in args.file:
if statefile == '-' and not os.path.isfile(statefile):
if statefile == "-" and not os.path.isfile(statefile):
statedata = sys.stdin.read()
else:
with open(statefile) as statefile:
@ -220,14 +220,14 @@ def apply(args):
statedata = sys.stdin.read()
return apply_state(statedata, args.verify, args.commit, args.timeout)
else:
sys.stderr.write('ERROR: No state specified\n')
sys.stderr.write("ERROR: No state specified\n")
return 1
def apply_state(statedata, verify_change, commit, timeout):
use_yaml = False
# JSON dictionaries start with a curly brace
if statedata[0] == '{':
if statedata[0] == "{":
state = json.loads(statedata)
else:
state = yaml.load(statedata, Loader=yaml.SafeLoader)
@ -236,24 +236,24 @@ def apply_state(statedata, verify_change, commit, timeout):
try:
checkpoint = libnmstate.apply(state, verify_change, commit, timeout)
except NmstatePermissionError as e:
sys.stderr.write('ERROR: Missing permissions:{}\n'.format(str(e)))
sys.stderr.write("ERROR: Missing permissions:{}\n".format(str(e)))
return os.EX_NOPERM
except NmstateConflictError:
sys.stderr.write(
'ERROR: State editing already in progress.\n'
'Commit, roll back or wait before retrying.\n'
"ERROR: State editing already in progress.\n"
"Commit, roll back or wait before retrying.\n"
)
return os.EX_UNAVAILABLE
print('Desired state applied: ')
print("Desired state applied: ")
print_state(state, use_yaml=use_yaml)
if checkpoint:
print('Checkpoint: {}'.format(checkpoint))
print("Checkpoint: {}".format(checkpoint))
def _filter_state(state, whitelist):
if whitelist != '*':
patterns = [p for p in whitelist.split(',')]
if whitelist != "*":
patterns = [p for p in whitelist.split(",")]
state[Interface.KEY] = _filter_interfaces(state, patterns)
state[Route.KEY] = _filter_routes(state, patterns)
return state
@ -268,7 +268,7 @@ def _filter_interfaces(state, patterns):
for interface in state[Interface.KEY]:
for pattern in patterns:
if fnmatch.fnmatch(interface['name'], pattern):
if fnmatch.fnmatch(interface["name"], pattern):
showinterfaces.append(interface)
break
return showinterfaces
@ -291,11 +291,11 @@ def _get_edited_state(txtstate, suffix, use_yaml):
def _run_editor(txtstate, suffix):
editor = os.environ.get('EDITOR', 'vi')
editor = os.environ.get("EDITOR", "vi")
with tempfile.NamedTemporaryFile(
suffix=suffix, prefix='nmstate-'
suffix=suffix, prefix="nmstate-"
) as statefile:
statefile.write(txtstate.encode('utf-8'))
statefile.write(txtstate.encode("utf-8"))
statefile.flush()
try:
@ -304,25 +304,25 @@ def _run_editor(txtstate, suffix):
return statefile.read()
except subprocess.CalledProcessError:
sys.stderr.write('Error running editor, aborting...\n')
sys.stderr.write("Error running editor, aborting...\n")
return None
def _parse_state(txtstate, parse_yaml):
error = ''
error = ""
state = {}
if parse_yaml:
try:
state = yaml.load(txtstate, Loader=yaml.SafeLoader)
except yaml.parser.ParserError as e:
error = 'Invalid YAML syntax: %s\n' % e
error = "Invalid YAML syntax: %s\n" % e
except yaml.parser.ScannerError as e:
error = 'Invalid YAML syntax: %s\n' % e
error = "Invalid YAML syntax: %s\n" % e
else:
try:
state = json.loads(txtstate)
except ValueError as e:
error = 'Invalid JSON syntax: %s\n' % e
error = "Invalid JSON syntax: %s\n" % e
if not error and Interface.KEY not in state:
# Allow editing routes only.
@ -337,16 +337,16 @@ def _try_edit_again(error):
edited again and False otherwise.
"""
sys.stderr.write('ERROR: ' + error)
response = ''
while response not in ('y', 'n'):
sys.stderr.write("ERROR: " + error)
response = ""
while response not in ("y", "n"):
response = input(
'Try again? [y,n]:\n'
'y - yes, start editor again\n'
'n - no, throw away my changes\n'
'> '
"Try again? [y,n]:\n"
"y - yes, start editor again\n"
"n - no, throw away my changes\n"
"> "
).lower()
if response == 'n':
if response == "n":
return False
return True

View File

@ -1,3 +1,2 @@
[tool.black]
line-length = 79
skip-string-normalization = true

View File

@ -3,52 +3,52 @@ from datetime import date
def readme():
with open('README.md') as f:
with open("README.md") as f:
return f.read()
def requirements():
req = []
with open('requirements.txt') as fd:
with open("requirements.txt") as fd:
for line in fd:
line.strip()
if not line.startswith('#'):
if not line.startswith("#"):
req.append(line)
return req
def get_version():
with open('VERSION') as f:
with open("VERSION") as f:
version = f.read().strip()
return version
def gen_manpage():
manpage = ""
with open('doc/nmstatectl.8.in') as f:
with open("doc/nmstatectl.8.in") as f:
manpage = f.read()
manpage = manpage.replace("@DATE@", date.today().strftime("%B %d, %Y"))
manpage = manpage.replace("@VERSION@", get_version())
with open('doc/nmstatectl.8', 'w') as f:
with open("doc/nmstatectl.8", "w") as f:
f.write(manpage)
return [('share/man/man8', ['doc/nmstatectl.8'])]
return [("share/man/man8", ["doc/nmstatectl.8"])]
setup(
name='nmstate',
name="nmstate",
version=get_version(),
description='Declarative network manager API',
description="Declarative network manager API",
author="Edward Haas",
author_email="ehaas@redhat.com",
long_description=readme(),
long_description_content_type='text/markdown',
url='https://nmstate.github.io/',
license='LGPL2.1+',
long_description_content_type="text/markdown",
url="https://nmstate.github.io/",
license="LGPL2.1+",
packages=find_packages(),
install_requires=requirements(),
entry_points={
'console_scripts': ['nmstatectl = nmstatectl.nmstatectl:main']
"console_scripts": ["nmstatectl = nmstatectl.nmstatectl:main"]
},
package_data={'libnmstate': ['schemas/operational-state.yaml']},
package_data={"libnmstate": ["schemas/operational-state.yaml"]},
data_files=gen_manpage(),
)

View File

@ -66,67 +66,67 @@ interfaces:
"""
@mock.patch('sys.argv', ['nmstatectl', 'set', 'mystate.json'])
@mock.patch("sys.argv", ["nmstatectl", "set", "mystate.json"])
@mock.patch.object(
nmstatectl.libnmstate,
'apply',
"apply",
lambda state, verify_change, commit, timeout: None,
)
@mock.patch.object(
nmstatectl, 'open', mock.mock_open(read_data='{}'), create=True
nmstatectl, "open", mock.mock_open(read_data="{}"), create=True
)
def test_run_ctl_directly_set():
nmstatectl.main()
@mock.patch('sys.argv', ['nmstatectl', 'show'])
@mock.patch.object(nmstatectl.libnmstate, 'show', lambda: {})
@mock.patch("sys.argv", ["nmstatectl", "show"])
@mock.patch.object(nmstatectl.libnmstate, "show", lambda: {})
def test_run_ctl_directly_show_empty():
nmstatectl.main()
@mock.patch('sys.argv', ['nmstatectl', 'show', 'non_existing_interface'])
@mock.patch("sys.argv", ["nmstatectl", "show", "non_existing_interface"])
@mock.patch.object(
nmstatectl.libnmstate, 'show', lambda: json.loads(LO_JSON_STATE)
nmstatectl.libnmstate, "show", lambda: json.loads(LO_JSON_STATE)
)
@mock.patch('nmstatectl.nmstatectl.sys.stdout', new_callable=io.StringIO)
@mock.patch("nmstatectl.nmstatectl.sys.stdout", new_callable=io.StringIO)
def test_run_ctl_directly_show_only_empty(mock_stdout):
nmstatectl.main()
assert mock_stdout.getvalue() == EMPTY_YAML_STATE
@mock.patch('sys.argv', ['nmstatectl', 'show', 'lo'])
@mock.patch("sys.argv", ["nmstatectl", "show", "lo"])
@mock.patch.object(
nmstatectl.libnmstate, 'show', lambda: json.loads(LO_JSON_STATE)
nmstatectl.libnmstate, "show", lambda: json.loads(LO_JSON_STATE)
)
@mock.patch('nmstatectl.nmstatectl.sys.stdout', new_callable=io.StringIO)
@mock.patch("nmstatectl.nmstatectl.sys.stdout", new_callable=io.StringIO)
def test_run_ctl_directly_show_only(mock_stdout):
nmstatectl.main()
assert mock_stdout.getvalue() == LO_YAML_STATE
@mock.patch(
'sys.argv', ['nmstatectl', 'show', '--json', 'non_existing_interface']
"sys.argv", ["nmstatectl", "show", "--json", "non_existing_interface"]
)
@mock.patch.object(
nmstatectl.libnmstate, 'show', lambda: json.loads(LO_JSON_STATE)
nmstatectl.libnmstate, "show", lambda: json.loads(LO_JSON_STATE)
)
@mock.patch('nmstatectl.nmstatectl.sys.stdout', new_callable=io.StringIO)
@mock.patch("nmstatectl.nmstatectl.sys.stdout", new_callable=io.StringIO)
def test_run_ctl_directly_show_json_only_empty(mock_stdout):
nmstatectl.main()
assert mock_stdout.getvalue() == EMPTY_JSON_STATE
@mock.patch('sys.argv', ['nmstatectl', 'show', '--json', 'lo'])
@mock.patch("sys.argv", ["nmstatectl", "show", "--json", "lo"])
@mock.patch.object(
nmstatectl.libnmstate, 'show', lambda: json.loads(LO_JSON_STATE)
nmstatectl.libnmstate, "show", lambda: json.loads(LO_JSON_STATE)
)
@mock.patch('nmstatectl.nmstatectl.sys.stdout', new_callable=io.StringIO)
@mock.patch("nmstatectl.nmstatectl.sys.stdout", new_callable=io.StringIO)
def test_run_ctl_directly_show_json_only(mock_stdout):
nmstatectl.main()
assert mock_stdout.getvalue() == LO_JSON_STATE
def test_run_ctl_executable():
rc = subprocess.call(['nmstatectl', '--help'])
rc = subprocess.call(["nmstatectl", "--help"])
assert rc == 0

View File

@ -41,10 +41,10 @@ from .testlib.bridgelib import linux_bridge
from .testlib.bridgelib import add_port_to_bridge
from .testlib.bridgelib import create_bridge_subtree_state
BOND99 = 'bond99'
BOND99 = "bond99"
MAC0 = '02:ff:ff:ff:ff:00'
MAC1 = '02:ff:ff:ff:ff:01'
MAC0 = "02:ff:ff:ff:ff:00"
MAC1 = "02:ff:ff:ff:ff:01"
BOND99_YAML_BASE = """
interfaces:
@ -65,7 +65,7 @@ def setup_remove_bond99():
remove_bond = {
Interface.KEY: [
{
Interface.NAME: 'bond99',
Interface.NAME: "bond99",
Interface.TYPE: InterfaceType.BOND,
Interface.STATE: InterfaceState.ABSENT,
}
@ -80,7 +80,7 @@ def bond99_with_2_slaves(eth1_up, eth2_up):
eth1_up[Interface.KEY][0][Interface.NAME],
eth2_up[Interface.KEY][0][Interface.NAME],
]
with bond_interface('bond99', slaves) as state:
with bond_interface("bond99", slaves) as state:
yield state
@ -133,7 +133,7 @@ def test_remove_bond_with_minimum_desired_state(eth1_up, eth2_up):
def test_add_bond_without_slaves():
with bond_interface(name='bond99', slaves=[]) as state:
with bond_interface(name="bond99", slaves=[]) as state:
assert state[Interface.KEY][0][Bond.CONFIG_SUBTREE][Bond.SLAVES] == []
@ -142,14 +142,14 @@ def test_add_bond_with_slaves_and_ipv4(eth1_up, eth2_up, setup_remove_bond99):
desired_bond_state = {
Interface.KEY: [
{
Interface.NAME: 'bond99',
Interface.NAME: "bond99",
Interface.TYPE: InterfaceType.BOND,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
InterfaceIPv4.ENABLED: True,
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '192.168.122.250',
InterfaceIPv4.ADDRESS_IP: "192.168.122.250",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
}
],
@ -160,7 +160,7 @@ def test_add_bond_with_slaves_and_ipv4(eth1_up, eth2_up, setup_remove_bond99):
eth1_up[Interface.KEY][0][Interface.NAME],
eth2_up[Interface.KEY][0][Interface.NAME],
],
Bond.OPTIONS_SUBTREE: {'miimon': '140'},
Bond.OPTIONS_SUBTREE: {"miimon": "140"},
},
}
]
@ -176,14 +176,14 @@ def test_rollback_for_bond(eth1_up, eth2_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'bond99',
Interface.NAME: "bond99",
Interface.TYPE: InterfaceType.BOND,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
InterfaceIPv4.ENABLED: True,
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '192.168.122.250',
InterfaceIPv4.ADDRESS_IP: "192.168.122.250",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
}
],
@ -194,13 +194,13 @@ def test_rollback_for_bond(eth1_up, eth2_up):
eth1_up[Interface.KEY][0][Interface.NAME],
eth2_up[Interface.KEY][0][Interface.NAME],
],
Bond.OPTIONS_SUBTREE: {'miimon': '140'},
Bond.OPTIONS_SUBTREE: {"miimon": "140"},
},
}
]
}
desired_state[Interface.KEY][0]['invalid_key'] = 'foo'
desired_state[Interface.KEY][0]["invalid_key"] = "foo"
with pytest.raises(NmstateVerificationError):
libnmstate.apply(desired_state)
@ -333,18 +333,18 @@ def test_bond_with_empty_ipv6_static_address(eth1_up):
}
}
with bond_interface(
name='bond99', slaves=['eth1'], extra_iface_state=extra_iface_state
name="bond99", slaves=["eth1"], extra_iface_state=extra_iface_state
) as bond_state:
assertlib.assert_state(bond_state)
assertlib.assert_absent('bond99')
assertlib.assert_absent("bond99")
def test_create_vlan_over_a_bond_slave(bond99_with_slave):
bond_ifstate = bond99_with_slave[Interface.KEY][0]
bond_slave_ifname = bond_ifstate[Bond.CONFIG_SUBTREE][Bond.SLAVES][0]
vlan_id = 102
vlan_iface_name = '{}.{}'.format(bond_slave_ifname, vlan_id)
vlan_iface_name = "{}.{}".format(bond_slave_ifname, vlan_id)
with vlan_interface(
vlan_iface_name, vlan_id, bond_slave_ifname
) as desired_state:
@ -354,11 +354,11 @@ def test_create_vlan_over_a_bond_slave(bond99_with_slave):
def test_create_linux_bridge_over_bond(bond99_with_slave):
port_state = {
'stp-hairpin-mode': False,
'stp-path-cost': 100,
'stp-priority': 32,
"stp-hairpin-mode": False,
"stp-path-cost": 100,
"stp-priority": 32,
}
bridge_name = 'linux-br0'
bridge_name = "linux-br0"
bridge_state = add_port_to_bridge(
create_bridge_subtree_state(), BOND99, port_state
)
@ -370,7 +370,7 @@ def test_create_linux_bridge_over_bond(bond99_with_slave):
strict=True, reason="https://nmstate.atlassian.net/browse/NMSTATE-272"
)
def test_preserve_bond_after_bridge_removal(bond99_with_slave):
bridge_name = 'linux-br0'
bridge_name = "linux-br0"
bridge_state = add_port_to_bridge(create_bridge_subtree_state(), BOND99)
with linux_bridge(bridge_name, bridge_state) as desired_state:
assertlib.assert_state_match(desired_state)
@ -380,7 +380,7 @@ def test_preserve_bond_after_bridge_removal(bond99_with_slave):
def test_create_vlan_over_a_bond(bond99_with_slave):
vlan_base_iface = bond99_with_slave[Interface.KEY][0][Interface.NAME]
vlan_id = 102
vlan_iface_name = '{}.{}'.format(vlan_base_iface, vlan_id)
vlan_iface_name = "{}.{}".format(vlan_base_iface, vlan_id)
with vlan_interface(
vlan_iface_name, vlan_id, vlan_base_iface
) as desired_state:

View File

@ -33,29 +33,29 @@ OS: {osname}
"""
@pytest.fixture(scope='session', autouse=True)
@pytest.fixture(scope="session", autouse=True)
def logging_setup():
logging.basicConfig(
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
format="%(asctime)s %(name)-12s %(levelname)-8s %(message)s",
level=logging.DEBUG,
)
@pytest.fixture(scope='session', autouse=True)
@pytest.fixture(scope="session", autouse=True)
def ethx_init(diff_initial_state):
""" Remove any existing definitions on the ethX interfaces. """
ifacelib.ifaces_init('eth1', 'eth2')
ifacelib.ifaces_init("eth1", "eth2")
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def eth1_up():
with ifacelib.iface_up('eth1') as ifstate:
with ifacelib.iface_up("eth1") as ifstate:
yield ifstate
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def eth2_up():
with ifacelib.iface_up('eth2') as ifstate:
with ifacelib.iface_up("eth2") as ifstate:
yield ifstate
@ -63,7 +63,7 @@ port0_up = eth1_up
port1_up = eth2_up
@pytest.fixture(scope='session', autouse=True)
@pytest.fixture(scope="session", autouse=True)
def diff_initial_state():
old_state = libnmstate.show()
yield
@ -71,8 +71,8 @@ def diff_initial_state():
if old_state != new_state:
warnings.warn(
'Network state after test run does not match network state '
'before test run:\n {}\n'.format(
"Network state after test run does not match network state "
"before test run:\n {}\n".format(
libnmstate.prettystate.format_desired_current_state_diff(
old_state, new_state
)
@ -82,19 +82,19 @@ def diff_initial_state():
def pytest_report_header(config):
return REPORT_HEADER.format(
rpms=_get_package_nvr('NetworkManager'), osname=_get_osname()
rpms=_get_package_nvr("NetworkManager"), osname=_get_osname()
)
def _get_package_nvr(package):
return (
subprocess.check_output(['rpm', '-q', package]).strip().decode('utf-8')
subprocess.check_output(["rpm", "-q", package]).strip().decode("utf-8")
)
def _get_osname():
with open('/etc/os-release') as os_release:
with open("/etc/os-release") as os_release:
for line in os_release.readlines():
if line.startswith('PRETTY_NAME='):
return line.split('=', maxsplit=1)[1].strip().strip('"')
return ''
if line.startswith("PRETTY_NAME="):
return line.split("=", maxsplit=1)[1].strip().strip('"')
return ""

View File

@ -31,21 +31,21 @@ from libnmstate.schema import InterfaceType
from libnmstate.schema import Route
IPV4_DNS_NAMESERVERS = ['8.8.8.8', '1.1.1.1']
IPV6_DNS_NAMESERVERS = ['2001:4860:4860::8888', '2606:4700:4700::1111']
EXAMPLE_SEARCHES = ['example.org', 'example.com']
IPV4_DNS_NAMESERVERS = ["8.8.8.8", "1.1.1.1"]
IPV6_DNS_NAMESERVERS = ["2001:4860:4860::8888", "2606:4700:4700::1111"]
EXAMPLE_SEARCHES = ["example.org", "example.com"]
parametrize_ip_ver = pytest.mark.parametrize(
'dns_config',
"dns_config",
[
({DNS.SERVER: IPV4_DNS_NAMESERVERS, DNS.SEARCH: EXAMPLE_SEARCHES}),
({DNS.SERVER: IPV6_DNS_NAMESERVERS, DNS.SEARCH: EXAMPLE_SEARCHES}),
],
ids=['ipv4', 'ipv6'],
ids=["ipv4", "ipv6"],
)
@pytest.fixture(scope='function', autouse=True)
@pytest.fixture(scope="function", autouse=True)
def dns_test_env(eth1_up, eth2_up):
yield
# Remove DNS config as it be saved in eth1 or eth2 which might trigger
@ -101,7 +101,7 @@ def test_dns_edit_ipv6_nameserver_before_ipv4():
@pytest.mark.xfail(
raises=NmstateNotImplementedError,
reason='https://nmstate.atlassian.net/browse/NMSTATE-220',
reason="https://nmstate.atlassian.net/browse/NMSTATE-220",
strict=True,
)
def test_dns_edit_three_nameservers():
@ -158,11 +158,11 @@ def test_preserve_dns_config():
Route.KEY: {
Route.CONFIG: [
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.STATE: Route.STATE_ABSENT,
},
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.STATE: Route.STATE_ABSENT,
},
]
@ -203,13 +203,13 @@ def test_preserve_dns_config_with_empty_state(setup_ipv4_ipv6_name_server):
def _get_test_iface_states():
return [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.STATE: InterfaceState.UP,
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV4: {
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '192.0.2.251',
InterfaceIPv4.ADDRESS_IP: "192.0.2.251",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
}
],
@ -219,7 +219,7 @@ def _get_test_iface_states():
Interface.IPV6: {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: '2001:db8:1::1',
InterfaceIPv6.ADDRESS_IP: "2001:db8:1::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
}
],
@ -229,13 +229,13 @@ def _get_test_iface_states():
},
},
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.STATE: InterfaceState.UP,
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV4: {
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '198.51.100.1',
InterfaceIPv4.ADDRESS_IP: "198.51.100.1",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
}
],
@ -245,7 +245,7 @@ def _get_test_iface_states():
Interface.IPV6: {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: '2001:db8:2::1',
InterfaceIPv6.ADDRESS_IP: "2001:db8:2::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
}
],
@ -260,15 +260,15 @@ def _get_test_iface_states():
def _gen_default_gateway_route():
return [
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.METRIC: 200,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.NEXT_HOP_INTERFACE: "eth1",
},
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '2001:db8:2::f',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "2001:db8:2::f",
Route.NEXT_HOP_INTERFACE: "eth1",
},
]

View File

@ -47,28 +47,28 @@ from .testlib.bridgelib import linux_bridge
DEFAULT_TIMEOUT = 20
IPV4_ADDRESS1 = '192.0.2.251'
IPV4_ADDRESS2 = '192.0.2.252'
IPV6_ADDRESS1 = '2001:db8:1::1'
IPV6_ADDRESS2 = '2001:db8:2::1'
IPV4_CLASSLESS_ROUTE_DST_NET1 = '198.51.100.0/24'
IPV4_CLASSLESS_ROUTE_NEXT_HOP1 = '192.0.2.1'
IPV6_CLASSLESS_ROUTE_PREFIX = '2001:db8:f'
IPV6_CLASSLESS_ROUTE_DST_NET1 = '{}::/64'.format(IPV6_CLASSLESS_ROUTE_PREFIX)
IPV4_ADDRESS1 = "192.0.2.251"
IPV4_ADDRESS2 = "192.0.2.252"
IPV6_ADDRESS1 = "2001:db8:1::1"
IPV6_ADDRESS2 = "2001:db8:2::1"
IPV4_CLASSLESS_ROUTE_DST_NET1 = "198.51.100.0/24"
IPV4_CLASSLESS_ROUTE_NEXT_HOP1 = "192.0.2.1"
IPV6_CLASSLESS_ROUTE_PREFIX = "2001:db8:f"
IPV6_CLASSLESS_ROUTE_DST_NET1 = "{}::/64".format(IPV6_CLASSLESS_ROUTE_PREFIX)
TEST_BRIDGE_NIC = 'brtest0'
TEST_BRIDGE_NIC = "brtest0"
DHCP_SRV_NIC = 'dhcpsrv'
DHCP_CLI_NIC = 'dhcpcli'
DHCP_SRV_NIC = "dhcpsrv"
DHCP_CLI_NIC = "dhcpcli"
DHCP_SRV_IP4 = IPV4_ADDRESS1
DHCP_SRV_IP6 = IPV6_ADDRESS1
DHCP_SRV_IP6_2 = "{}::1".format(IPV6_CLASSLESS_ROUTE_PREFIX)
DHCP_SRV_IP4_PREFIX = '192.0.2'
DHCP_SRV_IP6_PREFIX = '2001:db8:1'
DHCP_SRV_IP6_NETWORK = '{}::/64'.format(DHCP_SRV_IP6_PREFIX)
DHCP_SRV_IP4_PREFIX = "192.0.2"
DHCP_SRV_IP6_PREFIX = "2001:db8:1"
DHCP_SRV_IP6_NETWORK = "{}::/64".format(DHCP_SRV_IP6_PREFIX)
IPV6_DEFAULT_GATEWAY = '::/0'
IPV4_DEFAULT_GATEWAY = '0.0.0.0/0'
IPV6_DEFAULT_GATEWAY = "::/0"
IPV4_DEFAULT_GATEWAY = "0.0.0.0/0"
DNSMASQ_CONF_STR = """
interface={iface}
@ -80,25 +80,25 @@ dhcp-option=option:classless-static-route,{classless_rt},{classless_rt_dst}
dhcp-option=option:dns-server,{v4_dns_server}
""".format(
**{
'iface': DHCP_SRV_NIC,
'ipv4_prefix': DHCP_SRV_IP4_PREFIX,
'ipv6_prefix': DHCP_SRV_IP6_PREFIX,
'classless_rt': IPV4_CLASSLESS_ROUTE_DST_NET1,
'classless_rt_dst': IPV4_CLASSLESS_ROUTE_NEXT_HOP1,
'v4_dns_server': DHCP_SRV_IP4,
'ipv6_classless_route': IPV6_CLASSLESS_ROUTE_PREFIX,
"iface": DHCP_SRV_NIC,
"ipv4_prefix": DHCP_SRV_IP4_PREFIX,
"ipv6_prefix": DHCP_SRV_IP6_PREFIX,
"classless_rt": IPV4_CLASSLESS_ROUTE_DST_NET1,
"classless_rt_dst": IPV4_CLASSLESS_ROUTE_NEXT_HOP1,
"v4_dns_server": DHCP_SRV_IP4,
"ipv6_classless_route": IPV6_CLASSLESS_ROUTE_PREFIX,
}
)
DNSMASQ_CONF_PATH = '/etc/dnsmasq.d/nmstate.conf'
DNSMASQ_CONF_PATH = "/etc/dnsmasq.d/nmstate.conf"
# Docker does not allow NetworkManager to edit /etc/resolv.conf.
# Have to read NetworkManager internal resolv.conf
RESOLV_CONF_PATH = '/var/run/NetworkManager/resolv.conf'
RESOLV_CONF_PATH = "/var/run/NetworkManager/resolv.conf"
SYSFS_DISABLE_IPV6_FILE = '/proc/sys/net/ipv6/conf/{}/disable_ipv6'.format(
SYSFS_DISABLE_IPV6_FILE = "/proc/sys/net/ipv6/conf/{}/disable_ipv6".format(
DHCP_SRV_NIC
)
SYSFS_DISABLE_RA_SRV = '/proc/sys/net/ipv6/conf/{}/accept_ra'.format(
SYSFS_DISABLE_RA_SRV = "/proc/sys/net/ipv6/conf/{}/accept_ra".format(
DHCP_SRV_NIC
)
@ -109,15 +109,15 @@ except NameError:
FileNotFoundError = IOError
@pytest.fixture(scope='module')
@pytest.fixture(scope="module")
def dhcp_env():
try:
_create_veth_pair()
_setup_dhcp_nics()
with open(DNSMASQ_CONF_PATH, 'w') as fd:
with open(DNSMASQ_CONF_PATH, "w") as fd:
fd.write(DNSMASQ_CONF_STR)
assert libcmd.exec_cmd(['systemctl', 'restart', 'dnsmasq'])[0] == 0
assert libcmd.exec_cmd(["systemctl", "restart", "dnsmasq"])[0] == 0
yield
finally:
@ -251,7 +251,7 @@ def test_dhcp_with_addresses(dhcpcli_up):
def test_ipv4_dhcp_on_bond(dhcpcli_up):
ipv4_state = {Interface.IPV4: create_ipv4_state(enabled=True, dhcp=True)}
with bondlib.bond_interface(
'bond99', slaves=[DHCP_CLI_NIC], extra_iface_state=ipv4_state
"bond99", slaves=[DHCP_CLI_NIC], extra_iface_state=ipv4_state
) as desired_state:
assertlib.assert_state(desired_state)
@ -574,14 +574,14 @@ def _create_veth_pair():
assert (
libcmd.exec_cmd(
[
'ip',
'link',
'add',
"ip",
"link",
"add",
DHCP_SRV_NIC,
'type',
'veth',
'peer',
'name',
"type",
"veth",
"peer",
"name",
DHCP_CLI_NIC,
]
)[0]
@ -590,20 +590,20 @@ def _create_veth_pair():
def _remove_veth_pair():
libcmd.exec_cmd(['ip', 'link', 'del', 'dev', DHCP_SRV_NIC])
libcmd.exec_cmd(["ip", "link", "del", "dev", DHCP_SRV_NIC])
def _setup_dhcp_nics():
assert libcmd.exec_cmd(['ip', 'link', 'set', DHCP_SRV_NIC, 'up'])[0] == 0
assert libcmd.exec_cmd(['ip', 'link', 'set', DHCP_CLI_NIC, 'up'])[0] == 0
assert libcmd.exec_cmd(["ip", "link", "set", DHCP_SRV_NIC, "up"])[0] == 0
assert libcmd.exec_cmd(["ip", "link", "set", DHCP_CLI_NIC, "up"])[0] == 0
assert (
libcmd.exec_cmd(
[
'ip',
'addr',
'add',
"ip",
"addr",
"add",
"{}/24".format(DHCP_SRV_IP4),
'dev',
"dev",
DHCP_SRV_NIC,
]
)[0]
@ -611,25 +611,25 @@ def _setup_dhcp_nics():
)
assert (
libcmd.exec_cmd(
['nmcli', 'device', 'set', DHCP_CLI_NIC, 'managed', 'yes']
["nmcli", "device", "set", DHCP_CLI_NIC, "managed", "yes"]
)[0]
== 0
)
# This stop dhcp server NIC get another IPv6 address from dnsmasq.
with open(SYSFS_DISABLE_RA_SRV, 'w') as fd:
fd.write('0')
with open(SYSFS_DISABLE_RA_SRV, "w") as fd:
fd.write("0")
with open(SYSFS_DISABLE_IPV6_FILE, 'w') as fd:
fd.write('0')
with open(SYSFS_DISABLE_IPV6_FILE, "w") as fd:
fd.write("0")
assert (
libcmd.exec_cmd(
[
'ip',
'addr',
'add',
"ip",
"addr",
"add",
"{}/64".format(DHCP_SRV_IP6),
'dev',
"dev",
DHCP_SRV_NIC,
]
)[0]
@ -639,11 +639,11 @@ def _setup_dhcp_nics():
assert (
libcmd.exec_cmd(
[
'ip',
'addr',
'add',
"ip",
"addr",
"add",
"{}/64".format(DHCP_SRV_IP6_2),
'dev',
"dev",
DHCP_SRV_NIC,
]
)[0]
@ -652,7 +652,7 @@ def _setup_dhcp_nics():
def _clean_up():
libcmd.exec_cmd(['systemctl', 'stop', 'dnsmasq'])
libcmd.exec_cmd(["systemctl", "stop", "dnsmasq"])
_remove_veth_pair()
try:
os.unlink(DNSMASQ_CONF_PATH)
@ -754,7 +754,7 @@ def _has_dhcpv6_addr(nic=DHCP_CLI_NIC):
current_state = statelib.show_only((nic,))[Interface.KEY][0]
has_dhcp_ip_addr = False
addrs = current_state[Interface.IPV6].get(InterfaceIPv6.ADDRESS, [])
logging.debug('Current IPv6 address of {}: {}'.format(nic, addrs))
logging.debug("Current IPv6 address of {}: {}".format(nic, addrs))
for addr in addrs:
if (
addr[InterfaceIPv6.ADDRESS_PREFIX_LENGTH] == 128
@ -769,7 +769,7 @@ def _has_dhcpv4_addr(nic=DHCP_CLI_NIC):
current_state = statelib.show_only((nic,))[Interface.KEY][0]
has_dhcp_ip_addr = False
addrs = current_state[Interface.IPV4].get(InterfaceIPv4.ADDRESS, [])
logging.debug('Current IPv4 address of {}: {}'.format(nic, addrs))
logging.debug("Current IPv4 address of {}: {}".format(nic, addrs))
for addr in addrs:
if (
addr[InterfaceIPv6.ADDRESS_PREFIX_LENGTH] == 24
@ -826,7 +826,7 @@ def create_ipv6_address_state(address, prefix_length):
def test_activate_dummy_without_dhcp_service():
ifstate = {
Interface.NAME: 'dummy00',
Interface.NAME: "dummy00",
Interface.TYPE: InterfaceType.DUMMY,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: create_ipv4_state(enabled=True, dhcp=True),

View File

@ -33,7 +33,7 @@ from .testlib.iproutelib import ip_monitor_assert_stable_link_up
from .testlib.vlan import vlan_interface
@pytest.fixture(scope='function', autouse=True)
@pytest.fixture(scope="function", autouse=True)
def eth1(eth1_up):
pass
@ -46,7 +46,7 @@ def eth1_with_ipv6(eth1_up):
def test_increase_iface_mtu():
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 1900
@ -56,7 +56,7 @@ def test_increase_iface_mtu():
def test_decrease_iface_mtu():
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 1400
@ -66,7 +66,7 @@ def test_decrease_iface_mtu():
def test_upper_limit_jambo_iface_mtu():
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 9000
@ -76,7 +76,7 @@ def test_upper_limit_jambo_iface_mtu():
def test_increase_more_than_jambo_iface_mtu():
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 10000
@ -86,33 +86,33 @@ def test_increase_more_than_jambo_iface_mtu():
def test_decrease_to_zero_iface_mtu():
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
origin_desired_state = copy.deepcopy(desired_state)
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 0
with pytest.raises(NmstateVerificationError) as err:
libnmstate.apply(desired_state)
assert '-mtu: 0' in err.value.args[0]
assert "-mtu: 0" in err.value.args[0]
# FIXME: Drop the sleep when the waiting logic is implemented.
time.sleep(2)
assertlib.assert_state(origin_desired_state)
def test_decrease_to_negative_iface_mtu():
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
origin_desired_state = copy.deepcopy(desired_state)
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = -1
with pytest.raises(js.ValidationError) as err:
libnmstate.apply(desired_state)
assert '-1' in err.value.args[0]
assert "-1" in err.value.args[0]
assertlib.assert_state(origin_desired_state)
def test_decrease_to_ipv6_min_ethernet_frame_size_iface_mtu(eth1_with_ipv6):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 1280
@ -122,24 +122,24 @@ def test_decrease_to_ipv6_min_ethernet_frame_size_iface_mtu(eth1_with_ipv6):
def test_decrease_to_lower_than_min_ipv6_iface_mtu(eth1_with_ipv6):
original_state = statelib.show_only(('eth1',))
original_state = statelib.show_only(("eth1",))
desired_state = copy.deepcopy(original_state)
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 1279
with pytest.raises(NmstateVerificationError) as err:
libnmstate.apply(desired_state)
assert '1279' in err.value.args[0]
assert "1279" in err.value.args[0]
# FIXME: Drop the sleep when the waiting logic is implemented.
time.sleep(2)
assertlib.assert_state(original_state)
@pytest.mark.xfail(reason='https://bugzilla.redhat.com/1751079', strict=True)
@pytest.mark.xfail(reason="https://bugzilla.redhat.com/1751079", strict=True)
def test_set_mtu_on_two_vlans_with_a_shared_base(eth1_up):
base_ifname = eth1_up[Interface.KEY][0][Interface.NAME]
v101 = vlan_interface('eth1.101', 101, base_ifname)
v102 = vlan_interface('eth1.102', 102, base_ifname)
v101 = vlan_interface("eth1.101", 101, base_ifname)
v102 = vlan_interface("eth1.102", 102, base_ifname)
with v101 as v101_state, v102 as v102_state:
desired_state = {
Interface.KEY: [
@ -156,9 +156,9 @@ def test_set_mtu_on_two_vlans_with_a_shared_base(eth1_up):
assertlib.assert_state(desired_state)
@ip_monitor_assert_stable_link_up('eth1')
@ip_monitor_assert_stable_link_up("eth1")
def test_change_mtu_with_stable_link_up(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.MTU] = 1900

View File

@ -32,54 +32,54 @@ def test_add_down_remove_vlan(eth1_up):
Test adding, downing and removing a vlan
"""
vlan_ifname = 'eth1.101'
vlan_ifname = "eth1.101"
with example_state(
'vlan101_eth1_up.yml', cleanup='vlan101_eth1_absent.yml'
"vlan101_eth1_up.yml", cleanup="vlan101_eth1_absent.yml"
) as desired_state:
assertlib.assert_state(desired_state)
with example_state('vlan101_eth1_down.yml') as desired_state:
with example_state("vlan101_eth1_down.yml") as desired_state:
assertlib.assert_absent(vlan_ifname)
assertlib.assert_absent(vlan_ifname)
@pytest.mark.xfail(
raises=NmstateLibnmError, reason='https://bugzilla.redhat.com/1724901'
raises=NmstateLibnmError, reason="https://bugzilla.redhat.com/1724901"
)
def test_add_remove_ovs_bridge(eth1_up):
with example_state(
'ovsbridge_create.yml', cleanup='ovsbridge_delete.yml'
"ovsbridge_create.yml", cleanup="ovsbridge_delete.yml"
) as desired_state:
assertlib.assert_state(desired_state)
assertlib.assert_absent('ovs-br0')
assertlib.assert_absent("ovs-br0")
def test_add_remove_linux_bridge(eth1_up):
with example_state(
'linuxbrige_eth1_up.yml', cleanup='linuxbrige_eth1_absent.yml'
"linuxbrige_eth1_up.yml", cleanup="linuxbrige_eth1_absent.yml"
) as desired_state:
assertlib.assert_state(desired_state)
assertlib.assert_absent('linux-br0')
assertlib.assert_absent("linux-br0")
def test_bond_linuxbridge_vlan(eth1_up, eth2_up):
with example_state(
'bond_linuxbridge_vlan_up.yml',
cleanup='bond_linuxbridge_vlan_absent.yml',
"bond_linuxbridge_vlan_up.yml",
cleanup="bond_linuxbridge_vlan_absent.yml",
) as desired_state:
assertlib.assert_state_match(desired_state)
assertlib.assert_absent('bond0')
assertlib.assert_absent('br0')
assertlib.assert_absent('br29')
assertlib.assert_absent('vlan29')
assertlib.assert_absent("bond0")
assertlib.assert_absent("br0")
assertlib.assert_absent("br29")
assertlib.assert_absent("vlan29")
def test_dns_edit(eth1_up):
with example_state(
'dns_edit_eth1.yml', cleanup='dns_remove.yml'
"dns_edit_eth1.yml", cleanup="dns_remove.yml"
) as desired_state:
assertlib.assert_state(desired_state)
@ -95,8 +95,8 @@ def test_add_remove_routes(eth1_up):
Test adding a strict route and removing all routes next hop to eth1.
"""
with example_state(
'eth1_add_route.yml', cleanup='eth1_del_all_routes.yml'
"eth1_add_route.yml", cleanup="eth1_del_all_routes.yml"
) as desired_state:
assertlib.assert_state(desired_state)
assertlib.assert_no_config_route_to_iface('eth1')
assertlib.assert_no_config_route_to_iface("eth1")

View File

@ -31,7 +31,7 @@ def test_set_a_down_iface_down(eth1_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.DOWN,
}
@ -45,12 +45,12 @@ def test_set_a_down_iface_down(eth1_up):
assertlib.assert_state(desired_state)
@pytest.mark.xfail(reason='Some ifaces cannot be removed', strict=True)
@pytest.mark.xfail(reason="Some ifaces cannot be removed", strict=True)
def test_removing_a_non_removable_iface(eth1_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.ABSENT,
}
@ -65,7 +65,7 @@ def test_removing_a_non_removable_iface(eth1_up):
def test_set_iface_down_without_type(eth1_up):
desired_state = {
Interface.KEY: [
{Interface.NAME: 'eth1', Interface.STATE: InterfaceState.DOWN}
{Interface.NAME: "eth1", Interface.STATE: InterfaceState.DOWN}
]
}
libnmstate.apply(desired_state)
@ -75,7 +75,7 @@ def test_set_iface_down_without_type(eth1_up):
def test_change_iface_without_type(eth1_up):
desired_state = {
Interface.KEY: [{Interface.NAME: 'eth1', Interface.MTU: 1400}]
Interface.KEY: [{Interface.NAME: "eth1", Interface.MTU: 1400}]
}
libnmstate.apply(desired_state)

View File

@ -32,16 +32,16 @@ from libnmstate.schema import InterfaceIPv4
from libnmstate.schema import InterfaceIPv6
from libnmstate.schema import InterfaceState
DUMMY_INTERFACE = 'dummy_test'
DUMMY_INTERFACE = "dummy_test"
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def ip_link_dummy():
libcmd.exec_cmd(['ip', 'link', 'add', DUMMY_INTERFACE, 'type', 'dummy'])
libcmd.exec_cmd(["ip", "link", "add", DUMMY_INTERFACE, "type", "dummy"])
try:
yield
finally:
libcmd.exec_cmd(['ip', 'link', 'del', DUMMY_INTERFACE])
libcmd.exec_cmd(["ip", "link", "del", DUMMY_INTERFACE])
@contextmanager
@ -67,14 +67,14 @@ def dummy_interface(name):
def test_iface_description_removal(eth1_up):
desired_state = eth1_up
desired_state[Interface.KEY][0][Interface.DESCRIPTION] = 'bar'
desired_state[Interface.KEY][0][Interface.DESCRIPTION] = "bar"
libnmstate.apply(desired_state)
current_state = statelib.show_only(('eth1',))
assert current_state[Interface.KEY][0][Interface.DESCRIPTION] == 'bar'
current_state = statelib.show_only(("eth1",))
assert current_state[Interface.KEY][0][Interface.DESCRIPTION] == "bar"
desired_state[Interface.KEY][0][Interface.DESCRIPTION] = ''
desired_state[Interface.KEY][0][Interface.DESCRIPTION] = ""
libnmstate.apply(desired_state)
current_state = statelib.show_only(('eth1',))
current_state = statelib.show_only(("eth1",))
assert Interface.DESCRIPTION not in current_state[Interface.KEY][0]
@ -90,7 +90,7 @@ def test_take_over_virtual_interface_and_rollback(ip_link_dummy):
with dummy_interface(DUMMY_INTERFACE) as dummy_desired_state:
assertlib.assert_state_match(dummy_desired_state)
dummy_desired_state[Interface.KEY][0]['invalid_key'] = 'foo'
dummy_desired_state[Interface.KEY][0]["invalid_key"] = "foo"
with pytest.raises(NmstateVerificationError):
libnmstate.apply(dummy_desired_state)

View File

@ -43,7 +43,7 @@ from .testlib.assertlib import assert_mac_address
from .testlib.vlan import vlan_interface
from .testlib.env import is_fedora
TEST_BRIDGE0 = 'linux-br0'
TEST_BRIDGE0 = "linux-br0"
BRIDGE_OPTIONS_YAML = """
@ -106,7 +106,7 @@ def _bridge0_with_port0(port0_up, use_port_mac=False):
def port0_vlan101(port0_up):
vlan_id = 101
vlan_base_iface = port0_up[Interface.KEY][0][Interface.NAME]
port_name = '{}.{}'.format(vlan_base_iface, vlan_id)
port_name = "{}.{}".format(vlan_base_iface, vlan_id)
with vlan_interface(port_name, vlan_id, vlan_base_iface):
state = show_only((port_name,))
yield state
@ -114,7 +114,7 @@ def port0_vlan101(port0_up):
@pytest.fixture
def bond0(port0_up):
bond_name = 'testbond0'
bond_name = "testbond0"
port_name = port0_up[Interface.KEY][0][Interface.NAME]
with bond_interface(bond_name, [port_name], create=False) as bond0:
yield bond0
@ -194,7 +194,7 @@ def test_create_vlan_as_slave_of_linux_bridge(port0_vlan101):
def test_create_vlan_over_linux_bridge(bridge0_with_port0):
vlan_base_iface = TEST_BRIDGE0
vlan_id = 101
port_name = '{}.{}'.format(vlan_base_iface, vlan_id)
port_name = "{}.{}".format(vlan_base_iface, vlan_id)
with vlan_interface(port_name, vlan_id, vlan_base_iface) as desired_state:
assertlib.assert_state(desired_state)
@ -215,8 +215,8 @@ def test_add_port_to_existing_bridge(bridge0_with_port0, port1_up):
@pytest.mark.xfail(
is_fedora(),
reason=(
'On Fedora 31+, users need to explicitly configure the port MAC '
'due to changes to the default systemd config.'
"On Fedora 31+, users need to explicitly configure the port MAC "
"due to changes to the default systemd config."
),
raises=AssertionError,
strict=True,
@ -348,7 +348,7 @@ def test_rollback_for_linux_bridge():
bridge_state = _create_bridge_subtree_config(())
with pytest.raises(NmstateVerificationError):
with linux_bridge(bridge_name, bridge_state) as desired_state:
desired_state[Interface.KEY][0]['invalid_key'] = 'foo'
desired_state[Interface.KEY][0]["invalid_key"] = "foo"
libnmstate.apply(desired_state)
time.sleep(5) # Give some time for NetworkManager to rollback
@ -378,7 +378,7 @@ def test_activate_empty_bridge_does_not_blocked_by_dhcp():
@pytest.mark.xfail(
raises=NmstateNotImplementedError,
reason='https://nmstate.atlassian.net/browse/NMSTATE-230',
reason="https://nmstate.atlassian.net/browse/NMSTATE-230",
strict=True,
)
def test_port_vlan_not_implemented(port0_up):

View File

@ -26,13 +26,13 @@ from libnmstate.schema import Interface
from .testlib import mainloop_run
BOND0 = 'bondtest0'
BOND0 = "bondtest0"
def test_create_and_remove_bond(eth1_up):
bond_options = {
schema.Bond.MODE: schema.BondMode.ROUND_ROBIN,
'miimon': '140',
"miimon": "140",
}
with _bond_interface(BOND0, bond_options):
@ -126,12 +126,12 @@ def _attach_slave_to_bond(bond, slave):
def _create_connection_setting(bond, port_con_profile):
con_setting = nm.connection.ConnectionSetting()
con_setting.import_by_profile(port_con_profile)
con_setting.set_master(bond, 'bond')
con_setting.set_master(bond, "bond")
return con_setting.setting
def _convert_slaves_devices_to_iface_names(info):
if info:
info['slaves'] = [slave.props.interface for slave in info['slaves']]
info["slaves"] = [slave.props.interface for slave in info["slaves"]]
return info

View File

@ -24,9 +24,9 @@ from ..testlib import iproutelib
from .testlib import mainloop
TEST_IFACE = 'eth1'
TEST_IFACE = "eth1"
IPV4_ADDRESS1 = '192.0.2.251'
IPV4_ADDRESS1 = "192.0.2.251"
@iproutelib.ip_monitor_assert_stable_link_up(TEST_IFACE)

View File

@ -29,7 +29,7 @@ from ..testlib import iproutelib
from .testlib import mainloop_run
BRIDGE0 = 'brtest0'
BRIDGE0 = "brtest0"
@pytest.fixture
@ -168,7 +168,7 @@ def _create_bridge(bridge_desired_state):
def _attach_port_to_bridge(port_state):
port_nmdev = nm.device.get_device_by_name(port_state['name'])
port_nmdev = nm.device.get_device_by_name(port_state["name"])
curr_port_con_profile = nm.connection.ConnectionProfile()
curr_port_con_profile.import_by_device(port_nmdev)
iface_port_settings = _get_iface_port_settings(
@ -192,7 +192,7 @@ def _create_bridge_iface(iface_bridge_settings):
def _get_iface_port_settings(port_state, port_con_profile):
con_setting = nm.connection.ConnectionSetting()
con_setting.import_by_profile(port_con_profile)
con_setting.set_master(BRIDGE0, 'bridge')
con_setting.set_master(BRIDGE0, "bridge")
bridge_port_setting = nm.bridge.create_port_setting(
port_state, port_con_profile.profile

View File

@ -28,8 +28,8 @@ from .testlib import mainloop
from .testlib import MainloopTestError
BRIDGE0 = 'brtest0'
ETH1 = 'eth1'
BRIDGE0 = "brtest0"
ETH1 = "eth1"
@pytest.fixture
@ -42,7 +42,7 @@ def bridge_default_config():
return {
OB.CONFIG_SUBTREE: {
OB.OPTIONS_SUBTREE: {
OB.Options.FAIL_MODE: '',
OB.Options.FAIL_MODE: "",
OB.Options.MCAST_SNOOPING_ENABLED: False,
OB.Options.RSTP: False,
OB.Options.STP: False,
@ -54,7 +54,7 @@ def bridge_default_config():
@pytest.mark.xfail(
raises=(MainloopTestError, AssertionError),
reason='https://bugzilla.redhat.com/1724901',
reason="https://bugzilla.redhat.com/1724901",
)
def test_create_and_remove_minimum_config_bridge(
bridge_minimum_config, bridge_default_config
@ -71,13 +71,13 @@ def test_create_and_remove_minimum_config_bridge(
@pytest.mark.xfail(
raises=(MainloopTestError, AssertionError),
reason='https://bugzilla.redhat.com/1724901',
reason="https://bugzilla.redhat.com/1724901",
)
def test_bridge_with_system_port(eth1_up, bridge_default_config):
bridge_desired_state = bridge_default_config
eth1_port = {
OB.Port.NAME: 'eth1',
OB.Port.NAME: "eth1",
# OVS vlan/s are not yet supported.
# OB.VLAN.MODE: None,
# OB.VLAN.TAG: 0,
@ -94,12 +94,12 @@ def test_bridge_with_system_port(eth1_up, bridge_default_config):
@pytest.mark.xfail(
raises=(MainloopTestError, AssertionError),
reason='https://bugzilla.redhat.com/1724901',
reason="https://bugzilla.redhat.com/1724901",
)
def test_bridge_with_internal_interface(bridge_default_config):
bridge_desired_state = bridge_default_config
ovs_port = {OB.Port.NAME: 'ovs0'}
ovs_port = {OB.Port.NAME: "ovs0"}
bridge_desired_state[OB.CONFIG_SUBTREE][OB.PORT_SUBTREE].append(ovs_port)

View File

@ -32,13 +32,13 @@ from libnmstate.schema import InterfaceIPv6
from .testlib import mainloop_run
from ..testlib import iprule
ETH1 = 'eth1'
ETH1 = "eth1"
IPV4_ADDRESS1 = '192.0.2.251'
IPV6_ADDRESS1 = '2001:db8:1::1'
IPV4_ADDRESS1 = "192.0.2.251"
IPV6_ADDRESS1 = "2001:db8:1::1"
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def eth1_up_with_static(eth1_up):
state = eth1_up
iface_state = state[Interface.KEY][0]
@ -72,13 +72,13 @@ def eth1_up_with_static(eth1_up):
def test_create_rule_add_full(eth1_up_with_static):
rule_v4_0 = _create_route_rule('198.51.100.0/24', '192.0.2.1/32', 50, 103)
rule_v4_1 = _create_route_rule('198.51.100.0/24', '192.0.2.2/32', 51, 104)
rule_v4_0 = _create_route_rule("198.51.100.0/24", "192.0.2.1/32", 50, 103)
rule_v4_1 = _create_route_rule("198.51.100.0/24", "192.0.2.2/32", 51, 104)
rule_v6_0 = _create_route_rule(
'2001:db8:a::/64', '2001:db8:1::a/128', 50, 103
"2001:db8:a::/64", "2001:db8:1::a/128", 50, 103
)
rule_v6_1 = _create_route_rule(
'2001:db8:b::/64', '2001:db8:1::a/128', 51, 104
"2001:db8:b::/64", "2001:db8:1::a/128", 51, 104
)
ipv4_state = eth1_up_with_static[Interface.KEY][0][Interface.IPV4]
@ -94,7 +94,7 @@ def test_create_rule_add_full(eth1_up_with_static):
def test_route_rule_without_prioriry(eth1_up_with_static):
rule = _create_route_rule('198.51.100.0/24', '192.0.2.1/32', 50, 103)
rule = _create_route_rule("198.51.100.0/24", "192.0.2.1/32", 50, 103)
del rule[RouteRule.PRIORITY]
ipv4_state = eth1_up_with_static[Interface.KEY][0][Interface.IPV4]
ipv4_state.update({nm.route.ROUTE_RULES_METADATA: [rule]})
@ -107,7 +107,7 @@ def test_route_rule_without_prioriry(eth1_up_with_static):
def test_route_rule_without_table(eth1_up_with_static):
rule = _create_route_rule('198.51.100.0/24', '192.0.2.1/32', 50, 103)
rule = _create_route_rule("198.51.100.0/24", "192.0.2.1/32", 50, 103)
del rule[RouteRule.ROUTE_TABLE]
ipv4_state = eth1_up_with_static[Interface.KEY][0][Interface.IPV4]
ipv4_state.update({nm.route.ROUTE_RULES_METADATA: [rule]})
@ -120,7 +120,7 @@ def test_route_rule_without_table(eth1_up_with_static):
def test_route_rule_without_from(eth1_up_with_static):
rule = _create_route_rule('198.51.100.0/24', '192.0.2.1/32', 50, 103)
rule = _create_route_rule("198.51.100.0/24", "192.0.2.1/32", 50, 103)
del rule[RouteRule.IP_FROM]
ipv4_state = eth1_up_with_static[Interface.KEY][0][Interface.IPV4]
ipv4_state.update({nm.route.ROUTE_RULES_METADATA: [rule]})
@ -132,7 +132,7 @@ def test_route_rule_without_from(eth1_up_with_static):
def test_route_rule_without_to(eth1_up_with_static):
rule = _create_route_rule('198.51.100.0/24', '192.0.2.1/32', 50, 103)
rule = _create_route_rule("198.51.100.0/24", "192.0.2.1/32", 50, 103)
del rule[RouteRule.IP_TO]
ipv4_state = eth1_up_with_static[Interface.KEY][0][Interface.IPV4]
ipv4_state.update({nm.route.ROUTE_RULES_METADATA: [rule]})
@ -191,6 +191,6 @@ def _assert_route_rules(expected_rules):
cur_rules = (
nm.ipv4.get_routing_rule_config() + nm.ipv6.get_routing_rule_config()
)
logging.debug(f'Current route rules reported by NM {cur_rules}')
logging.debug(f"Current route rules reported by NM {cur_rules}")
for rule in expected_rules:
assert rule in expected_rules

View File

@ -25,7 +25,7 @@ from libnmstate.schema import VLAN
from .testlib import mainloop
ETH1 = 'eth1'
ETH1 = "eth1"
def test_create_and_remove_vlan(eth1_up):
@ -89,6 +89,6 @@ def _delete_vlan(devname):
def _get_vlan_ifname(state):
return (
state[VLAN.CONFIG_SUBTREE][VLAN.BASE_IFACE]
+ '.'
+ "."
+ str(state[VLAN.CONFIG_SUBTREE][VLAN.ID])
)

View File

@ -42,9 +42,9 @@ def test_create_and_remove_vxlan(eth1_up):
@pytest.mark.xfail(
condition=StrictVersion(nm.nmclient.nm_version())
< StrictVersion('1.20.6'),
< StrictVersion("1.20.6"),
strict=True,
reason='https://bugzilla.redhat.com/show_bug.cgi?id=1768388',
reason="https://bugzilla.redhat.com/show_bug.cgi?id=1768388",
)
def test_read_destination_port_from_libnm(eth1_up):
vxlan_desired_state = _create_vxlan_state(eth1_up)
@ -65,7 +65,7 @@ def _create_vxlan_state(eth1_up):
VXLAN.CONFIG_SUBTREE: {
VXLAN.ID: 201,
VXLAN.BASE_IFACE: ifname,
VXLAN.REMOTE: '192.168.1.18',
VXLAN.REMOTE: "192.168.1.18",
VXLAN.DESTINATION_PORT: 4789,
}
}
@ -123,6 +123,6 @@ def _get_vxlan_device(ifname):
def _vxlan_ifname(state):
return (
state[VXLAN.CONFIG_SUBTREE][VXLAN.BASE_IFACE]
+ '.'
+ "."
+ str(state[VXLAN.CONFIG_SUBTREE][VXLAN.ID])
)

View File

@ -28,15 +28,15 @@ from .testlib import mainloop
from .testlib import MainloopTestError
ETH1 = 'eth1'
ETH1 = "eth1"
MAC0 = '02:FF:FF:FF:FF:00'
MAC0 = "02:FF:FF:FF:FF:00"
MTU0 = 1200
@pytest.mark.xfail(
condition=StrictVersion(nm.nmclient.nm_version()) < StrictVersion('1.18'),
reason='https://bugzilla.redhat.com/1702657',
condition=StrictVersion(nm.nmclient.nm_version()) < StrictVersion("1.18"),
reason="https://bugzilla.redhat.com/1702657",
strict=True,
)
def test_interface_mtu_change_with_reapply(eth1_up):

View File

@ -28,11 +28,11 @@ RC_SUCCESS = 0
def test_edit_abort():
runenv = dict(os.environ)
env = {'EDITOR': 'false'}
env = {"EDITOR": "false"}
runenv.update(env)
cmds = ['nmstatectl', 'edit', 'lo']
cmds = ["nmstatectl", "edit", "lo"]
ret = libcmd.exec_cmd(cmds, env=runenv)
rc, out, err = ret
@ -41,11 +41,11 @@ def test_edit_abort():
def test_edit_no_change_eth1():
runenv = dict(os.environ)
env = {'EDITOR': 'touch'}
env = {"EDITOR": "touch"}
runenv.update(env)
cmds = ['nmstatectl', 'edit', 'eth1']
cmds = ["nmstatectl", "edit", "eth1"]
ret = libcmd.exec_cmd(cmds, env=runenv)
rc, out, err = ret
@ -53,4 +53,4 @@ def test_edit_no_change_eth1():
def assert_rc(actual, expected, return_tuple):
assert actual == expected, 'rc={}, out={}, err={}'.format(*return_tuple)
assert actual == expected, "rc={}, out={}, err={}".format(*return_tuple)

View File

@ -31,10 +31,10 @@ from .testlib.examplelib import find_examples_dir
from .testlib.examplelib import load_example
SET_CMD = ['nmstatectl', 'set']
SHOW_CMD = ['nmstatectl', 'show']
CONFIRM_CMD = ['nmstatectl', 'commit']
ROLLBACK_CMD = ['nmstatectl', 'rollback']
SET_CMD = ["nmstatectl", "set"]
SHOW_CMD = ["nmstatectl", "show"]
CONFIRM_CMD = ["nmstatectl", "commit"]
ROLLBACK_CMD = ["nmstatectl", "rollback"]
LOOPBACK_JSON_CONFIG = """ {
"name": "lo",
@ -73,25 +73,25 @@ ETH1_YAML_CONFIG = b"""interfaces:
"""
EXAMPLES = find_examples_dir()
CONFIRMATION_INTERFACE = 'eth1.101'
CONFIRMATION_CLEAN = 'vlan101_eth1_absent.yml'
CONFIRMATION_TEST = 'vlan101_eth1_up.yml'
CONFIRMATION_INTERFACE = "eth1.101"
CONFIRMATION_CLEAN = "vlan101_eth1_absent.yml"
CONFIRMATION_TEST = "vlan101_eth1_up.yml"
CONFIRMATION_TEST_STATE = load_example(CONFIRMATION_TEST)
CONFIRMATION_SET = SET_CMD + [
'--no-commit',
"--no-commit",
os.path.join(EXAMPLES, CONFIRMATION_TEST),
]
CONFIRMATION_TIMEOUT = 5
CONFIRMATION_TIMOUT_COMMAND = SET_CMD + [
'--no-commit',
'--timeout',
"--no-commit",
"--timeout",
str(CONFIRMATION_TIMEOUT),
os.path.join(EXAMPLES, CONFIRMATION_TEST),
]
def test_missing_operation():
cmds = ['nmstatectl', 'no-such-oper']
cmds = ["nmstatectl", "no-such-oper"]
ret = libcmd.exec_cmd(cmds)
rc, out, err = ret
@ -100,7 +100,7 @@ def test_missing_operation():
def test_show_command_with_json():
ret = libcmd.exec_cmd(SHOW_CMD + ['--json'])
ret = libcmd.exec_cmd(SHOW_CMD + ["--json"])
rc, out, err = ret
assert rc == libcmd.RC_SUCCESS, libcmd.format_exec_cmd_result(ret)
@ -119,18 +119,18 @@ def test_show_command_with_yaml_format():
def test_show_command_json_only_lo():
ret = libcmd.exec_cmd(SHOW_CMD + ['--json', 'lo'])
ret = libcmd.exec_cmd(SHOW_CMD + ["--json", "lo"])
rc, out, err = ret
assert rc == libcmd.RC_SUCCESS, libcmd.format_exec_cmd_result(ret)
state = json.loads(out)
assert len(state[Constants.INTERFACES]) == 1
assert state[Constants.INTERFACES][0]['name'] == 'lo'
assert state[Constants.INTERFACES][0]["name"] == "lo"
def test_show_command_only_non_existing():
ret = libcmd.exec_cmd(SHOW_CMD + ['--json', 'non_existing_interface'])
ret = libcmd.exec_cmd(SHOW_CMD + ["--json", "non_existing_interface"])
rc, out, err = ret
assert rc == libcmd.RC_SUCCESS, libcmd.format_exec_cmd_result(ret)
@ -149,8 +149,8 @@ def test_set_command_with_yaml_format():
def test_set_command_with_two_states():
examples = find_examples_dir()
cmd = SET_CMD + [
os.path.join(examples, 'linuxbrige_eth1_up.yml'),
os.path.join(examples, 'linuxbrige_eth1_absent.yml'),
os.path.join(examples, "linuxbrige_eth1_up.yml"),
os.path.join(examples, "linuxbrige_eth1_absent.yml"),
]
ret = libcmd.exec_cmd(cmd)
rc = ret[0]

View File

@ -28,13 +28,13 @@ from .testlib import assertlib
from .testlib.ovslib import Bridge
BRIDGE1 = 'br1'
PORT1 = 'ovs1'
BRIDGE1 = "br1"
PORT1 = "ovs1"
@pytest.mark.xfail(
raises=(NmstateLibnmError, AssertionError),
reason='https://bugzilla.redhat.com/1724901',
reason="https://bugzilla.redhat.com/1724901",
)
def test_create_and_remove_ovs_bridge_with_min_desired_state():
with Bridge(BRIDGE1).create() as state:
@ -45,13 +45,13 @@ def test_create_and_remove_ovs_bridge_with_min_desired_state():
@pytest.mark.xfail(
raises=(NmstateLibnmError, AssertionError),
reason='https://bugzilla.redhat.com/1724901',
reason="https://bugzilla.redhat.com/1724901",
)
def test_create_and_remove_ovs_bridge_options_specified():
bridge = Bridge(BRIDGE1)
bridge.set_options(
{
OVSBridge.Options.FAIL_MODE: '',
OVSBridge.Options.FAIL_MODE: "",
OVSBridge.Options.MCAST_SNOOPING_ENABLED: False,
OVSBridge.Options.RSTP: False,
OVSBridge.Options.STP: True,
@ -66,7 +66,7 @@ def test_create_and_remove_ovs_bridge_options_specified():
@pytest.mark.xfail(
raises=(NmstateLibnmError, AssertionError),
reason='https://bugzilla.redhat.com/1724901',
reason="https://bugzilla.redhat.com/1724901",
)
def test_create_and_remove_ovs_bridge_with_a_system_port(port0_up):
bridge = Bridge(BRIDGE1)
@ -81,7 +81,7 @@ def test_create_and_remove_ovs_bridge_with_a_system_port(port0_up):
@pytest.mark.xfail(
raises=(NmstateLibnmError, AssertionError),
reason='https://bugzilla.redhat.com/1724901',
reason="https://bugzilla.redhat.com/1724901",
)
def test_create_and_remove_ovs_bridge_with_internal_port_and_static_ip():
bridge = Bridge(BRIDGE1)
@ -91,7 +91,7 @@ def test_create_and_remove_ovs_bridge_with_internal_port_and_static_ip():
InterfaceIPv4.ENABLED: True,
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '192.0.2.1',
InterfaceIPv4.ADDRESS_IP: "192.0.2.1",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
}
],

View File

@ -30,13 +30,13 @@ from libnmstate.schema import InterfaceState
from .testlib import statelib
from .testlib import cmd as libcmd
_IPV4_EXTRA_CONFIG = 'ipv4.dad-timeout'
_IPV4_EXTRA_VALUE = '0'
_IPV6_EXTRA_CONFIG = 'ipv6.dhcp-hostname'
_IPV6_EXTRA_VALUE = 'libnmstate.example.com'
_IPV4_EXTRA_CONFIG = "ipv4.dad-timeout"
_IPV4_EXTRA_VALUE = "0"
_IPV6_EXTRA_CONFIG = "ipv6.dhcp-hostname"
_IPV6_EXTRA_VALUE = "libnmstate.example.com"
IPV4_ADDRESS1 = '192.0.2.251'
IPV6_ADDRESS1 = '2001:db8:1::1'
IPV4_ADDRESS1 = "192.0.2.251"
IPV6_ADDRESS1 = "2001:db8:1::1"
def test_reapply_preserve_ip_config(eth1_up):
@ -44,7 +44,7 @@ def test_reapply_preserve_ip_config(eth1_up):
{
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
@ -70,7 +70,7 @@ def test_reapply_preserve_ip_config(eth1_up):
]
}
)
cur_state = statelib.show_only(('eth1',))
cur_state = statelib.show_only(("eth1",))
iface_name = cur_state[Interface.KEY][0][Interface.NAME]
uuid = _get_nm_profile_uuid(iface_name)
@ -98,10 +98,10 @@ def _get_nm_profile_uuid(iface_name):
def _get_cur_extra_ip_config(uuid, key):
rc, output, _ = libcmd.exec_cmd(
['nmcli', '--get-values', key, 'connection', 'show', uuid]
["nmcli", "--get-values", key, "connection", "show", uuid]
)
assert rc == 0
return output.split('\n')[0]
return output.split("\n")[0]
@contextmanager
@ -116,7 +116,7 @@ def _extra_ip_config(uuid, key, value):
def _apply_extra_ip_config(uuid, key, value):
assert (
libcmd.exec_cmd(['nmcli', 'connection', 'modify', uuid, key, value])[0]
libcmd.exec_cmd(["nmcli", "connection", "modify", uuid, key, value])[0]
== 0
)

View File

@ -31,45 +31,45 @@ from libnmstate.schema import InterfaceState
from .testlib import cmd as libcmd
DUMMY0_IFNAME = 'dummy0'
DUMMY0_IFNAME = "dummy0"
NMCLI_CON_ADD_DUMMY_CMD = [
'nmcli',
'con',
'add',
'type',
'dummy',
'con-name',
'testProfile',
'connection.autoconnect',
'no',
'ifname',
"nmcli",
"con",
"add",
"type",
"dummy",
"con-name",
"testProfile",
"connection.autoconnect",
"no",
"ifname",
DUMMY0_IFNAME,
]
NMCLI_CON_ADD_ETH_CMD = [
'nmcli',
'con',
'add',
'type',
'ethernet',
'con-name',
'testProfile',
'connection.autoconnect',
'no',
'ifname',
'eth1',
"nmcli",
"con",
"add",
"type",
"ethernet",
"con-name",
"testProfile",
"connection.autoconnect",
"no",
"ifname",
"eth1",
]
DUMMY_PROFILE_DIRECTORY = '/etc/NetworkManager/system-connections/'
DUMMY_PROFILE_DIRECTORY = "/etc/NetworkManager/system-connections/"
ETH_PROFILE_DIRECTORY = '/etc/sysconfig/network-scripts/'
ETH_PROFILE_DIRECTORY = "/etc/sysconfig/network-scripts/"
def test_delete_new_interface_inactive_profiles(dummy_inactive_profile):
with dummy_interface(dummy_inactive_profile):
profile_exists = _profile_exists(
DUMMY_PROFILE_DIRECTORY + 'testProfile.nmconnection'
DUMMY_PROFILE_DIRECTORY + "testProfile.nmconnection"
)
assert not profile_exists
@ -79,7 +79,7 @@ def test_delete_existing_interface_inactive_profiles(eth1_up):
eth1_up[Interface.KEY][0][Interface.MTU] = 2000
libnmstate.apply(eth1_up)
profile_exists = _profile_exists(
ETH_PROFILE_DIRECTORY + 'ifcfg-testProfile'
ETH_PROFILE_DIRECTORY + "ifcfg-testProfile"
)
assert not profile_exists
@ -108,13 +108,13 @@ def dummy_interface(ifname):
def dummy_inactive_profile():
libcmd.exec_cmd(NMCLI_CON_ADD_DUMMY_CMD)
profile_exists = _profile_exists(
DUMMY_PROFILE_DIRECTORY + 'testProfile.nmconnection'
DUMMY_PROFILE_DIRECTORY + "testProfile.nmconnection"
)
assert profile_exists
try:
yield DUMMY0_IFNAME
finally:
libcmd.exec_cmd(_nmcli_delete_connection('testProfile'))
libcmd.exec_cmd(_nmcli_delete_connection("testProfile"))
@contextmanager
@ -122,21 +122,21 @@ def create_inactive_profile(con_name):
libcmd.exec_cmd(_nmcli_deactivate_connection(con_name))
libcmd.exec_cmd(NMCLI_CON_ADD_ETH_CMD)
profile_exists = _profile_exists(
ETH_PROFILE_DIRECTORY + 'ifcfg-testProfile'
ETH_PROFILE_DIRECTORY + "ifcfg-testProfile"
)
assert profile_exists
try:
yield
finally:
libcmd.exec_cmd(_nmcli_delete_connection('testProfile'))
libcmd.exec_cmd(_nmcli_delete_connection("testProfile"))
def _nmcli_deactivate_connection(con_name):
return ['nmcli', 'con', 'down', con_name]
return ["nmcli", "con", "down", con_name]
def _nmcli_delete_connection(con_name):
return ['nmcli', 'con', 'delete', con_name]
return ["nmcli", "con", "delete", con_name]
def _profile_exists(profile_name):

View File

@ -34,21 +34,21 @@ from libnmstate.schema import RouteRule
from .testlib import iprule
IPV4_ADDRESS1 = '192.0.2.251'
IPV4_ADDRESS1 = "192.0.2.251"
IPV4_ROUTE_TABLE_ID1 = 50
IPV4_ROUTE_TABLE_ID2 = 51
IPV6_ADDRESS1 = '2001:db8:1::1'
IPV6_ADDRESS1 = "2001:db8:1::1"
IPV6_ROUTE_TABLE_ID1 = 50
IPV6_ROUTE_TABLE_ID2 = 51
IPV4_DNS_NAMESERVER = '8.8.8.8'
IPV6_DNS_NAMESERVER = '2001:4860:4860::8888'
DNS_SEARCHES = ['example.org', 'example.com']
IPV4_DNS_NAMESERVER = "8.8.8.8"
IPV6_DNS_NAMESERVER = "2001:4860:4860::8888"
DNS_SEARCHES = ["example.org", "example.com"]
ETH1_INTERFACE_STATE = {
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.STATE: InterfaceState.UP,
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV4: {
@ -166,13 +166,13 @@ def test_change_gateway(eth1_up):
Route.CONFIG: [
{
Route.STATE: Route.STATE_ABSENT,
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.DESTINATION: '0.0.0.0/0',
Route.NEXT_HOP_INTERFACE: "eth1",
Route.DESTINATION: "0.0.0.0/0",
},
{
Route.STATE: Route.STATE_ABSENT,
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.DESTINATION: '::/0',
Route.NEXT_HOP_INTERFACE: "eth1",
Route.DESTINATION: "::/0",
},
]
+ routes
@ -197,7 +197,7 @@ def _assert_routes(routes, state):
routes.sort(key=_route_sort_key)
config_routes = []
for config_route in state[Route.KEY][Route.CONFIG]:
if config_route[Route.NEXT_HOP_INTERFACE] == 'eth1':
if config_route[Route.NEXT_HOP_INTERFACE] == "eth1":
config_routes.append(config_route)
config_routes.sort(key=_route_sort_key)
@ -232,17 +232,17 @@ def _assert_in_running_route(route, running_routes):
def _get_ipv4_test_routes():
return [
{
Route.DESTINATION: '198.51.100.0/24',
Route.DESTINATION: "198.51.100.0/24",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: IPV4_ROUTE_TABLE_ID1,
},
{
Route.DESTINATION: '203.0.113.0/24',
Route.DESTINATION: "203.0.113.0/24",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: IPV4_ROUTE_TABLE_ID2,
},
]
@ -251,17 +251,17 @@ def _get_ipv4_test_routes():
def _get_ipv4_gateways():
return [
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: 254,
},
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.METRIC: 101,
Route.NEXT_HOP_ADDRESS: '192.0.2.2',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "192.0.2.2",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: 254,
},
]
@ -270,17 +270,17 @@ def _get_ipv4_gateways():
def _get_ipv6_test_routes():
return [
{
Route.DESTINATION: '2001:db8:a::/64',
Route.DESTINATION: "2001:db8:a::/64",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::a',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::a",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: IPV6_ROUTE_TABLE_ID1,
},
{
Route.DESTINATION: '2001:db8:b::/64',
Route.DESTINATION: "2001:db8:b::/64",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::b',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::b",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: IPV6_ROUTE_TABLE_ID2,
},
]
@ -289,17 +289,17 @@ def _get_ipv6_test_routes():
def _get_ipv6_gateways():
return [
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::f',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::f",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: 254,
},
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.METRIC: 101,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::e',
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::e",
Route.NEXT_HOP_INTERFACE: "eth1",
Route.TABLE_ID: 254,
},
]
@ -308,15 +308,15 @@ def _get_ipv6_gateways():
def _route_sort_key(route):
return (
route.get(Route.TABLE_ID, Route.USE_DEFAULT_ROUTE_TABLE),
route.get(Route.NEXT_HOP_INTERFACE, ''),
route.get(Route.DESTINATION, ''),
route.get(Route.NEXT_HOP_INTERFACE, ""),
route.get(Route.DESTINATION, ""),
)
parametrize_ip_ver_routes = pytest.mark.parametrize(
'get_routes_func',
"get_routes_func",
[(_get_ipv4_test_routes), (_get_ipv6_test_routes)],
ids=['ipv4', 'ipv6'],
ids=["ipv4", "ipv6"],
)
@ -361,7 +361,7 @@ def test_remove_wildcast_route_with_iface(eth1_up, get_routes_func):
absent_route = {
Route.STATE: Route.STATE_ABSENT,
Route.NEXT_HOP_INTERFACE: 'eth1',
Route.NEXT_HOP_INTERFACE: "eth1",
}
libnmstate.apply(
{
@ -440,7 +440,7 @@ def test_iface_down_with_routes_in_current(eth1_up, get_routes_func):
{
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.DOWN,
}
@ -452,7 +452,7 @@ def test_iface_down_with_routes_in_current(eth1_up, get_routes_func):
_assert_routes([], cur_state)
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def eth1_static_gateway_dns(eth1_up):
routes = (
[_get_ipv4_gateways()[0], _get_ipv6_gateways()[0]]
@ -481,7 +481,7 @@ def eth1_static_gateway_dns(eth1_up):
@pytest.mark.xfail(
raises=AssertionError,
reason='https://bugzilla.redhat.com/1748389',
reason="https://bugzilla.redhat.com/1748389",
strict=True,
)
def test_apply_empty_state_preserve_routes(eth1_static_gateway_dns):
@ -498,7 +498,7 @@ def test_apply_empty_state_preserve_routes(eth1_static_gateway_dns):
assert current_state[DNS.KEY][DNS.CONFIG] == state[DNS.KEY][DNS.CONFIG]
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def route_rule_test_env(eth1_static_gateway_dns):
yield eth1_static_gateway_dns
libnmstate.apply(
@ -529,11 +529,11 @@ def test_route_rule_add_from_only(route_rule_test_env):
state = route_rule_test_env
rules = [
{
RouteRule.IP_FROM: '2001:db8:f::/64',
RouteRule.IP_FROM: "2001:db8:f::/64",
RouteRule.ROUTE_TABLE: IPV6_ROUTE_TABLE_ID1,
},
{
RouteRule.IP_FROM: '192.0.2.0/24',
RouteRule.IP_FROM: "192.0.2.0/24",
RouteRule.ROUTE_TABLE: IPV4_ROUTE_TABLE_ID1,
},
]
@ -547,11 +547,11 @@ def test_route_rule_add_to_only(route_rule_test_env):
state = route_rule_test_env
rules = [
{
RouteRule.IP_TO: '2001:db8:f::/64',
RouteRule.IP_TO: "2001:db8:f::/64",
RouteRule.ROUTE_TABLE: IPV6_ROUTE_TABLE_ID1,
},
{
RouteRule.IP_TO: '192.0.2.0/24',
RouteRule.IP_TO: "192.0.2.0/24",
RouteRule.ROUTE_TABLE: IPV4_ROUTE_TABLE_ID1,
},
]
@ -565,14 +565,14 @@ def test_route_rule_add(route_rule_test_env):
state = route_rule_test_env
rules = [
{
RouteRule.IP_FROM: '2001:db8:a::/64',
RouteRule.IP_TO: '2001:db8:f::/64',
RouteRule.IP_FROM: "2001:db8:a::/64",
RouteRule.IP_TO: "2001:db8:f::/64",
RouteRule.PRIORITY: 1000,
RouteRule.ROUTE_TABLE: IPV6_ROUTE_TABLE_ID1,
},
{
RouteRule.IP_FROM: '203.0.113.0/24',
RouteRule.IP_TO: '192.0.2.0/24',
RouteRule.IP_FROM: "203.0.113.0/24",
RouteRule.IP_TO: "192.0.2.0/24",
RouteRule.PRIORITY: 1000,
RouteRule.ROUTE_TABLE: IPV4_ROUTE_TABLE_ID1,
},
@ -587,13 +587,13 @@ def test_route_rule_add_without_priority(route_rule_test_env):
state = route_rule_test_env
rules = [
{
RouteRule.IP_FROM: '2001:db8:a::/64',
RouteRule.IP_TO: '2001:db8:f::/64',
RouteRule.IP_FROM: "2001:db8:a::/64",
RouteRule.IP_TO: "2001:db8:f::/64",
RouteRule.ROUTE_TABLE: IPV6_ROUTE_TABLE_ID1,
},
{
RouteRule.IP_FROM: '203.0.113.0/24',
RouteRule.IP_TO: '192.0.2.0/24',
RouteRule.IP_FROM: "203.0.113.0/24",
RouteRule.IP_TO: "192.0.2.0/24",
RouteRule.ROUTE_TABLE: IPV4_ROUTE_TABLE_ID1,
},
]
@ -611,13 +611,13 @@ def test_route_rule_add_without_route_table(route_rule_test_env):
state = route_rule_test_env
rules = [
{
RouteRule.IP_FROM: '2001:db8:a::/64',
RouteRule.IP_TO: '2001:db8:f::/64',
RouteRule.IP_FROM: "2001:db8:a::/64",
RouteRule.IP_TO: "2001:db8:f::/64",
RouteRule.PRIORITY: 1000,
},
{
RouteRule.IP_FROM: '203.0.113.0/24',
RouteRule.IP_TO: '192.0.2.0/24',
RouteRule.IP_FROM: "203.0.113.0/24",
RouteRule.IP_TO: "192.0.2.0/24",
RouteRule.PRIORITY: 1000,
},
]

View File

@ -32,7 +32,7 @@ SRIOV_CONFIG = {Ethernet.SRIOV_SUBTREE: {Ethernet.SRIOV.TOTAL_VFS: 0}}
@pytest.mark.xfail(
raises=NmstateNotSupportedError,
reason='The device does not support SR-IOV.',
reason="The device does not support SR-IOV.",
)
def test_sriov_zero_vfs(sriov_interface):
assertlib.assert_state(sriov_interface)
@ -40,7 +40,7 @@ def test_sriov_zero_vfs(sriov_interface):
@pytest.mark.xfail(
raises=NmstateNotSupportedError,
reason='The device does not support SR-IOV.',
reason="The device does not support SR-IOV.",
)
def test_sriov_increase_vfs(sriov_interface):
eth_config = sriov_interface[Interface.KEY][0][Ethernet.CONFIG_SUBTREE]
@ -51,7 +51,7 @@ def test_sriov_increase_vfs(sriov_interface):
@pytest.mark.xfail(
raises=NmstateNotSupportedError,
reason='The device does not support SR-IOV.',
reason="The device does not support SR-IOV.",
)
def test_sriov_decrease_vfs(sriov_interface):
eth_config = sriov_interface[Interface.KEY][0][Ethernet.CONFIG_SUBTREE]

View File

@ -31,16 +31,16 @@ from .testlib import statelib
from .testlib.iproutelib import ip_monitor_assert_stable_link_up
# TEST-NET addresses: https://tools.ietf.org/html/rfc5737#section-3
IPV4_ADDRESS1 = '192.0.2.251'
IPV4_ADDRESS2 = '192.0.2.252'
IPV4_ADDRESS3 = '198.51.100.249'
IPV4_ADDRESS4 = '198.51.100.250'
IPV4_ADDRESS1 = "192.0.2.251"
IPV4_ADDRESS2 = "192.0.2.252"
IPV4_ADDRESS3 = "198.51.100.249"
IPV4_ADDRESS4 = "198.51.100.250"
# IPv6 Address Prefix Reserved for Documentation:
# https://tools.ietf.org/html/rfc3849
IPV6_ADDRESS1 = '2001:db8:1::1'
IPV6_ADDRESS2 = '2001:db8:2::1'
IPV6_LINK_LOCAL_ADDRESS1 = 'fe80::1'
IPV6_LINK_LOCAL_ADDRESS2 = 'fe80::2'
IPV6_ADDRESS1 = "2001:db8:1::1"
IPV6_ADDRESS2 = "2001:db8:2::1"
IPV6_LINK_LOCAL_ADDRESS1 = "fe80::1"
IPV6_LINK_LOCAL_ADDRESS2 = "fe80::2"
@pytest.fixture
@ -48,7 +48,7 @@ def setup_eth1_ipv4(eth1_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
@ -71,7 +71,7 @@ def setup_eth1_ipv6(eth1_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV6: {
@ -96,7 +96,7 @@ def setup_eth1_ipv6_disable(eth1_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV6: {InterfaceIPv6.ENABLED: False},
@ -109,7 +109,7 @@ def setup_eth1_ipv6_disable(eth1_up):
def test_add_static_ipv4_with_full_state(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.STATE] = InterfaceState.UP
@ -129,7 +129,7 @@ def test_add_static_ipv4_with_min_state(eth2_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
@ -153,7 +153,7 @@ def test_remove_static_ipv4(setup_eth1_ipv4):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV4: {InterfaceIPv4.ENABLED: False},
}
@ -169,7 +169,7 @@ def test_edit_static_ipv4_address_and_prefix(setup_eth1_ipv4):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
@ -196,7 +196,7 @@ def test_add_ifaces_with_same_static_ipv4_address_in_one_transaction(
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
@ -210,7 +210,7 @@ def test_add_ifaces_with_same_static_ipv4_address_in_one_transaction(
},
},
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
@ -237,7 +237,7 @@ def test_add_iface_with_same_static_ipv4_address_to_existing(
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV4: {
@ -258,7 +258,7 @@ def test_add_iface_with_same_static_ipv4_address_to_existing(
def test_add_static_ipv6_with_full_state(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.STATE] = InterfaceState.UP
eth1_desired_state[Interface.IPV6][InterfaceIPv6.ENABLED] = True
@ -278,7 +278,7 @@ def test_add_static_ipv6_with_full_state(eth1_up):
def test_add_static_ipv6_with_link_local(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.STATE] = InterfaceState.UP
eth1_desired_state[Interface.IPV6][InterfaceIPv6.ENABLED] = True
@ -296,7 +296,7 @@ def test_add_static_ipv6_with_link_local(eth1_up):
libnmstate.apply(desired_state)
# Make sure only the link local address got ignored.
cur_state = statelib.show_only(('eth1',))
cur_state = statelib.show_only(("eth1",))
eth1_cur_state = cur_state[Interface.KEY][0]
assert (
eth1_desired_state[Interface.IPV6][InterfaceIPv6.ADDRESS][0]
@ -309,7 +309,7 @@ def test_add_static_ipv6_with_link_local(eth1_up):
def test_add_static_ipv6_with_link_local_only(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.STATE] = InterfaceState.UP
eth1_desired_state[Interface.IPV6][InterfaceIPv6.ENABLED] = True
@ -327,7 +327,7 @@ def test_add_static_ipv6_with_link_local_only(eth1_up):
libnmstate.apply(desired_state)
# Make sure the link local address got ignored.
cur_state = statelib.show_only(('eth1',))
cur_state = statelib.show_only(("eth1",))
eth1_cur_state = cur_state[Interface.KEY][0]
assert (
eth1_desired_state[Interface.IPV6][InterfaceIPv6.ADDRESS][0]
@ -340,14 +340,14 @@ def test_add_static_ipv6_with_link_local_only(eth1_up):
def test_add_static_ipv6_with_no_address(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_desired_state = desired_state[Interface.KEY][0]
eth1_desired_state[Interface.STATE] = InterfaceState.UP
eth1_desired_state[Interface.IPV6][InterfaceIPv6.ENABLED] = True
libnmstate.apply(desired_state)
cur_state = statelib.show_only(('eth1',))
cur_state = statelib.show_only(("eth1",))
eth1_cur_state = cur_state[Interface.KEY][0]
# Should have at least 1 link-local address.
assert len(eth1_cur_state[Interface.IPV6][InterfaceIPv6.ADDRESS]) >= 1
@ -357,7 +357,7 @@ def test_add_static_ipv6_with_min_state(eth2_up):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV6: {
@ -381,7 +381,7 @@ def test_disable_static_ipv6(setup_eth1_ipv6):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV6: {InterfaceIPv6.ENABLED: False},
}
@ -397,10 +397,10 @@ def test_disable_static_ipv6_and_rollback(setup_eth1_ipv6):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV6: {InterfaceIPv6.ENABLED: False},
'foo': 'bad_value',
"foo": "bad_value",
}
]
}
@ -415,7 +415,7 @@ def test_enable_ipv6_and_rollback_to_disable_ipv6(setup_eth1_ipv6_disable):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV6: {
InterfaceIPv6.ENABLED: True,
@ -426,7 +426,7 @@ def test_enable_ipv6_and_rollback_to_disable_ipv6(setup_eth1_ipv6_disable):
}
],
},
'foo': 'bad_value',
"foo": "bad_value",
}
]
}
@ -442,7 +442,7 @@ def test_edit_static_ipv6_address_and_prefix(setup_eth1_ipv6):
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV6: {
@ -460,7 +460,7 @@ def test_edit_static_ipv6_address_and_prefix(setup_eth1_ipv6):
libnmstate.apply(desired_state)
eth1_desired_state = desired_state[Interface.KEY][0]
current_state = statelib.show_only(('eth1',))
current_state = statelib.show_only(("eth1",))
eth1_current_state = current_state[Interface.KEY][0]
@ -481,7 +481,7 @@ def test_add_ifaces_with_same_static_ipv6_address_in_one_transaction(
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth1',
Interface.NAME: "eth1",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV6: {
@ -495,7 +495,7 @@ def test_add_ifaces_with_same_static_ipv6_address_in_one_transaction(
},
},
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV6: {
@ -522,7 +522,7 @@ def test_add_iface_with_same_static_ipv6_address_to_existing(
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.TYPE: InterfaceType.ETHERNET,
Interface.STATE: InterfaceState.UP,
Interface.IPV6: {
@ -543,7 +543,7 @@ def test_add_iface_with_same_static_ipv6_address_to_existing(
def test_add_iface_with_static_ipv6_expanded_format(eth1_up):
ipv6_addr_lead_zeroes = '2001:0db8:85a3:0000:0000:8a2e:0370:7331'
ipv6_addr_lead_zeroes = "2001:0db8:85a3:0000:0000:8a2e:0370:7331"
desired_state = {
Interface.KEY: [
{
@ -566,7 +566,7 @@ def test_add_iface_with_static_ipv6_expanded_format(eth1_up):
assertlib.assert_state(desired_state)
@ip_monitor_assert_stable_link_up('eth1')
@ip_monitor_assert_stable_link_up("eth1")
def test_modify_ipv6_with_reapply(setup_eth1_ipv6):
ipv6_addr = IPV6_ADDRESS2
ipv6_state = setup_eth1_ipv6[Interface.KEY][0][Interface.IPV6]

View File

@ -26,7 +26,7 @@ from libnmstate.schema import InterfaceType
from libnmstate.schema import Team
TEAM0 = 'team0'
TEAM0 = "team0"
TEAM0_STATE = {
Interface.KEY: [
@ -34,7 +34,7 @@ TEAM0_STATE = {
Interface.NAME: TEAM0,
Interface.TYPE: InterfaceType.TEAM,
Team.CONFIG_SUBTREE: {
Team.PORT_SUBTREE: [{Team.Port.NAME: 'eth1'}]
Team.PORT_SUBTREE: [{Team.Port.NAME: "eth1"}]
},
}
]
@ -43,7 +43,7 @@ TEAM0_STATE = {
@pytest.mark.xfail(
raises=NmstateNotImplementedError,
reason='Team interface is not supported yet',
reason="Team interface is not supported yet",
strict=True,
)
def test_sriov_not_implemented():

View File

@ -19,4 +19,4 @@
import pytest
pytest.register_assert_rewrite(__name__ + '.assertlib')
pytest.register_assert_rewrite(__name__ + ".assertlib")

View File

@ -52,7 +52,7 @@ def exec_cmd(cmd, env=None, stdin=None):
logging.debug(_retcode_log_line(p.returncode, err=err))
return (p.returncode, out.decode('utf-8'), err.decode('utf-8'))
return (p.returncode, out.decode("utf-8"), err.decode("utf-8"))
def command_log_line(args, cwd=None):
@ -60,7 +60,7 @@ def command_log_line(args, cwd=None):
def format_exec_cmd_result(result):
return 'rc={}, out={}, err={}'.format(*result)
return "rc={}, out={}, err={}".format(*result)
def _retcode_log_line(code, err=None):
@ -76,13 +76,13 @@ def _list2cmdline(args):
"""
parts = []
for arg in args:
if _needs_quoting(arg) or arg == '':
if _needs_quoting(arg) or arg == "":
arg = "'" + arg.replace("'", r"'\''") + "'"
parts.append(arg)
return ' '.join(parts)
return " ".join(parts)
# This function returns truthy value if its argument contains unsafe characters
# for including in a command passed to the shell. The safe characters were
# stolen from pipes._safechars.
_needs_quoting = re.compile(r'[^A-Za-z0-9_%+,\-./:=@]').search
_needs_quoting = re.compile(r"[^A-Za-z0-9_%+,\-./:=@]").search

View File

@ -21,4 +21,4 @@ import os
def is_fedora():
return os.path.exists('/etc/fedora-release')
return os.path.exists("/etc/fedora-release")

View File

@ -62,12 +62,12 @@ def find_examples_dir():
Look recursively for the directory containing the examples
"""
path = ''
parent = '../'
rootdir = '/'
path = ""
parent = "../"
rootdir = "/"
examples = None
for _ in range(PATH_MAX // len('x/')):
maybe_examples = os.path.abspath(os.path.join(path, 'examples'))
for _ in range(PATH_MAX // len("x/")):
maybe_examples = os.path.abspath(os.path.join(path, "examples"))
if os.path.isdir(maybe_examples):
examples = maybe_examples
break
@ -80,4 +80,4 @@ def find_examples_dir():
if examples:
return examples
else:
raise RuntimeError('Cannot find examples directory')
raise RuntimeError("Cannot find examples directory")

View File

@ -38,10 +38,10 @@ def ip_monitor_assert_stable_link_up(dev, timeout=10):
def decorator(func):
@wraps(func)
def wrapper_ip_monitor(*args, **kwargs):
with ip_monitor('link', dev, timeout) as result:
with ip_monitor("link", dev, timeout) as result:
func(*args, **kwargs)
assert len(get_non_up_events(result, dev)) == 0, (
'result: ' + result.out
"result: " + result.out
)
return wrapper_ip_monitor
@ -53,7 +53,7 @@ def ip_monitor_assert_stable_link_up(dev, timeout=10):
def ip_monitor(object_type, dev, timeout=10):
result = IpMonitorResult()
cmds = 'timeout {} ip monitor {} dev {}'.format(timeout, object_type, dev)
cmds = "timeout {} ip monitor {} dev {}".format(timeout, object_type, dev)
def run():
result.popen = subprocess.Popen(
@ -65,14 +65,14 @@ def ip_monitor(object_type, dev, timeout=10):
env=None,
)
result.out, result.err = result.popen.communicate(None)
result.out = result.out.decode('utf-8')
result.err = result.err.decode('utf-8')
result.out = result.out.decode("utf-8")
result.err = result.err.decode("utf-8")
def finalize():
if result.popen:
result.popen.terminate()
with _thread(run, 'ip-monitor', teardown_cb=finalize):
with _thread(run, "ip-monitor", teardown_cb=finalize):
# Let the ip monitor thread start before proceeding to the action.
time.sleep(1)
yield result
@ -86,7 +86,7 @@ def get_non_up_events(result, dev):
:return: List of non UP events
"""
return [
l for l in result.out.split('\n') if 'state UP' not in l and dev in l
l for l in result.out.split("\n") if "state UP" not in l and dev in l
]

View File

@ -26,44 +26,44 @@ from . import cmd as libcmd
def ip_rule_exist_in_os(ip_from, ip_to, priority, table):
expected_rule = locals()
logging.debug('Checking ip rule for {}'.format(expected_rule))
cmds = ['ip']
logging.debug("Checking ip rule for {}".format(expected_rule))
cmds = ["ip"]
if (ip_from and iplib.is_ipv6_address(ip_from)) or (
ip_to and iplib.is_ipv6_address(ip_to)
):
cmds.append('-6')
result = libcmd.exec_cmd(cmds + ['--json', 'rule'])
logging.debug(f'Current ip rules in OS: {result[1]}')
cmds.append("-6")
result = libcmd.exec_cmd(cmds + ["--json", "rule"])
logging.debug(f"Current ip rules in OS: {result[1]}")
assert result[0] == 0
current_rules = json.loads(result[1])
found = True
for rule in current_rules:
if rule.get('src') == 'all' or rule.get('dst') == 'all':
if rule.get("src") == "all" or rule.get("dst") == "all":
continue
if rule.get('table') == 'main':
rule['table'] = f'{iplib.KERNEL_MAIN_ROUTE_TABLE_ID}'
if rule.get("table") == "main":
rule["table"] = f"{iplib.KERNEL_MAIN_ROUTE_TABLE_ID}"
logging.debug(f'Checking ip rule is OS: {rule}')
logging.debug(f"Checking ip rule is OS: {rule}")
found = True
if ip_from and ip_from != iplib.to_ip_address_full(
rule['src'], rule.get('srclen')
rule["src"], rule.get("srclen")
):
found = False
continue
if ip_to and ip_to != iplib.to_ip_address_full(
rule['dst'], rule.get('dstlen')
rule["dst"], rule.get("dstlen")
):
found = False
continue
if priority is not None and rule['priority'] != priority:
if priority is not None and rule["priority"] != priority:
found = False
continue
if table is not None and rule['table'] != f'{table}':
if table is not None and rule["table"] != f"{table}":
found = False
continue
if found:
break
if not found:
logging.debug(f'Failed to find expected ip rule: {expected_rule}')
logging.debug(f"Failed to find expected ip rule: {expected_rule}")
assert found

View File

@ -271,7 +271,7 @@ def _is_ipv6_link_local(ip, prefix):
"""
The IPv6 link local address range is fe80::/10.
"""
return ip[:3] in ['fe8', 'fe9', 'fea', 'feb'] and prefix >= 10
return ip[:3] in ["fe8", "fe9", "fea", "feb"] and prefix >= 10
def _state_match(desire, current):

View File

@ -28,7 +28,7 @@ from libnmstate.schema import VXLAN
class VxlanState:
def __init__(self, id, base_if, remote, destination_port=4789):
self.name = f'{base_if}.{id}'
self.name = f"{base_if}.{id}"
self.id = id
self.base_if = base_if
self.remote = remote

View File

@ -34,8 +34,8 @@ from .testlib import statelib
from .testlib.assertlib import assert_mac_address
from .testlib.vlan import vlan_interface
VLAN_IFNAME = 'eth1.101'
VLAN2_IFNAME = 'eth1.102'
VLAN_IFNAME = "eth1.101"
VLAN2_IFNAME = "eth1.102"
def test_add_and_remove_vlan(eth1_up):
@ -74,7 +74,7 @@ def test_add_and_remove_two_vlans_on_same_iface(eth1_up):
def test_two_vlans_on_eth1_change_mtu(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_state = desired_state[Interface.KEY][0]
vlans_state = create_two_vlans_state()
desired_state[Interface.KEY].extend(vlans_state[Interface.KEY])
@ -96,7 +96,7 @@ def test_two_vlans_on_eth1_change_mtu(eth1_up):
def test_two_vlans_on_eth1_change_base_iface_mtu(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
eth1_state = desired_state[Interface.KEY][0]
vlans_state = create_two_vlans_state()
desired_state[Interface.KEY].extend(vlans_state[Interface.KEY])
@ -111,7 +111,7 @@ def test_two_vlans_on_eth1_change_base_iface_mtu(eth1_up):
def test_two_vlans_on_eth1_change_mtu_rollback(eth1_up):
desired_state = statelib.show_only(('eth1',))
desired_state = statelib.show_only(("eth1",))
vlans_state = create_two_vlans_state()
desired_state[Interface.KEY].extend(vlans_state[Interface.KEY])
for iface in desired_state[Interface.KEY]:
@ -131,7 +131,7 @@ def test_rollback_for_vlans(eth1_up):
current_state = libnmstate.show()
desired_state = create_two_vlans_state()
desired_state[Interface.KEY][1]['invalid_key'] = 'foo'
desired_state[Interface.KEY][1]["invalid_key"] = "foo"
with pytest.raises(NmstateVerificationError):
libnmstate.apply(desired_state)
@ -161,11 +161,11 @@ def test_set_vlan_iface_down(eth1_up):
def test_add_new_base_iface_with_vlan():
iface_base = 'dummy00'
iface_base = "dummy00"
desired_state = {
Interface.KEY: [
{
Interface.NAME: 'dummy00.101',
Interface.NAME: "dummy00.101",
Interface.TYPE: InterfaceType.VLAN,
Interface.STATE: InterfaceState.UP,
VLAN.CONFIG_SUBTREE: {
@ -220,13 +220,13 @@ def create_two_vlans_state():
Interface.NAME: VLAN_IFNAME,
Interface.TYPE: InterfaceType.VLAN,
Interface.STATE: InterfaceState.UP,
VLAN.CONFIG_SUBTREE: {VLAN.ID: 101, VLAN.BASE_IFACE: 'eth1'},
VLAN.CONFIG_SUBTREE: {VLAN.ID: 101, VLAN.BASE_IFACE: "eth1"},
},
{
Interface.NAME: VLAN2_IFNAME,
Interface.TYPE: InterfaceType.VLAN,
Interface.STATE: InterfaceState.UP,
VLAN.CONFIG_SUBTREE: {VLAN.ID: 102, VLAN.BASE_IFACE: 'eth1'},
VLAN.CONFIG_SUBTREE: {VLAN.ID: 102, VLAN.BASE_IFACE: "eth1"},
},
]
}

View File

@ -44,7 +44,7 @@ VXLAN2_ID = 202
def test_add_and_remove_vxlan(eth1_up):
ifname = eth1_up[Interface.KEY][0][Interface.NAME]
with vxlan_interfaces(
VxlanState(id=VXLAN1_ID, base_if=ifname, remote='192.168.100.1')
VxlanState(id=VXLAN1_ID, base_if=ifname, remote="192.168.100.1")
) as desired_state:
assertlib.assert_state(desired_state)
@ -55,8 +55,8 @@ def test_add_and_remove_vxlan(eth1_up):
def test_add_and_remove_two_vxlans_on_same_iface(eth1_up):
ifname = eth1_up[Interface.KEY][0][Interface.NAME]
with vxlan_interfaces(
VxlanState(id=VXLAN1_ID, base_if=ifname, remote='192.168.100.1'),
VxlanState(id=VXLAN2_ID, base_if=ifname, remote='192.168.100.2'),
VxlanState(id=VXLAN1_ID, base_if=ifname, remote="192.168.100.1"),
VxlanState(id=VXLAN2_ID, base_if=ifname, remote="192.168.100.2"),
) as desired_state:
assertlib.assert_state(desired_state)
@ -71,11 +71,11 @@ def test_rollback_for_vxlans(eth1_up):
current_state = libnmstate.show()
desired_state = vxlans_up(
[
VxlanState(id=VXLAN1_ID, base_if=ifname, remote='192.168.100.1'),
VxlanState(id=VXLAN2_ID, base_if=ifname, remote='192.168.100.2'),
VxlanState(id=VXLAN1_ID, base_if=ifname, remote="192.168.100.1"),
VxlanState(id=VXLAN2_ID, base_if=ifname, remote="192.168.100.2"),
]
)
desired_state[Interface.KEY][1]['invalid_key'] = 'foo'
desired_state[Interface.KEY][1]["invalid_key"] = "foo"
with pytest.raises(NmstateVerificationError):
libnmstate.apply(desired_state)
@ -86,7 +86,7 @@ def test_rollback_for_vxlans(eth1_up):
def test_set_vxlan_iface_down(eth1_up):
ifname = eth1_up[Interface.KEY][0][Interface.NAME]
vxlan = VxlanState(id=VXLAN1_ID, base_if=ifname, remote='192.168.100.1')
vxlan = VxlanState(id=VXLAN1_ID, base_if=ifname, remote="192.168.100.1")
with vxlan_interfaces(vxlan):
desired_state = vxlans_down([vxlan])
libnmstate.apply(desired_state)
@ -94,12 +94,12 @@ def test_set_vxlan_iface_down(eth1_up):
@pytest.mark.xfail(
reason='https://bugzilla.redhat.com/show_bug.cgi?id=1772382', strict=False
reason="https://bugzilla.redhat.com/show_bug.cgi?id=1772382", strict=False
)
def test_add_new_bond_iface_with_vxlan(eth1_up):
eth_name = eth1_up[Interface.KEY][0][Interface.NAME]
bond_name = 'bond1'
vxlan = VxlanState(id=VXLAN1_ID, base_if=bond_name, remote='192.168.100.2')
bond_name = "bond1"
vxlan = VxlanState(id=VXLAN1_ID, base_if=bond_name, remote="192.168.100.2")
with bond_interface(
name=bond_name, slaves=[eth_name], extra_iface_state=None, create=False
) as bond_desired_state:
@ -116,10 +116,10 @@ def test_add_new_bond_iface_with_vxlan(eth1_up):
def test_show_vxlan_with_no_remote(eth1_up):
eth_name = eth1_up[Interface.KEY][0][Interface.NAME]
vxlan = VxlanState(id=VXLAN1_ID, base_if=eth_name, remote='')
vxlan = VxlanState(id=VXLAN1_ID, base_if=eth_name, remote="")
add_vxlan_cmd = (
f'ip link add {vxlan.name} type vxlan id {vxlan.id}'
f' dstport {vxlan.destination_port} dev {eth_name}'.split()
f"ip link add {vxlan.name} type vxlan id {vxlan.id}"
f" dstport {vxlan.destination_port} dev {eth_name}".split()
)
try:
ret = exec_cmd(add_vxlan_cmd)

View File

@ -38,14 +38,14 @@ from libnmstate.schema import RouteRule
TYPE_BOND = InterfaceType.BOND
TYPE_OVS_BR = InterfaceType.OVS_BRIDGE
BOND_NAME = 'bond99'
OVS_NAME = 'ovs-br99'
TEST_IFACE1 = 'eth1'
BOND_NAME = "bond99"
OVS_NAME = "ovs-br99"
TEST_IFACE1 = "eth1"
@pytest.fixture(autouse=True)
def nm_mock():
with mock.patch.object(metadata, 'nm') as m:
with mock.patch.object(metadata, "nm") as m:
yield m
@ -76,19 +76,19 @@ class TestDesiredStateBondMetadata:
desired_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1']),
{'name': 'eth0', 'type': 'unknown'},
{'name': 'eth1', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"]),
{"name": "eth0", "type": "unknown"},
{"name": "eth1", "type": "unknown"},
]
}
)
current_state = state.State({})
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth1'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces['eth1'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth0"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth1"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth1"][metadata.MASTER_TYPE] = TYPE_BOND
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -99,26 +99,26 @@ class TestDesiredStateBondMetadata:
desired_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1'])
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"])
]
}
)
current_state = state.State(
{
Interface.KEY: [
{'name': 'eth0', 'type': 'unknown'},
{'name': 'eth1', 'type': 'unknown'},
{"name": "eth0", "type": "unknown"},
{"name": "eth1", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces['eth1'] = {'name': 'eth1', 'state': 'up'}
expected_dstate.interfaces['eth1'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth1'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth1"] = {"name": "eth1", "state": "up"}
expected_dstate.interfaces["eth1"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth1"][metadata.MASTER_TYPE] = TYPE_BOND
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -129,16 +129,16 @@ class TestDesiredStateBondMetadata:
desired_state = state.State(
{
Interface.KEY: [
{'name': BOND_NAME, 'type': TYPE_BOND, 'state': 'down'}
{"name": BOND_NAME, "type": TYPE_BOND, "state": "down"}
]
}
)
current_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1']),
{'name': 'eth0', 'type': 'unknown'},
{'name': 'eth1', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"]),
{"name": "eth0", "type": "unknown"},
{"name": "eth1", "type": "unknown"},
]
}
)
@ -154,21 +154,21 @@ class TestDesiredStateBondMetadata:
desired_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1']),
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"]),
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
current_state = state.State(
{Interface.KEY: [{'name': 'eth0', 'type': 'unknown'}]}
{Interface.KEY: [{"name": "eth0", "type": "unknown"}]}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth1'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces['eth1'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth1"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth1"][metadata.MASTER_TYPE] = TYPE_BOND
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -177,23 +177,23 @@ class TestDesiredStateBondMetadata:
def test_bond_removing_slaves(self):
desired_state = state.State(
{Interface.KEY: [create_bond_state_dict(BOND_NAME, ['eth0'])]}
{Interface.KEY: [create_bond_state_dict(BOND_NAME, ["eth0"])]}
)
current_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1']),
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"]),
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces['eth1'] = {'name': 'eth1'}
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth1"] = {"name": "eth1"}
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -204,23 +204,23 @@ class TestDesiredStateBondMetadata:
desired_state = state.State(
{
Interface.KEY: [
{'name': 'eth0', 'type': 'unknown', 'fookey': 'fooval'}
{"name": "eth0", "type": "unknown", "fookey": "fooval"}
]
}
)
current_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1']),
{'name': 'eth0', 'type': 'unknown'},
{'name': 'eth1', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"]),
{"name": "eth0", "type": "unknown"},
{"name": "eth1", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth0"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_BOND
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -228,24 +228,24 @@ class TestDesiredStateBondMetadata:
assert current_state == expected_cstate
def test_bond_reusing_slave_used_by_existing_bond(self):
BOND2_NAME = 'bond88'
BOND2_NAME = "bond88"
desired_state = state.State(
{Interface.KEY: [create_bond_state_dict(BOND2_NAME, ['eth0'])]}
{Interface.KEY: [create_bond_state_dict(BOND2_NAME, ["eth0"])]}
)
current_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1']),
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"]),
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = BOND2_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = BOND2_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_BOND
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -253,33 +253,33 @@ class TestDesiredStateBondMetadata:
assert current_state == expected_cstate
def test_swap_slaves_between_bonds(self):
BOND2_NAME = 'bond88'
BOND2_NAME = "bond88"
desired_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth1']),
create_bond_state_dict(BOND2_NAME, ['eth0']),
create_bond_state_dict(BOND_NAME, ["eth1"]),
create_bond_state_dict(BOND2_NAME, ["eth0"]),
]
}
)
current_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0']),
create_bond_state_dict(BOND2_NAME, ['eth1']),
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0"]),
create_bond_state_dict(BOND2_NAME, ["eth1"]),
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth1'] = {'name': 'eth1', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = BOND2_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces['eth1'][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces['eth1'][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth1"] = {"name": "eth1", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = BOND2_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_BOND
expected_dstate.interfaces["eth1"][metadata.MASTER] = BOND_NAME
expected_dstate.interfaces["eth1"][metadata.MASTER_TYPE] = TYPE_BOND
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -295,7 +295,7 @@ class TestDesiredStateBondMetadata:
Interface.STATE: InterfaceState.ABSENT,
},
{
Interface.NAME: 'eth0',
Interface.NAME: "eth0",
Interface.STATE: InterfaceState.UP,
Interface.TYPE: InterfaceType.UNKNOWN,
},
@ -305,9 +305,9 @@ class TestDesiredStateBondMetadata:
current_state = state.State(
{
Interface.KEY: [
create_bond_state_dict(BOND_NAME, ['eth0', 'eth1']),
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
create_bond_state_dict(BOND_NAME, ["eth0", "eth1"]),
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
@ -323,10 +323,10 @@ class TestDesiredStateBondMetadata:
def create_bond_state_dict(name, slaves=None):
slaves = slaves or []
return {
'name': name,
'type': TYPE_BOND,
'state': 'up',
'link-aggregation': {'mode': 'balance-rr', 'slaves': slaves},
"name": name,
"type": TYPE_BOND,
"state": "up",
"link-aggregation": {"mode": "balance-rr", "slaves": slaves},
}
@ -336,31 +336,31 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {
'port': [{'name': 'eth0'}, {'name': 'eth1'}]
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {
"port": [{"name": "eth0"}, {"name": "eth1"}]
},
},
{'name': 'eth0', 'type': 'unknown'},
{'name': 'eth1', 'type': 'unknown'},
{"name": "eth0", "type": "unknown"},
{"name": "eth1", "type": "unknown"},
]
}
)
current_state = state.State({})
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth1'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth1'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth0'][
expected_dstate.interfaces["eth0"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth1"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth1"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth0"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS_NAME]['bridge']['port'][0]
expected_dstate.interfaces['eth1'][
] = desired_state.interfaces[OVS_NAME]["bridge"]["port"][0]
expected_dstate.interfaces["eth1"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS_NAME]['bridge']['port'][1]
] = desired_state.interfaces[OVS_NAME]["bridge"]["port"][1]
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -372,11 +372,11 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {
'port': [{'name': 'eth0'}, {'name': 'eth1'}]
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {
"port": [{"name": "eth0"}, {"name": "eth1"}]
},
}
]
@ -385,25 +385,25 @@ class TestDesiredStateOvsMetadata:
current_state = state.State(
{
Interface.KEY: [
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth1'] = {'name': 'eth1', 'state': 'up'}
expected_dstate.interfaces['eth1'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth1'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth0'][
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth1"] = {"name": "eth1", "state": "up"}
expected_dstate.interfaces["eth1"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth1"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth0"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS_NAME]['bridge']['port'][0]
expected_dstate.interfaces['eth1'][
] = desired_state.interfaces[OVS_NAME]["bridge"]["port"][0]
expected_dstate.interfaces["eth1"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS_NAME]['bridge']['port'][1]
] = desired_state.interfaces[OVS_NAME]["bridge"]["port"][1]
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -414,7 +414,7 @@ class TestDesiredStateOvsMetadata:
desired_state = state.State(
{
Interface.KEY: [
{'name': OVS_NAME, 'type': TYPE_OVS_BR, 'state': 'down'}
{"name": OVS_NAME, "type": TYPE_OVS_BR, "state": "down"}
]
}
)
@ -422,15 +422,15 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {
'port': [{'name': 'eth0'}, {'name': 'eth1'}]
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {
"port": [{"name": "eth0"}, {"name": "eth1"}]
},
},
{'name': 'eth0', 'type': 'unknown'},
{'name': 'eth1', 'type': 'unknown'},
{"name": "eth0", "type": "unknown"},
{"name": "eth1", "type": "unknown"},
]
}
)
@ -447,37 +447,37 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {
'port': [{'name': 'eth0'}, {'name': 'eth1'}]
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {
"port": [{"name": "eth0"}, {"name": "eth1"}]
},
},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
current_state = state.State(
{
Interface.KEY: [
{'name': 'eth0', 'state': 'up', 'type': 'unknown'}
{"name": "eth0", "state": "up", "type": "unknown"}
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth1'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth1'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth0'][
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth1"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth1"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth0"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS_NAME]['bridge']['port'][0]
expected_dstate.interfaces['eth1'][
] = desired_state.interfaces[OVS_NAME]["bridge"]["port"][0]
expected_dstate.interfaces["eth1"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS_NAME]['bridge']['port'][1]
] = desired_state.interfaces[OVS_NAME]["bridge"]["port"][1]
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -489,10 +489,10 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {'port': [{'name': 'eth0'}]},
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {"port": [{"name": "eth0"}]},
}
]
}
@ -501,27 +501,27 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {
'port': [{'name': 'eth0'}, {'name': 'eth1'}]
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {
"port": [{"name": "eth0"}, {"name": "eth1"}]
},
},
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth1'] = {'name': 'eth1'}
expected_dstate.interfaces['eth0'][
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth1"] = {"name": "eth1"}
expected_dstate.interfaces["eth0"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS_NAME]['bridge']['port'][0]
] = desired_state.interfaces[OVS_NAME]["bridge"]["port"][0]
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -532,7 +532,7 @@ class TestDesiredStateOvsMetadata:
desired_state = state.State(
{
Interface.KEY: [
{'name': 'eth0', 'type': 'unknown', 'fookey': 'fooval'}
{"name": "eth0", "type": "unknown", "fookey": "fooval"}
]
}
)
@ -540,25 +540,25 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {
'port': [{'name': 'eth0'}, {'name': 'eth1'}]
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {
"port": [{"name": "eth0"}, {"name": "eth1"}]
},
},
{'name': 'eth0', 'type': 'unknown'},
{'name': 'eth1', 'type': 'unknown'},
{"name": "eth0", "type": "unknown"},
{"name": "eth1", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth0'][
expected_dstate.interfaces["eth0"][metadata.MASTER] = OVS_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth0"][
metadata.BRPORT_OPTIONS
] = current_state.interfaces[OVS_NAME]['bridge']['port'][0]
] = current_state.interfaces[OVS_NAME]["bridge"]["port"][0]
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -566,15 +566,15 @@ class TestDesiredStateOvsMetadata:
assert current_state == expected_cstate
def test_ovs_reusing_slave_used_by_existing_bridge(self):
OVS2_NAME = 'ovs-br88'
OVS2_NAME = "ovs-br88"
desired_state = state.State(
{
Interface.KEY: [
{
'name': OVS2_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {'port': [{'name': 'eth0'}]},
"name": OVS2_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {"port": [{"name": "eth0"}]},
}
]
}
@ -583,26 +583,26 @@ class TestDesiredStateOvsMetadata:
{
Interface.KEY: [
{
'name': OVS_NAME,
'type': TYPE_OVS_BR,
'state': 'up',
'bridge': {
'port': [{'name': 'eth0'}, {'name': 'eth1'}]
"name": OVS_NAME,
"type": TYPE_OVS_BR,
"state": "up",
"bridge": {
"port": [{"name": "eth0"}, {"name": "eth1"}]
},
},
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
expected_dstate = state.State(desired_state.state)
expected_cstate = state.State(current_state.state)
expected_dstate.interfaces['eth0'] = {'name': 'eth0', 'state': 'up'}
expected_dstate.interfaces['eth0'][metadata.MASTER] = OVS2_NAME
expected_dstate.interfaces['eth0'][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces['eth0'][
expected_dstate.interfaces["eth0"] = {"name": "eth0", "state": "up"}
expected_dstate.interfaces["eth0"][metadata.MASTER] = OVS2_NAME
expected_dstate.interfaces["eth0"][metadata.MASTER_TYPE] = TYPE_OVS_BR
expected_dstate.interfaces["eth0"][
metadata.BRPORT_OPTIONS
] = desired_state.interfaces[OVS2_NAME]['bridge']['port'][0]
] = desired_state.interfaces[OVS2_NAME]["bridge"]["port"][0]
metadata.generate_ifaces_metadata(desired_state, current_state)
@ -646,27 +646,27 @@ class TestRouteMetadata:
route0 = self._create_route0()
desired_state = state.State(
{
Interface.KEY: [_create_interface_state('foo')],
Interface.KEY: [_create_interface_state("foo")],
Route.KEY: {Route.CONFIG: [route0.to_dict()]},
}
)
current_state = state.State(
{
Interface.KEY: [_create_interface_state('boo')],
Interface.KEY: [_create_interface_state("boo")],
Route.KEY: {Route.CONFIG: []},
}
)
metadata.generate_ifaces_metadata(desired_state, current_state)
assert 'foo' in desired_state.interfaces
assert metadata.ROUTES not in desired_state.interfaces['foo']
assert "foo" in desired_state.interfaces
assert metadata.ROUTES not in desired_state.interfaces["foo"]
def test_route_with_matching_desired_interface(self):
route0 = self._create_route0()
desired_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {Route.CONFIG: [route0.to_dict()]},
}
)
@ -674,7 +674,7 @@ class TestRouteMetadata:
metadata.generate_ifaces_metadata(desired_state, current_state)
iface_state = desired_state.interfaces['eth1']
iface_state = desired_state.interfaces["eth1"]
(route_metadata,) = iface_state[Interface.IPV4][metadata.ROUTES]
assert route0.to_dict() == route_metadata
@ -685,14 +685,14 @@ class TestRouteMetadata:
)
current_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {Route.CONFIG: []},
}
)
metadata.generate_ifaces_metadata(desired_state, current_state)
iface_state = desired_state.interfaces['eth1']
iface_state = desired_state.interfaces["eth1"]
(route_metadata,) = iface_state[Interface.IPV4][metadata.ROUTES]
assert route0.to_dict() == route_metadata
@ -701,7 +701,7 @@ class TestRouteMetadata:
route1 = self._create_route1()
desired_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {
Route.CONFIG: [route0.to_dict(), route1.to_dict()]
},
@ -709,26 +709,26 @@ class TestRouteMetadata:
)
current_state = state.State(
{
Interface.KEY: [_create_interface_state('eth2')],
Interface.KEY: [_create_interface_state("eth2")],
Route.KEY: {Route.CONFIG: []},
}
)
metadata.generate_ifaces_metadata(desired_state, current_state)
iface0_state = desired_state.interfaces['eth1']
iface1_state = desired_state.interfaces['eth2']
iface0_state = desired_state.interfaces["eth1"]
iface1_state = desired_state.interfaces["eth2"]
(route0_metadata,) = iface0_state[Interface.IPV4][metadata.ROUTES]
(route1_metadata,) = iface1_state[Interface.IPV6][metadata.ROUTES]
assert route0.to_dict() == route0_metadata
assert route1.to_dict() == route1_metadata
def _create_route0(self):
return _create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103)
return _create_route("198.51.100.0/24", "192.0.2.1", "eth1", 50, 103)
def _create_route1(self):
return _create_route(
'2001:db8:a::/64', '2001:db8:1::a', 'eth2', 51, 104
"2001:db8:a::/64", "2001:db8:1::a", "eth2", 51, 104
)
@ -774,8 +774,8 @@ def test_dns_gen_metadata_static_gateway_ipv6_name_server_before_ipv4(
nm_dns_mock,
):
dns_config = {
DNS.SERVER: ['2001:4860:4860::8888', '8.8.8.8'],
DNS.SEARCH: ['example.org', 'example.com'],
DNS.SERVER: ["2001:4860:4860::8888", "8.8.8.8"],
DNS.SEARCH: ["example.org", "example.com"],
}
desired_state = state.State(
@ -789,13 +789,13 @@ def test_dns_gen_metadata_static_gateway_ipv6_name_server_before_ipv4(
metadata.generate_ifaces_metadata(desired_state, current_state)
ipv4_dns_config = {
DNS.SERVER: ['8.8.8.8'],
DNS.SERVER: ["8.8.8.8"],
DNS.SEARCH: [],
nm_dns.DNS_METADATA_PRIORITY: nm_dns.DNS_PRIORITY_STATIC_BASE + 1,
}
ipv6_dns_config = {
DNS.SERVER: ['2001:4860:4860::8888'],
DNS.SEARCH: ['example.org', 'example.com'],
DNS.SERVER: ["2001:4860:4860::8888"],
DNS.SEARCH: ["example.org", "example.com"],
nm_dns.DNS_METADATA_PRIORITY: nm_dns.DNS_PRIORITY_STATIC_BASE,
}
iface_state = desired_state.interfaces[TEST_IFACE1]
@ -807,8 +807,8 @@ def test_dns_gen_metadata_static_gateway_ipv6_name_server_after_ipv4(
nm_dns_mock,
):
dns_config = {
DNS.SERVER: ['8.8.8.8', '2001:4860:4860::8888'],
DNS.SEARCH: ['example.org', 'example.com'],
DNS.SERVER: ["8.8.8.8", "2001:4860:4860::8888"],
DNS.SEARCH: ["example.org", "example.com"],
}
desired_state = state.State(
@ -822,12 +822,12 @@ def test_dns_gen_metadata_static_gateway_ipv6_name_server_after_ipv4(
metadata.generate_ifaces_metadata(desired_state, current_state)
ipv4_dns_config = {
DNS.SERVER: ['8.8.8.8'],
DNS.SEARCH: ['example.org', 'example.com'],
DNS.SERVER: ["8.8.8.8"],
DNS.SEARCH: ["example.org", "example.com"],
nm_dns.DNS_METADATA_PRIORITY: nm_dns.DNS_PRIORITY_STATIC_BASE,
}
ipv6_dns_config = {
DNS.SERVER: ['2001:4860:4860::8888'],
DNS.SERVER: ["2001:4860:4860::8888"],
DNS.SEARCH: [],
nm_dns.DNS_METADATA_PRIORITY: nm_dns.DNS_PRIORITY_STATIC_BASE + 1,
}
@ -838,8 +838,8 @@ def test_dns_gen_metadata_static_gateway_ipv6_name_server_after_ipv4(
def test_dns_metadata_interface_not_included_in_desire(nm_dns_mock):
dns_config = {
DNS.SERVER: ['2001:4860:4860::8888', '8.8.8.8'],
DNS.SEARCH: ['example.org', 'example.com'],
DNS.SERVER: ["2001:4860:4860::8888", "8.8.8.8"],
DNS.SEARCH: ["example.org", "example.com"],
}
desired_state = state.State(
@ -858,13 +858,13 @@ def test_dns_metadata_interface_not_included_in_desire(nm_dns_mock):
metadata.generate_ifaces_metadata(desired_state, current_state)
iface_state = desired_state.interfaces[TEST_IFACE1]
ipv4_dns_config = {
DNS.SERVER: ['8.8.8.8'],
DNS.SERVER: ["8.8.8.8"],
DNS.SEARCH: [],
nm_dns.DNS_METADATA_PRIORITY: nm_dns.DNS_PRIORITY_STATIC_BASE + 1,
}
ipv6_dns_config = {
DNS.SERVER: ['2001:4860:4860::8888'],
DNS.SEARCH: ['example.org', 'example.com'],
DNS.SERVER: ["2001:4860:4860::8888"],
DNS.SEARCH: ["example.org", "example.com"],
nm_dns.DNS_METADATA_PRIORITY: nm_dns.DNS_PRIORITY_STATIC_BASE,
}
assert ipv4_dns_config == iface_state[Interface.IPV4][nm_dns.DNS_METADATA]
@ -880,7 +880,7 @@ def _get_test_iface_states():
Interface.IPV4: {
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '192.0.2.251',
InterfaceIPv4.ADDRESS_IP: "192.0.2.251",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
}
],
@ -890,7 +890,7 @@ def _get_test_iface_states():
Interface.IPV6: {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: '2001:db8:1::1',
InterfaceIPv6.ADDRESS_IP: "2001:db8:1::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
}
],
@ -900,13 +900,13 @@ def _get_test_iface_states():
},
},
{
Interface.NAME: 'eth2',
Interface.NAME: "eth2",
Interface.STATE: InterfaceState.UP,
Interface.TYPE: InterfaceType.ETHERNET,
Interface.IPV4: {
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '198.51.100.1',
InterfaceIPv4.ADDRESS_IP: "198.51.100.1",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
}
],
@ -916,7 +916,7 @@ def _get_test_iface_states():
Interface.IPV6: {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: '2001:db8:2::1',
InterfaceIPv6.ADDRESS_IP: "2001:db8:2::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
}
],
@ -931,16 +931,16 @@ def _get_test_iface_states():
def _gen_default_gateway_route(iface_name):
return [
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.METRIC: 200,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.NEXT_HOP_INTERFACE: iface_name,
Route.TABLE_ID: 54,
},
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '2001:db8:2::f',
Route.NEXT_HOP_ADDRESS: "2001:db8:2::f",
Route.NEXT_HOP_INTERFACE: iface_name,
Route.TABLE_ID: 54,
},
@ -986,43 +986,43 @@ class TestRouteRuleMetadata:
def test_rule_with_no_matching_route_table(self):
rule0 = self._create_rule0()
route = _create_route(
'198.51.100.0/24',
'192.0.2.1',
'eth1',
"198.51.100.0/24",
"192.0.2.1",
"eth1",
TestRouteRuleMetadata.TEST_ROUTE_TABLE + 1,
103,
)
desired_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {Route.CONFIG: [route.to_dict()]},
RouteRule.KEY: {RouteRule.CONFIG: [rule0.to_dict()]},
}
)
current_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {Route.CONFIG: [route.to_dict()]},
}
)
rule0 = self._create_rule0()
route = _create_route(
'198.51.100.0/24',
'192.0.2.1',
'eth1',
"198.51.100.0/24",
"192.0.2.1",
"eth1",
TestRouteRuleMetadata.TEST_ROUTE_TABLE + 1,
103,
)
desired_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {Route.CONFIG: [route.to_dict()]},
RouteRule.KEY: {RouteRule.CONFIG: [rule0.to_dict()]},
}
)
current_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {Route.CONFIG: [route.to_dict()]},
}
)
@ -1034,22 +1034,22 @@ class TestRouteRuleMetadata:
rule0 = self._create_rule0()
rule1 = self._create_rule1()
route0 = _create_route(
'198.51.100.0/24',
'192.0.2.1',
'eth1',
"198.51.100.0/24",
"192.0.2.1",
"eth1",
TestRouteRuleMetadata.TEST_ROUTE_TABLE,
103,
)
route1 = _create_route(
'2001:db8:f::/64',
'2001:db8:e::',
'eth1',
"2001:db8:f::/64",
"2001:db8:e::",
"eth1",
TestRouteRuleMetadata.TEST_ROUTE_TABLE,
103,
)
desired_state = state.State(
{
Interface.KEY: [_create_interface_state('eth1')],
Interface.KEY: [_create_interface_state("eth1")],
Route.KEY: {
Route.CONFIG: [route0.to_dict(), route1.to_dict()]
},
@ -1062,7 +1062,7 @@ class TestRouteRuleMetadata:
metadata.generate_ifaces_metadata(desired_state, current_state)
iface_state = desired_state.interfaces['eth1']
iface_state = desired_state.interfaces["eth1"]
(rule0_metadata,) = iface_state[Interface.IPV4][
metadata.ROUTE_RULES_METADATA
]
@ -1074,16 +1074,16 @@ class TestRouteRuleMetadata:
def _create_rule0(self):
return _create_rule(
'198.51.100.0/24',
'192.0.2.1',
"198.51.100.0/24",
"192.0.2.1",
103,
TestRouteRuleMetadata.TEST_ROUTE_TABLE,
)
def _create_rule1(self):
return _create_rule(
'2001:db8:a::/64',
'2001:db8:1::a',
"2001:db8:a::/64",
"2001:db8:1::a",
104,
TestRouteRuleMetadata.TEST_ROUTE_TABLE,
)

View File

@ -29,27 +29,27 @@ from libnmstate.schema import InterfaceIPv6
from libnmstate.schema import InterfaceType
INTERFACES = Constants.INTERFACES
BOND_TYPE = 'bond'
BOND_TYPE = "bond"
@pytest.fixture(scope='module', autouse=True)
@pytest.fixture(scope="module", autouse=True)
def nmclient_mock():
client_mock = mock.patch.object(netapplier.nmclient, 'client')
mainloop_mock = mock.patch.object(netapplier.nmclient, 'mainloop')
client_mock = mock.patch.object(netapplier.nmclient, "client")
mainloop_mock = mock.patch.object(netapplier.nmclient, "mainloop")
with client_mock, mainloop_mock:
yield
@pytest.fixture
def netapplier_nm_mock():
with mock.patch.object(netapplier, 'nm') as m:
with mock.patch.object(netapplier, "nm") as m:
m.applier.prepare_proxy_ifaces_desired_state.return_value = []
yield m
@pytest.fixture
def netinfo_nm_mock():
with mock.patch.object(netapplier.netinfo, 'nm') as m:
with mock.patch.object(netapplier.netinfo, "nm") as m:
m.ipv4.get_routing_rule_config.return_value = []
m.ipv6.get_routing_rule_config.return_value = []
yield m
@ -59,32 +59,32 @@ def test_iface_admin_state_change(netinfo_nm_mock, netapplier_nm_mock):
current_config = {
INTERFACES: [
{
'name': 'foo',
'type': InterfaceType.DUMMY,
'state': 'up',
'ipv4': {InterfaceIPv4.ENABLED: False},
'ipv6': {InterfaceIPv6.ENABLED: False},
"name": "foo",
"type": InterfaceType.DUMMY,
"state": "up",
"ipv4": {InterfaceIPv4.ENABLED: False},
"ipv6": {InterfaceIPv6.ENABLED: False},
}
]
}
desired_config = copy.deepcopy(current_config)
current_iface0 = current_config[INTERFACES][0]
netinfo_nm_mock.device.list_devices.return_value = ['one-item']
netinfo_nm_mock.device.list_devices.return_value = ["one-item"]
netinfo_nm_mock.translator.Nm2Api.get_common_device_info.return_value = (
current_iface0
)
netinfo_nm_mock.bond.is_bond_type_id.return_value = False
netinfo_nm_mock.ovs.is_ovs_bridge_type_id.return_value = False
netinfo_nm_mock.ovs.is_ovs_port_type_id.return_value = False
netinfo_nm_mock.ipv4.get_info.return_value = current_iface0['ipv4']
netinfo_nm_mock.ipv6.get_info.return_value = current_iface0['ipv6']
netinfo_nm_mock.ipv4.get_info.return_value = current_iface0["ipv4"]
netinfo_nm_mock.ipv6.get_info.return_value = current_iface0["ipv6"]
netinfo_nm_mock.ipv4.get_route_running.return_value = []
netinfo_nm_mock.ipv4.get_route_config.return_value = []
netinfo_nm_mock.ipv6.get_route_running.return_value = []
netinfo_nm_mock.ipv6.get_route_config.return_value = []
desired_config[INTERFACES][0]['state'] = 'down'
desired_config[INTERFACES][0]["state"] = "down"
netapplier.apply(desired_config, verify_change=False)
applier_mock = netapplier_nm_mock.applier
@ -114,16 +114,16 @@ def test_add_new_bond(netinfo_nm_mock, netapplier_nm_mock):
desired_config = {
INTERFACES: [
{
'name': 'bond99',
'type': BOND_TYPE,
'state': 'up',
'link-aggregation': {
'mode': 'balance-rr',
'slaves': [],
'options': {'miimon': 200},
"name": "bond99",
"type": BOND_TYPE,
"state": "up",
"link-aggregation": {
"mode": "balance-rr",
"slaves": [],
"options": {"miimon": 200},
},
'ipv4': {},
'ipv6': {},
"ipv4": {},
"ipv6": {},
}
]
}
@ -141,41 +141,41 @@ def test_edit_existing_bond(netinfo_nm_mock, netapplier_nm_mock):
current_config = {
INTERFACES: [
{
'name': 'bond99',
'type': BOND_TYPE,
'state': 'up',
'link-aggregation': {
'mode': 'balance-rr',
'slaves': [],
'options': {'miimon': '100'},
"name": "bond99",
"type": BOND_TYPE,
"state": "up",
"link-aggregation": {
"mode": "balance-rr",
"slaves": [],
"options": {"miimon": "100"},
},
'ipv4': {InterfaceIPv4.ENABLED: False},
'ipv6': {InterfaceIPv6.ENABLED: False},
"ipv4": {InterfaceIPv4.ENABLED: False},
"ipv6": {InterfaceIPv6.ENABLED: False},
}
]
}
current_iface0 = current_config[INTERFACES][0]
netinfo_nm_mock.device.list_devices.return_value = ['one-item']
netinfo_nm_mock.device.list_devices.return_value = ["one-item"]
netinfo_nm_mock.translator.Nm2Api.get_common_device_info.return_value = {
'name': current_iface0['name'],
'type': current_iface0['type'],
'state': current_iface0['state'],
"name": current_iface0["name"],
"type": current_iface0["type"],
"state": current_iface0["state"],
}
netinfo_nm_mock.bond.is_bond_type_id.return_value = True
netinfo_nm_mock.translator.Nm2Api.get_bond_info.return_value = {
'link-aggregation': current_iface0['link-aggregation']
"link-aggregation": current_iface0["link-aggregation"]
}
netinfo_nm_mock.ipv4.get_info.return_value = current_iface0['ipv4']
netinfo_nm_mock.ipv6.get_info.return_value = current_iface0['ipv6']
netinfo_nm_mock.ipv4.get_info.return_value = current_iface0["ipv4"]
netinfo_nm_mock.ipv6.get_info.return_value = current_iface0["ipv6"]
netinfo_nm_mock.ipv4.get_route_running.return_value = []
netinfo_nm_mock.ipv4.get_route_config.return_value = []
netinfo_nm_mock.ipv6.get_route_running.return_value = []
netinfo_nm_mock.ipv6.get_route_config.return_value = []
desired_config = copy.deepcopy(current_config)
options = desired_config[INTERFACES][0]['link-aggregation']['options']
options['miimon'] = 200
options = desired_config[INTERFACES][0]["link-aggregation"]["options"]
options["miimon"] = 200
netapplier.apply(desired_config, verify_change=False)

View File

@ -34,7 +34,7 @@ ROUTES = Constants.ROUTES
@pytest.fixture
def nm_mock():
with mock.patch.object(netinfo, 'nm') as m:
with mock.patch.object(netinfo, "nm") as m:
m.ipv4.get_routing_rule_config.return_value = []
m.ipv6.get_routing_rule_config.return_value = []
yield m
@ -42,34 +42,34 @@ def nm_mock():
@pytest.fixture
def nm_dns_mock():
with mock.patch.object(netinfo, 'nm_dns') as m:
with mock.patch.object(netinfo, "nm_dns") as m:
yield m
def test_netinfo_show_generic_iface(nm_mock, nm_dns_mock):
current_config = {
DNS.KEY: {DNS.RUNNING: {}, DNS.CONFIG: {}},
ROUTES: {'config': [], 'running': []},
ROUTES: {"config": [], "running": []},
RouteRule.KEY: {RouteRule.CONFIG: []},
INTERFACES: [
{
'name': 'foo',
'type': 'unknown',
'state': 'up',
'ipv4': {InterfaceIPv4.ENABLED: False},
'ipv6': {InterfaceIPv6.ENABLED: False},
"name": "foo",
"type": "unknown",
"state": "up",
"ipv4": {InterfaceIPv4.ENABLED: False},
"ipv6": {InterfaceIPv6.ENABLED: False},
}
],
}
current_iface0 = current_config[INTERFACES][0]
nm_mock.device.list_devices.return_value = ['one-item']
nm_mock.device.list_devices.return_value = ["one-item"]
nm_mock.translator.Nm2Api.get_common_device_info.return_value = (
current_iface0
)
nm_mock.bond.is_bond_type_id.return_value = False
nm_mock.ipv4.get_info.return_value = current_iface0['ipv4']
nm_mock.ipv6.get_info.return_value = current_iface0['ipv6']
nm_mock.ipv4.get_info.return_value = current_iface0["ipv4"]
nm_mock.ipv6.get_info.return_value = current_iface0["ipv6"]
nm_mock.ipv4.get_route_running.return_value = []
nm_mock.ipv4.get_route_config.return_value = []
nm_mock.ipv6.get_route_running.return_value = []
@ -85,36 +85,36 @@ def test_netinfo_show_generic_iface(nm_mock, nm_dns_mock):
def test_netinfo_show_bond_iface(nm_mock, nm_dns_mock):
current_config = {
DNS.KEY: {DNS.RUNNING: {}, DNS.CONFIG: {}},
ROUTES: {'config': [], 'running': []},
ROUTES: {"config": [], "running": []},
RouteRule.KEY: {RouteRule.CONFIG: []},
INTERFACES: [
{
'name': 'bond99',
'type': 'bond',
'state': 'up',
'link-aggregation': {
'mode': 'balance-rr',
'slaves': [],
'options': {'miimon': '100'},
"name": "bond99",
"type": "bond",
"state": "up",
"link-aggregation": {
"mode": "balance-rr",
"slaves": [],
"options": {"miimon": "100"},
},
'ipv4': {InterfaceIPv4.ENABLED: False},
'ipv6': {InterfaceIPv6.ENABLED: False},
"ipv4": {InterfaceIPv4.ENABLED: False},
"ipv6": {InterfaceIPv6.ENABLED: False},
}
],
}
nm_mock.device.list_devices.return_value = ['one-item']
nm_mock.device.list_devices.return_value = ["one-item"]
nm_mock.translator.Nm2Api.get_common_device_info.return_value = {
'name': current_config[INTERFACES][0]['name'],
'type': current_config[INTERFACES][0]['type'],
'state': current_config[INTERFACES][0]['state'],
"name": current_config[INTERFACES][0]["name"],
"type": current_config[INTERFACES][0]["type"],
"state": current_config[INTERFACES][0]["state"],
}
nm_mock.bond.is_bond_type_id.return_value = True
nm_mock.translator.Nm2Api.get_bond_info.return_value = {
'link-aggregation': current_config[INTERFACES][0]['link-aggregation']
"link-aggregation": current_config[INTERFACES][0]["link-aggregation"]
}
nm_mock.ipv4.get_info.return_value = current_config[INTERFACES][0]['ipv4']
nm_mock.ipv6.get_info.return_value = current_config[INTERFACES][0]['ipv6']
nm_mock.ipv4.get_info.return_value = current_config[INTERFACES][0]["ipv4"]
nm_mock.ipv6.get_info.return_value = current_config[INTERFACES][0]["ipv6"]
nm_mock.ipv4.get_route_running.return_value = []
nm_mock.ipv4.get_route_config.return_value = []
nm_mock.ipv6.get_route_running.return_value = []

View File

@ -27,41 +27,41 @@ from libnmstate import nm
@pytest.fixture
def nm_bond_mock():
with mock.patch.object(nm.applier, 'bond') as m:
with mock.patch.object(nm.applier, "bond") as m:
yield m
@pytest.fixture
def nm_connection_mock():
with mock.patch.object(nm.applier, 'connection') as m:
with mock.patch.object(nm.applier, "connection") as m:
yield m
@pytest.fixture
def nm_device_mock():
with mock.patch.object(nm.applier, 'device') as m:
with mock.patch.object(nm.applier, "device") as m:
yield m
@pytest.fixture
def nm_ipv4_mock():
with mock.patch.object(nm.applier, 'ipv4') as m:
with mock.patch.object(nm.applier, "ipv4") as m:
yield m
@pytest.fixture
def nm_ipv6_mock():
with mock.patch.object(nm.applier, 'ipv6') as m:
with mock.patch.object(nm.applier, "ipv6") as m:
yield m
@pytest.fixture
def nm_ovs_mock():
with mock.patch.object(nm.applier, 'ovs') as m:
with mock.patch.object(nm.applier, "ovs") as m:
yield m
@mock.patch.object(nm.connection, 'ConnectionProfile')
@mock.patch.object(nm.connection, "ConnectionProfile")
def test_create_new_ifaces(con_profile_mock):
con_profiles = [con_profile_mock(), con_profile_mock()]
@ -72,7 +72,7 @@ def test_create_new_ifaces(con_profile_mock):
@mock.patch.object(
nm.translator.Api2Nm, 'get_iface_type', staticmethod(lambda t: t)
nm.translator.Api2Nm, "get_iface_type", staticmethod(lambda t: t)
)
def test_prepare_new_ifaces_configuration(
nm_bond_mock, nm_connection_mock, nm_ipv4_mock, nm_ipv6_mock, nm_ovs_mock
@ -82,20 +82,20 @@ def test_prepare_new_ifaces_configuration(
ifaces_desired_state = [
{
'name': 'eth0',
'type': 'ethernet',
'state': 'up',
metadata.MASTER: 'bond99',
metadata.MASTER_TYPE: 'bond',
"name": "eth0",
"type": "ethernet",
"state": "up",
metadata.MASTER: "bond99",
metadata.MASTER_TYPE: "bond",
},
{
'name': 'bond99',
'type': 'bond',
'state': 'up',
'link-aggregation': {
'mode': 'balance-rr',
'slaves': ['eth0'],
'options': {'miimon': 120},
"name": "bond99",
"type": "bond",
"state": "up",
"link-aggregation": {
"mode": "balance-rr",
"slaves": ["eth0"],
"options": {"miimon": 120},
},
},
]
@ -104,7 +104,7 @@ def test_prepare_new_ifaces_configuration(
con_setting = nm_connection_mock.ConnectionSetting.return_value
con_setting.set_master.assert_has_calls(
[mock.call('bond99', 'bond'), mock.call(None, None)], any_order=True
[mock.call("bond99", "bond"), mock.call(None, None)], any_order=True
)
con_profile = nm_connection_mock.ConnectionProfile.return_value
con_profile.create.assert_has_calls(
@ -128,7 +128,7 @@ def test_prepare_new_ifaces_configuration(
)
@mock.patch.object(nm.connection, 'ConnectionProfile')
@mock.patch.object(nm.connection, "ConnectionProfile")
def test_edit_existing_ifaces_with_profile(con_profile_mock, nm_device_mock):
con_profiles = [con_profile_mock(), con_profile_mock()]
@ -140,7 +140,7 @@ def test_edit_existing_ifaces_with_profile(con_profile_mock, nm_device_mock):
)
@mock.patch.object(nm.connection, 'ConnectionProfile')
@mock.patch.object(nm.connection, "ConnectionProfile")
def test_edit_existing_ifaces_without_profile(
con_profile_mock, nm_device_mock
):
@ -154,7 +154,7 @@ def test_edit_existing_ifaces_without_profile(
@mock.patch.object(
nm.translator.Api2Nm, 'get_iface_type', staticmethod(lambda t: t)
nm.translator.Api2Nm, "get_iface_type", staticmethod(lambda t: t)
)
def test_prepare_edited_ifaces_configuration(
nm_device_mock, nm_connection_mock, nm_ipv4_mock, nm_ipv6_mock, nm_ovs_mock
@ -163,7 +163,7 @@ def test_prepare_edited_ifaces_configuration(
nm_ovs_mock.translate_port_options.return_value = {}
ifaces_desired_state = [
{'name': 'eth0', 'type': 'ethernet', 'state': 'up'}
{"name": "eth0", "type": "ethernet", "state": "up"}
]
cons = nm.applier.prepare_edited_ifaces_configuration(ifaces_desired_state)
@ -176,10 +176,10 @@ def test_prepare_edited_ifaces_configuration(
class TestIfaceAdminStateControl:
def test_set_ifaces_admin_state_up(self, nm_device_mock):
ifaces_desired_state = [
{'name': 'eth0', 'type': 'ethernet', 'state': 'up'}
{"name": "eth0", "type": "ethernet", "state": "up"}
]
con_profile = mock.MagicMock()
con_profile.devname = ifaces_desired_state[0]['name']
con_profile.devname = ifaces_desired_state[0]["name"]
nm.applier.set_ifaces_admin_state(ifaces_desired_state, [con_profile])
nm_device_mock.modify.assert_called_once_with(
@ -188,7 +188,7 @@ class TestIfaceAdminStateControl:
def test_set_ifaces_admin_state_down(self, nm_device_mock):
ifaces_desired_state = [
{'name': 'eth0', 'type': 'ethernet', 'state': 'down'}
{"name": "eth0", "type": "ethernet", "state": "down"}
]
nm.applier.set_ifaces_admin_state(ifaces_desired_state)
@ -201,7 +201,7 @@ class TestIfaceAdminStateControl:
def test_set_ifaces_admin_state_absent(self, nm_device_mock):
ifaces_desired_state = [
{'name': 'eth0', 'type': 'ethernet', 'state': 'absent'}
{"name": "eth0", "type": "ethernet", "state": "absent"}
]
nm.applier.set_ifaces_admin_state(ifaces_desired_state)
@ -217,24 +217,24 @@ class TestIfaceAdminStateControl:
):
ifaces_desired_state = [
{
'name': 'bond0',
'type': 'bond',
'state': 'up',
'link-aggregation': {'mode': '802.3ad', 'slaves': ['eth0']},
"name": "bond0",
"type": "bond",
"state": "up",
"link-aggregation": {"mode": "802.3ad", "slaves": ["eth0"]},
},
{'name': 'eth0', 'type': 'ethernet', 'state': 'up'},
{"name": "eth0", "type": "ethernet", "state": "up"},
]
nm_device_mock.get_device_by_name = lambda devname: devname
bond = ifaces_desired_state[0]['name']
slaves = ifaces_desired_state[0]['link-aggregation']['slaves']
bond = ifaces_desired_state[0]["name"]
slaves = ifaces_desired_state[0]["link-aggregation"]["slaves"]
nm_bond_mock.BOND_TYPE = nm.bond.BOND_TYPE
nm_bond_mock.get_slaves.return_value = slaves
bond_con_profile = mock.MagicMock()
bond_con_profile.devname = ifaces_desired_state[0]['name']
bond_con_profile.devname = ifaces_desired_state[0]["name"]
slave_con_profile = mock.MagicMock()
slave_con_profile.devname = ifaces_desired_state[1]['name']
slave_con_profile.devname = ifaces_desired_state[1]["name"]
nm.applier.set_ifaces_admin_state(
ifaces_desired_state, [bond_con_profile, slave_con_profile]

View File

@ -29,39 +29,39 @@ def dev_mock():
return mock.MagicMock()
@mock.patch.object(nm.bond.nmclient, 'NM')
@mock.patch.object(nm.bond.nmclient, "NM")
def test_create_setting(NM_mock):
bond_setting_mock = NM_mock.SettingBond.new.return_value
bond_setting_mock.add_option.return_value = True
options = {'mode': 'balance-rr', 'miimon': '100'}
options = {"mode": "balance-rr", "miimon": "100"}
nm.bond.create_setting(options)
bond_setting_mock.add_option.assert_has_calls(
[mock.call('mode', 'balance-rr'), mock.call('miimon', '100')],
[mock.call("mode", "balance-rr"), mock.call("miimon", "100")],
any_order=True,
)
@mock.patch.object(nm.bond.nmclient, 'NM')
@mock.patch.object(nm.bond.nmclient, "NM")
def test_create_setting_with_invalid_bond_option(NM_mock):
bond_setting_mock = NM_mock.SettingBond.new.return_value
bond_setting_mock.add_option.return_value = False
options = {'mode': 'balance-rr', 'foo': '100'}
options = {"mode": "balance-rr", "foo": "100"}
with pytest.raises(NmstateValueError):
nm.bond.create_setting(options)
@mock.patch.object(nm.bond.nmclient, 'NM')
@mock.patch.object(nm.bond.nmclient, "NM")
def test_is_bond_type_id(NM_mock):
type_id = NM_mock.DeviceType.BOND
assert nm.bond.is_bond_type_id(type_id)
@mock.patch.object(nm.bond.connection, 'ConnectionProfile')
@mock.patch.object(nm.bond.connection, "ConnectionProfile")
def test_get_bond_info(con_profile_mock, dev_mock):
info = nm.bond.get_bond_info(dev_mock)
@ -73,7 +73,7 @@ def test_get_bond_info(con_profile_mock, dev_mock):
opts_mock = connection_mock.get_setting_bond.return_value.props.options
expected_info = {
'slaves': dev_mock.get_slaves.return_value,
'options': opts_mock,
"slaves": dev_mock.get_slaves.return_value,
"options": opts_mock,
}
assert expected_info == info

View File

@ -26,19 +26,19 @@ from libnmstate import nm
@pytest.fixture
def NM_mock():
with mock.patch.object(nm.connection.nmclient, 'NM') as m:
with mock.patch.object(nm.connection.nmclient, "NM") as m:
yield m
@pytest.fixture()
def client_mock():
with mock.patch.object(nm.connection.nmclient, 'client') as m:
with mock.patch.object(nm.connection.nmclient, "client") as m:
yield m.return_value
@pytest.fixture()
def mainloop_mock():
with mock.patch.object(nm.connection.nmclient, 'mainloop') as m:
with mock.patch.object(nm.connection.nmclient, "mainloop") as m:
yield m.return_value
@ -57,12 +57,12 @@ def test_create_profile(NM_mock):
def test_add_profile(client_mock, mainloop_mock):
save_to_disk = True
con_profile = nm.connection.ConnectionProfile('profile')
con_profile = nm.connection.ConnectionProfile("profile")
con_profile.add(save_to_disk)
mainloop_mock.push_action.assert_called_once_with(
client_mock.add_connection_async,
'profile',
"profile",
save_to_disk,
mainloop_mock.cancellable,
nm.connection.ConnectionProfile._add_connection_callback,
@ -71,13 +71,13 @@ def test_add_profile(client_mock, mainloop_mock):
def test_update_profile():
base_profile = nm.connection.ConnectionProfile('p')
base_profile = nm.connection.ConnectionProfile("p")
profile = mock.MagicMock()
con_profile = nm.connection.ConnectionProfile(profile)
con_profile.update(base_profile)
profile.replace_settings_from_connection.assert_called_once_with('p')
profile.replace_settings_from_connection.assert_called_once_with("p")
def test_commit_profile(mainloop_mock):
@ -97,12 +97,12 @@ def test_commit_profile(mainloop_mock):
def test_create_setting(NM_mock):
con_setting = nm.connection.ConnectionSetting()
con_setting.create('con-name', 'iface-name', 'iface-type')
con_setting.create("con-name", "iface-name", "iface-type")
assert con_setting.setting.props.id == 'con-name'
assert con_setting.setting.props.interface_name == 'iface-name'
assert con_setting.setting.props.id == "con-name"
assert con_setting.setting.props.interface_name == "iface-name"
assert con_setting.setting.props.uuid
assert con_setting.setting.props.type == 'iface-type'
assert con_setting.setting.props.type == "iface-type"
assert con_setting.setting.props.autoconnect is True
assert con_setting.setting.props.autoconnect_slaves == (
NM_mock.SettingConnectionAutoconnectSlaves.YES
@ -127,10 +127,10 @@ def test_duplicate_settings(NM_mock):
def test_set_master_setting():
con_setting = nm.connection.ConnectionSetting(mock.MagicMock())
con_setting.set_master('master0', 'slave-type')
con_setting.set_master("master0", "slave-type")
assert con_setting.setting.props.master == 'master0'
assert con_setting.setting.props.slave_type == 'slave-type'
assert con_setting.setting.props.master == "master0"
assert con_setting.setting.props.slave_type == "slave-type"
def test_get_device_connection():

View File

@ -25,23 +25,23 @@ from libnmstate import nm
@pytest.fixture
def NM_mock():
with mock.patch.object(nm.device.nmclient, 'NM') as m:
with mock.patch.object(nm.device.nmclient, "NM") as m:
yield m
@pytest.fixture()
def client_mock():
with mock.patch.object(nm.device.nmclient, 'client') as m:
with mock.patch.object(nm.device.nmclient, "client") as m:
yield m.return_value
@pytest.fixture()
def mainloop_mock():
with mock.patch.object(nm.device.nmclient, 'mainloop') as m:
with mock.patch.object(nm.device.nmclient, "mainloop") as m:
yield m.return_value
@mock.patch.object(nm.device.connection, 'ConnectionProfile')
@mock.patch.object(nm.device.connection, "ConnectionProfile")
def test_activate(con_profile_mock):
dev = mock.MagicMock()
con_profile = con_profile_mock()
@ -51,7 +51,7 @@ def test_activate(con_profile_mock):
con_profile.activate.assert_called_once()
@mock.patch.object(nm.device.ac, 'ActiveConnection')
@mock.patch.object(nm.device.ac, "ActiveConnection")
def test_deactivate(act_con_mock):
dev = mock.MagicMock()
act_con = act_con_mock()
@ -62,7 +62,7 @@ def test_deactivate(act_con_mock):
act_con.deactivate.assert_called_once()
@mock.patch.object(nm.connection, 'ConnectionProfile')
@mock.patch.object(nm.connection, "ConnectionProfile")
def test_delete(con_profile_mock):
dev = mock.MagicMock()
dev.get_available_connections.return_value = [mock.MagicMock()]
@ -74,7 +74,7 @@ def test_delete(con_profile_mock):
def test_get_device_by_name(client_mock):
devname = 'foo'
devname = "foo"
nm.device.get_device_by_name(devname)
client_mock.get_device_by_iface.assert_called_once_with(devname)
@ -92,9 +92,9 @@ def test_get_device_common_info():
info = nm.device.get_device_common_info(dev)
expected_info = {
'name': dev.get_iface.return_value,
'type_id': dev.get_device_type.return_value,
'type_name': dev.get_type_description.return_value,
'state': dev.get_state.return_value,
"name": dev.get_iface.return_value,
"type_id": dev.get_device_type.return_value,
"type_name": dev.get_type_description.return_value,
"state": dev.get_state.return_value,
}
assert expected_info == info

View File

@ -28,36 +28,36 @@ from libnmstate.schema import InterfaceIP
from libnmstate.schema import Route
TEST_IPV4_GATEWAY_IFACE = 'eth1'
TEST_IPV6_GATEWAY_IFACE = 'eth2'
TEST_STATIC_ROUTE_IFACE = 'eth3'
TEST_IPV4_GATEWAY_IFACE = "eth1"
TEST_IPV6_GATEWAY_IFACE = "eth2"
TEST_STATIC_ROUTE_IFACE = "eth3"
def _get_test_dns_v4():
return {
nm_dns.DNS_METADATA_PRIORITY: 40,
DNS.SERVER: ['8.8.8.8', '1.1.1.1'],
DNS.SEARCH: ['example.org', 'example.com'],
DNS.SERVER: ["8.8.8.8", "1.1.1.1"],
DNS.SEARCH: ["example.org", "example.com"],
}
def _get_test_dns_v6():
return {
nm_dns.DNS_METADATA_PRIORITY: 40,
DNS.SERVER: ['2001:4860:4860::8888', '2606:4700:4700::1111'],
DNS.SEARCH: ['example.net', 'example.edu'],
DNS.SERVER: ["2001:4860:4860::8888", "2606:4700:4700::1111"],
DNS.SEARCH: ["example.net", "example.edu"],
}
parametrize_ip_ver = pytest.mark.parametrize(
'nm_ip', [(nm_ipv4), (nm_ipv6)], ids=['ipv4', 'ipv6']
"nm_ip", [(nm_ipv4), (nm_ipv6)], ids=["ipv4", "ipv6"]
)
parametrize_ip_ver_dns = pytest.mark.parametrize(
'nm_ip, get_test_dns_func',
"nm_ip, get_test_dns_func",
[(nm_ipv4, _get_test_dns_v4), (nm_ipv6, _get_test_dns_v6)],
ids=['ipv4', 'ipv6'],
ids=["ipv4", "ipv6"],
)
@ -182,9 +182,9 @@ def test_find_interfaces_for_dns_with_no_gateway():
def _get_test_ipv4_gateway():
return [
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.METRIC: 200,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.NEXT_HOP_INTERFACE: TEST_IPV4_GATEWAY_IFACE,
Route.TABLE_ID: 54,
}
@ -194,9 +194,9 @@ def _get_test_ipv4_gateway():
def _get_test_ipv6_gateway():
return [
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '2001:db8:2::f',
Route.NEXT_HOP_ADDRESS: "2001:db8:2::f",
Route.NEXT_HOP_INTERFACE: TEST_IPV6_GATEWAY_IFACE,
Route.TABLE_ID: 54,
}
@ -206,16 +206,16 @@ def _get_test_ipv6_gateway():
def _get_test_static_routes():
return [
{
Route.DESTINATION: '2001:db8:3::1',
Route.DESTINATION: "2001:db8:3::1",
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '2001:db8:2::f',
Route.NEXT_HOP_ADDRESS: "2001:db8:2::f",
Route.NEXT_HOP_INTERFACE: TEST_STATIC_ROUTE_IFACE,
Route.TABLE_ID: 54,
},
{
Route.DESTINATION: '198.51.100.0/24',
Route.DESTINATION: "198.51.100.0/24",
Route.METRIC: 201,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.NEXT_HOP_INTERFACE: TEST_STATIC_ROUTE_IFACE,
Route.TABLE_ID: 54,
},

View File

@ -24,12 +24,12 @@ from unittest import mock
from libnmstate import nm
from libnmstate.schema import InterfaceIPv4
IPV4_ADDRESS1 = '192.0.2.251'
IPV4_ADDRESS1 = "192.0.2.251"
@pytest.fixture
def NM_mock():
with mock.patch.object(nm.ipv4.nmclient, 'NM') as m:
with mock.patch.object(nm.ipv4.nmclient, "NM") as m:
yield m
@ -68,11 +68,11 @@ def test_create_setting_with_static_addresses(NM_mock):
InterfaceIPv4.ENABLED: True,
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '10.10.10.1',
InterfaceIPv4.ADDRESS_IP: "10.10.10.1",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
},
{
InterfaceIPv4.ADDRESS_IP: '10.10.20.1',
InterfaceIPv4.ADDRESS_IP: "10.10.20.1",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
},
],

View File

@ -26,19 +26,19 @@ from libnmstate.schema import InterfaceIPv6
# IPv6 Address Prefix Reserved for Documentation:
# https://tools.ietf.org/html/rfc3849
IPV6_ADDRESS1 = '2001:db8:1::1'
IPV6_LINK_LOCAL_ADDRESS1 = 'fe80::1'
IPV6_ADDRESS1 = "2001:db8:1::1"
IPV6_LINK_LOCAL_ADDRESS1 = "fe80::1"
@pytest.fixture
def NM_mock():
with mock.patch.object(nm.ipv6.nmclient, 'NM') as m:
with mock.patch.object(nm.ipv6.nmclient, "NM") as m:
yield m
def test_create_setting_without_config(NM_mock):
NM_mock.SettingIP6Config.new().props.addresses = []
NM_mock.NM.SETTING_IP6_CONFIG_METHOD_DISABLED = 'disabled'
NM_mock.NM.SETTING_IP6_CONFIG_METHOD_DISABLED = "disabled"
ipv6_setting = nm.ipv6.create_setting(config=None, base_con_profile=None)
@ -49,7 +49,7 @@ def test_create_setting_without_config(NM_mock):
def test_create_setting_with_ipv6_disabled(NM_mock):
NM_mock.SettingIP6Config.new().props.addresses = []
NM_mock.NM.SETTING_IP6_CONFIG_METHOD_DISABLED = 'disabled'
NM_mock.NM.SETTING_IP6_CONFIG_METHOD_DISABLED = "disabled"
ipv6_setting = nm.ipv6.create_setting(
config={InterfaceIPv6.ENABLED: False}, base_con_profile=None
@ -80,11 +80,11 @@ def test_create_setting_with_static_addresses(NM_mock):
InterfaceIPv6.ENABLED: True,
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: 'fd12:3456:789a:1::1',
InterfaceIPv6.ADDRESS_IP: "fd12:3456:789a:1::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 24,
},
{
InterfaceIPv6.ADDRESS_IP: 'fd12:3456:789a:2::1',
InterfaceIPv6.ADDRESS_IP: "fd12:3456:789a:2::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 24,
},
],

View File

@ -26,19 +26,19 @@ from libnmstate import nm
@pytest.fixture
def NM_mock():
with mock.patch.object(nm.ovs.nmclient, 'NM') as m:
with mock.patch.object(nm.ovs.nmclient, "NM") as m:
yield m
@pytest.fixture
def nm_connection_mock():
with mock.patch.object(nm.ovs, 'connection') as m:
with mock.patch.object(nm.ovs, "connection") as m:
yield m
@pytest.fixture
def nm_device_mock():
with mock.patch.object(nm.ovs, 'device') as m:
with mock.patch.object(nm.ovs, "device") as m:
yield m
@ -65,12 +65,12 @@ def test_get_ovs_info_without_ports(nm_connection_mock, NM_mock):
info = nm.ovs.get_ovs_info(bridge_device, device_info)
expected_info = {
'port': [],
'options': {
'fail-mode': '',
'mcast-snooping-enable': False,
'rstp': False,
'stp': False,
"port": [],
"options": {
"fail-mode": "",
"mcast-snooping-enable": False,
"rstp": False,
"stp": False,
},
}
assert expected_info == info
@ -89,12 +89,12 @@ def test_get_ovs_info_with_ports_without_interfaces(
info = nm.ovs.get_ovs_info(bridge_device, device_info)
expected_info = {
'port': [],
'options': {
'fail-mode': '',
'mcast-snooping-enable': False,
'rstp': False,
'stp': False,
"port": [],
"options": {
"fail-mode": "",
"mcast-snooping-enable": False,
"rstp": False,
"stp": False,
},
}
assert expected_info == info
@ -120,46 +120,46 @@ def test_get_ovs_info_with_ports_with_interfaces(
device_info = [(bridge_device, None), (port_device, None)]
info = nm.ovs.get_ovs_info(bridge_device, device_info)
assert len(info['port']) == 1
assert 'name' in info['port'][0]
assert 'vlan-mode' in info['port'][0]
assert 'access-tag' in info['port'][0]
assert len(info["port"]) == 1
assert "name" in info["port"][0]
assert "vlan-mode" in info["port"][0]
assert "access-tag" in info["port"][0]
def test_create_bridge_setting(NM_mock):
options = {
'fail-mode': 'foo',
'mcast-snooping-enable': False,
'rstp': False,
'stp': False,
"fail-mode": "foo",
"mcast-snooping-enable": False,
"rstp": False,
"stp": False,
}
bridge_setting = nm.ovs.create_bridge_setting(options)
assert bridge_setting.props.fail_mode == options['fail-mode']
assert bridge_setting.props.fail_mode == options["fail-mode"]
assert bridge_setting.props.mcast_snooping_enable == (
options['mcast-snooping-enable']
options["mcast-snooping-enable"]
)
assert bridge_setting.props.rstp_enable == options['rstp']
assert bridge_setting.props.stp_enable == options['stp']
assert bridge_setting.props.rstp_enable == options["rstp"]
assert bridge_setting.props.stp_enable == options["stp"]
def test_create_port_setting(NM_mock):
options = {
'tag': 101,
'vlan-mode': 'voomode',
'bond-mode': 'boomode',
'lacp': 'yes',
'bond-updelay': 0,
'bond-downdelay': 0,
"tag": 101,
"vlan-mode": "voomode",
"bond-mode": "boomode",
"lacp": "yes",
"bond-updelay": 0,
"bond-downdelay": 0,
}
port_setting = nm.ovs.create_port_setting(options)
assert port_setting.props.tag == options['tag']
assert port_setting.props.vlan_mode == options['vlan-mode']
assert port_setting.props.bond_mode == options['bond-mode']
assert port_setting.props.lacp == options['lacp']
assert port_setting.props.bond_updelay == options['bond-updelay']
assert port_setting.props.bond_downdelay == options['bond-downdelay']
assert port_setting.props.tag == options["tag"]
assert port_setting.props.vlan_mode == options["vlan-mode"]
assert port_setting.props.bond_mode == options["bond-mode"]
assert port_setting.props.lacp == options["lacp"]
assert port_setting.props.bond_updelay == options["bond-updelay"]
assert port_setting.props.bond_downdelay == options["bond-downdelay"]
def _mock_port_profile(nm_connection_mock):

View File

@ -29,59 +29,59 @@ from libnmstate.nm import connection as nm_connection
from libnmstate.schema import InterfaceIP
from libnmstate.schema import Route
IPV4_DEFAULT_GATEWAY_DESTINATION = '0.0.0.0/0'
IPV6_DEFAULT_GATEWAY_DESTINATION = '::/0'
IPV4_DEFAULT_GATEWAY_DESTINATION = "0.0.0.0/0"
IPV6_DEFAULT_GATEWAY_DESTINATION = "::/0"
IPV4_ROUTE1 = {
Route.DESTINATION: '198.51.100.0/24',
Route.DESTINATION: "198.51.100.0/24",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.TABLE_ID: 50,
}
IPV4_ROUTE2 = {
Route.DESTINATION: '203.0.113.0/24',
Route.DESTINATION: "203.0.113.0/24",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '192.0.2.2',
Route.NEXT_HOP_ADDRESS: "192.0.2.2",
Route.TABLE_ID: 51,
}
IPV6_ROUTE1 = {
Route.DESTINATION: '2001:db8:a::/64',
Route.DESTINATION: "2001:db8:a::/64",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::a',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::a",
Route.TABLE_ID: 50,
}
IPV6_ROUTE2 = {
Route.DESTINATION: '2001:db8:b::/64',
Route.DESTINATION: "2001:db8:b::/64",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::b',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::b",
Route.TABLE_ID: 51,
}
parametrize_ip_ver_routes = pytest.mark.parametrize(
'nm_ip, routes',
"nm_ip, routes",
[
(nm_ipv4, [IPV4_ROUTE1, IPV4_ROUTE2]),
(nm_ipv6, [IPV6_ROUTE1, IPV6_ROUTE2]),
],
ids=['ipv4', 'ipv6'],
ids=["ipv4", "ipv6"],
)
def _get_test_ipv4_gateways():
return [
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '192.0.2.1',
Route.NEXT_HOP_ADDRESS: "192.0.2.1",
Route.TABLE_ID: 52,
},
{
Route.DESTINATION: '0.0.0.0/0',
Route.DESTINATION: "0.0.0.0/0",
Route.METRIC: 101,
Route.NEXT_HOP_ADDRESS: '192.0.2.2',
Route.NEXT_HOP_ADDRESS: "192.0.2.2",
Route.TABLE_ID: 53,
},
]
@ -90,27 +90,27 @@ def _get_test_ipv4_gateways():
def _get_test_ipv6_gateways():
return [
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.METRIC: 103,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::f',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::f",
Route.TABLE_ID: 52,
},
{
Route.DESTINATION: '::/0',
Route.DESTINATION: "::/0",
Route.METRIC: 101,
Route.NEXT_HOP_ADDRESS: '2001:db8:1::e',
Route.NEXT_HOP_ADDRESS: "2001:db8:1::e",
Route.TABLE_ID: 53,
},
]
parametrize_ip_ver_routes_gw = pytest.mark.parametrize(
'nm_ip, routes, gateways',
"nm_ip, routes, gateways",
[
(nm_ipv4, [IPV4_ROUTE1, IPV4_ROUTE2], _get_test_ipv4_gateways()),
(nm_ipv6, [IPV6_ROUTE1, IPV6_ROUTE2], _get_test_ipv6_gateways()),
],
ids=['ipv4', 'ipv6'],
ids=["ipv4", "ipv6"],
)
@ -193,7 +193,7 @@ def test_change_gateway(nm_ip, routes, gateways):
@pytest.mark.xfail(
raises=NmstateNotImplementedError,
strict=True,
reason='Network Manager Bug: ' 'https://bugzilla.redhat.com/1707396',
reason="Network Manager Bug: " "https://bugzilla.redhat.com/1707396",
)
@parametrize_ip_ver_routes_gw
def test_add_two_gateway(nm_ip, routes, gateways):
@ -206,7 +206,7 @@ def test_add_two_gateway(nm_ip, routes, gateways):
@pytest.mark.xfail(
raises=NmstateNotImplementedError,
strict=True,
reason='Network Manager Bug: ' 'https://bugzilla.redhat.com/1707396',
reason="Network Manager Bug: " "https://bugzilla.redhat.com/1707396",
)
@parametrize_ip_ver_routes_gw
def test_add_duplicate_gateways(nm_ip, routes, gateways):
@ -263,12 +263,12 @@ def test_clear_gateway(nm_ip, routes, gateways):
def _nm_route_to_dict(nm_route):
dst = '{ip}/{prefix}'.format(
dst = "{ip}/{prefix}".format(
ip=nm_route.get_dest(), prefix=nm_route.get_prefix()
)
next_hop = nm_route.get_next_hop() or ''
next_hop = nm_route.get_next_hop() or ""
metric = int(nm_route.get_metric())
table_id_variant = nm_route.get_attribute('table')
table_id_variant = nm_route.get_attribute("table")
return {
Route.TABLE_ID: int(table_id_variant.get_uint32()),

View File

@ -24,14 +24,14 @@ from unittest import mock
from libnmstate import nm
@pytest.fixture(scope='module')
@pytest.fixture(scope="module")
def NM_mock():
saved_api2nm_map = nm.translator.Api2Nm._iface_types_map
saved_nm2api_map = nm.translator.Nm2Api._iface_types_map
nm.translator.Api2Nm._iface_types_map = None
nm.translator.Nm2Api._iface_types_map = None
with mock.patch.object(nm.translator.nmclient, 'NM') as m:
with mock.patch.object(nm.translator.nmclient, "NM") as m:
yield m
nm.translator.Api2Nm._iface_types_map = saved_api2nm_map
@ -42,38 +42,38 @@ def test_api2nm_iface_type_map(NM_mock):
map = nm.translator.Api2Nm.get_iface_type_map()
expected_map = {
'ethernet': NM_mock.SETTING_WIRED_SETTING_NAME,
'bond': NM_mock.SETTING_BOND_SETTING_NAME,
'dummy': NM_mock.SETTING_DUMMY_SETTING_NAME,
'ovs-bridge': NM_mock.SETTING_OVS_BRIDGE_SETTING_NAME,
'ovs-port': NM_mock.SETTING_OVS_PORT_SETTING_NAME,
'ovs-interface': NM_mock.SETTING_OVS_INTERFACE_SETTING_NAME,
'vlan': NM_mock.SETTING_VLAN_SETTING_NAME,
'linux-bridge': NM_mock.SETTING_BRIDGE_SETTING_NAME,
'vxlan': NM_mock.SETTING_VXLAN_SETTING_NAME,
"ethernet": NM_mock.SETTING_WIRED_SETTING_NAME,
"bond": NM_mock.SETTING_BOND_SETTING_NAME,
"dummy": NM_mock.SETTING_DUMMY_SETTING_NAME,
"ovs-bridge": NM_mock.SETTING_OVS_BRIDGE_SETTING_NAME,
"ovs-port": NM_mock.SETTING_OVS_PORT_SETTING_NAME,
"ovs-interface": NM_mock.SETTING_OVS_INTERFACE_SETTING_NAME,
"vlan": NM_mock.SETTING_VLAN_SETTING_NAME,
"linux-bridge": NM_mock.SETTING_BRIDGE_SETTING_NAME,
"vxlan": NM_mock.SETTING_VXLAN_SETTING_NAME,
}
assert map == expected_map
def test_api2nm_get_iface_type(NM_mock):
nm_type = nm.translator.Api2Nm.get_iface_type('ethernet')
nm_type = nm.translator.Api2Nm.get_iface_type("ethernet")
assert NM_mock.SETTING_WIRED_SETTING_NAME == nm_type
@mock.patch.object(
nm.translator.Api2Nm, 'get_iface_type', staticmethod(lambda t: t)
nm.translator.Api2Nm, "get_iface_type", staticmethod(lambda t: t)
)
def test_api2nm_bond_options():
bond_options = {
'name': 'bond99',
'type': 'bond',
'state': 'up',
'link-aggregation': {'mode': 'balance-rr', 'options': {'miimon': 120}},
"name": "bond99",
"type": "bond",
"state": "up",
"link-aggregation": {"mode": "balance-rr", "options": {"miimon": 120}},
}
nm_bond_options = nm.translator.Api2Nm.get_bond_options(bond_options)
assert {'miimon': 120, 'mode': 'balance-rr'} == nm_bond_options
assert {"miimon": 120, "mode": "balance-rr"} == nm_bond_options
def test_nm2api_common_device_info(NM_mock):
@ -81,33 +81,33 @@ def test_nm2api_common_device_info(NM_mock):
NM_mock.DeviceState.IP_CONFIG = 70
nm.nmclient.NM.DeviceState.DISCONNECTED = 30
devinfo = {
'name': 'devname',
'type_id': 'devtypeid',
'type_name': 'devtypename',
'state': nm.nmclient.NM.DeviceState.DISCONNECTED,
"name": "devname",
"type_id": "devtypeid",
"type_name": "devtypename",
"state": nm.nmclient.NM.DeviceState.DISCONNECTED,
}
info = nm.translator.Nm2Api.get_common_device_info(devinfo)
expected_info = {'name': 'devname', 'state': 'down', 'type': 'unknown'}
expected_info = {"name": "devname", "state": "down", "type": "unknown"}
assert expected_info == info
def test_nm2api_bond_info():
slaves_mock = [mock.MagicMock(), mock.MagicMock()]
bondinfo = {
'slaves': slaves_mock,
'options': {'mode': 'balance-rr', 'miimon': 120},
"slaves": slaves_mock,
"options": {"mode": "balance-rr", "miimon": 120},
}
info = nm.translator.Nm2Api.get_bond_info(bondinfo)
expected_info = {
'link-aggregation': {
'mode': 'balance-rr',
'slaves': [
"link-aggregation": {
"mode": "balance-rr",
"slaves": [
slaves_mock[0].props.interface,
slaves_mock[1].props.interface,
],
'options': {'miimon': 120},
"options": {"miimon": 120},
}
}
assert expected_info == info

View File

@ -26,7 +26,7 @@ from libnmstate import nm
@pytest.fixture
def NM_mock():
with mock.patch.object(nm.user.nmclient, 'NM') as m:
with mock.patch.object(nm.user.nmclient, "NM") as m:
yield m
@ -39,7 +39,7 @@ def test_create_setting_duplicate(NM_mock):
base_profile = mock.MagicMock()
setting = nm.user.create_setting(
{'description': 'test_interface'}, base_profile
{"description": "test_interface"}, base_profile
)
base_profile.get_setting_by_name.assert_called_with(
NM_mock.SETTING_USER_SETTING_NAME
@ -51,8 +51,8 @@ def test_create_setting_duplicate(NM_mock):
def test_create_setting_description(NM_mock):
setting = nm.user.create_setting({'description': 'test_interface'}, None)
setting = nm.user.create_setting({"description": "test_interface"}, None)
assert setting == NM_mock.SettingUser.new.return_value
setting.set_data.assert_called_with(
'nmstate.interface.description', 'test_interface'
"nmstate.interface.description", "test_interface"
)

View File

@ -27,7 +27,7 @@ from libnmstate import schema
@pytest.fixture
def NM_mock():
with mock.patch.object(nm.wired.nmclient, 'NM') as m:
with mock.patch.object(nm.wired.nmclient, "NM") as m:
yield m
@ -51,10 +51,10 @@ def test_create_setting_duplicate(NM_mock):
def test_create_setting_mac(NM_mock):
setting = nm.wired.create_setting(
{schema.Interface.MAC: '01:23:45:67:89:ab'}, None
{schema.Interface.MAC: "01:23:45:67:89:ab"}, None
)
assert setting == NM_mock.SettingWired.new.return_value
assert setting.props.cloned_mac_address == '01:23:45:67:89:ab'
assert setting.props.cloned_mac_address == "01:23:45:67:89:ab"
def test_create_setting_mtu(NM_mock):
@ -65,17 +65,17 @@ def test_create_setting_mtu(NM_mock):
@mock.patch.object(
nm.wired,
'minimal_ethtool',
"minimal_ethtool",
return_value={
'speed': 1337,
'duplex': 'full',
'auto-negotiation': 'mocked',
"speed": 1337,
"duplex": "full",
"auto-negotiation": "mocked",
},
)
def test_create_setting_auto_negotiation_False(ethtool_mock, NM_mock):
setting = nm.wired.create_setting(
{
schema.Interface.NAME: 'nmstate_test',
schema.Interface.NAME: "nmstate_test",
schema.Ethernet.CONFIG_SUBTREE: {
schema.Ethernet.AUTO_NEGOTIATION: False
},
@ -86,7 +86,7 @@ def test_create_setting_auto_negotiation_False(ethtool_mock, NM_mock):
assert setting.props.auto_negotiate is False
assert setting.props.speed == 1337
assert setting.props.duplex == schema.Ethernet.FULL_DUPLEX
assert ethtool_mock.called_with('nmstate_test')
assert ethtool_mock.called_with("nmstate_test")
def test_create_setting_only_auto_negotiation_True(NM_mock):
@ -138,17 +138,17 @@ def test_create_setting_speed_duplex(NM_mock):
@mock.patch.object(
nm.wired,
'minimal_ethtool',
"minimal_ethtool",
return_value={
'speed': 1500,
'duplex': 'unknown',
'auto-negotiation': True,
"speed": 1500,
"duplex": "unknown",
"auto-negotiation": True,
},
)
def test_get_info_with_invalid_duplex(ethtool_mock, NM_mock):
dev_mock = mock.MagicMock()
dev_mock.get_iface.return_value = 'nmstate_test'
dev_mock.get_hw_address.return_value = 'ab:cd:ef:01:23:45'
dev_mock.get_iface.return_value = "nmstate_test"
dev_mock.get_hw_address.return_value = "ab:cd:ef:01:23:45"
dev_mock.get_mtu.return_value = 1500
dev_mock.get_device_type.return_value = NM_mock.DeviceType.ETHERNET
@ -175,19 +175,19 @@ class TestWiredSetting:
assert not obj
def test_no_relevant_keys_is_false(self):
state = {'foo': 'boo'}
state = {"foo": "boo"}
obj = nm.wired.WiredSetting(state)
assert not obj
def test_relevant_keys_with_false_values_is_false(self):
state = {schema.Interface.MTU: 0, schema.Interface.MAC: ''}
state = {schema.Interface.MTU: 0, schema.Interface.MAC: ""}
obj = nm.wired.WiredSetting(state)
assert not obj
def test_partial_relevant_keys_is_true(self):
state = {schema.Interface.MTU: 1500, schema.Interface.MAC: 'abc'}
state = {schema.Interface.MTU: 1500, schema.Interface.MAC: "abc"}
obj = nm.wired.WiredSetting(state)
assert obj
@ -201,7 +201,7 @@ class TestWiredSetting:
assert not (obj1 != obj2)
def test_equality_for_partial_states(self):
state = {schema.Interface.MTU: 1500, schema.Interface.MAC: 'abc'}
state = {schema.Interface.MTU: 1500, schema.Interface.MAC: "abc"}
obj1 = nm.wired.WiredSetting(state)
obj2 = nm.wired.WiredSetting(state)
@ -209,8 +209,8 @@ class TestWiredSetting:
assert not (obj1 != obj2)
def test_inequality_for_partial_states(self):
state1 = {schema.Interface.MTU: 1500, schema.Interface.MAC: 'abc'}
state2 = {schema.Interface.MTU: 1000, schema.Interface.MAC: 'abc'}
state1 = {schema.Interface.MTU: 1500, schema.Interface.MAC: "abc"}
state2 = {schema.Interface.MTU: 1000, schema.Interface.MAC: "abc"}
obj1 = nm.wired.WiredSetting(state1)
obj2 = nm.wired.WiredSetting(state2)
@ -218,8 +218,8 @@ class TestWiredSetting:
assert not (obj1 == obj2)
def test_inequality_for_partial_states_with_missing_properties(self):
state1 = {schema.Interface.MTU: 1500, schema.Interface.MAC: 'abc'}
state2 = {schema.Interface.MAC: 'abc'}
state1 = {schema.Interface.MTU: 1500, schema.Interface.MAC: "abc"}
state2 = {schema.Interface.MAC: "abc"}
obj1 = nm.wired.WiredSetting(state1)
obj2 = nm.wired.WiredSetting(state2)
@ -228,16 +228,16 @@ class TestWiredSetting:
assert not (obj1 == obj2)
def test_hash_unique(self):
state = {schema.Interface.MTU: 1500, schema.Interface.MAC: 'abc'}
state = {schema.Interface.MTU: 1500, schema.Interface.MAC: "abc"}
obj1 = nm.wired.WiredSetting(state)
obj2 = nm.wired.WiredSetting(state)
assert hash(obj1) == hash(obj2)
def test_behaviour_with_set(self):
state1 = {schema.Interface.MTU: 1500, schema.Interface.MAC: 'abc'}
state2 = {schema.Interface.MTU: 1500, schema.Interface.MAC: 'abc'}
state3 = {schema.Interface.MAC: 'abc'}
state1 = {schema.Interface.MTU: 1500, schema.Interface.MAC: "abc"}
state2 = {schema.Interface.MTU: 1500, schema.Interface.MAC: "abc"}
state3 = {schema.Interface.MAC: "abc"}
obj1 = nm.wired.WiredSetting(state1)
obj2 = nm.wired.WiredSetting(state2)

View File

@ -23,20 +23,20 @@ from libnmstate.schema import OVSBridge
@pytest.mark.parametrize(
'changes',
"changes",
argvalues=[
['GROUP_FORWARD_MASK', LinuxBridge.Options.GROUP_FORWARD_MASK],
['MAC_AGEING_TIME', LinuxBridge.Options.MAC_AGEING_TIME],
['MULTICAST_SNOOPING', LinuxBridge.Options.MULTICAST_SNOOPING],
['PORT_NAME', LinuxBridge.Port.NAME],
['PORT_STP_HAIRPIN_MODE', LinuxBridge.Port.STP_HAIRPIN_MODE],
['PORT_STP_PATH_COST', LinuxBridge.Port.STP_PATH_COST],
['PORT_STP_PRIORITY', LinuxBridge.Port.STP_PRIORITY],
['STP_ENABLED', LinuxBridge.STP.ENABLED],
['STP_FORWARD_DELAY', LinuxBridge.STP.FORWARD_DELAY],
['STP_HELLO_TIME', LinuxBridge.STP.HELLO_TIME],
['STP_MAX_AGE', LinuxBridge.STP.MAX_AGE],
['STP_PRIORITY', LinuxBridge.STP.PRIORITY],
["GROUP_FORWARD_MASK", LinuxBridge.Options.GROUP_FORWARD_MASK],
["MAC_AGEING_TIME", LinuxBridge.Options.MAC_AGEING_TIME],
["MULTICAST_SNOOPING", LinuxBridge.Options.MULTICAST_SNOOPING],
["PORT_NAME", LinuxBridge.Port.NAME],
["PORT_STP_HAIRPIN_MODE", LinuxBridge.Port.STP_HAIRPIN_MODE],
["PORT_STP_PATH_COST", LinuxBridge.Port.STP_PATH_COST],
["PORT_STP_PRIORITY", LinuxBridge.Port.STP_PRIORITY],
["STP_ENABLED", LinuxBridge.STP.ENABLED],
["STP_FORWARD_DELAY", LinuxBridge.STP.FORWARD_DELAY],
["STP_HELLO_TIME", LinuxBridge.STP.HELLO_TIME],
["STP_MAX_AGE", LinuxBridge.STP.MAX_AGE],
["STP_PRIORITY", LinuxBridge.STP.PRIORITY],
],
)
def test_linuxbridge_deprecated_constants(changes):
@ -49,13 +49,13 @@ def test_linuxbridge_deprecated_constants(changes):
@pytest.mark.parametrize(
'changes',
"changes",
argvalues=[
['PORT_NAME', OVSBridge.Port.NAME],
['FAIL_MODE', OVSBridge.Options.FAIL_MODE],
['MCAST_SNOOPING_ENABLED', OVSBridge.Options.MCAST_SNOOPING_ENABLED],
['RSTP', OVSBridge.Options.RSTP],
['STP', OVSBridge.Options.STP],
["PORT_NAME", OVSBridge.Port.NAME],
["FAIL_MODE", OVSBridge.Options.FAIL_MODE],
["MCAST_SNOOPING_ENABLED", OVSBridge.Options.MCAST_SNOOPING_ENABLED],
["RSTP", OVSBridge.Options.RSTP],
["STP", OVSBridge.Options.STP],
],
)
def test_ovsbridge_deprecated_constants(changes):

View File

@ -37,69 +37,69 @@ from libnmstate.schema import VXLAN
INTERFACES = Constants.INTERFACES
ROUTES = Constants.ROUTES
THE_BRIDGE = 'br0'
VXLAN0 = 'vxlan0'
TEAM0 = 'team0'
THE_BRIDGE = "br0"
VXLAN0 = "vxlan0"
TEAM0 = "team0"
COMMON_DATA = {
INTERFACES: [
{
'name': 'lo',
'description': 'Loopback Interface',
'type': 'unknown',
'state': 'down',
'link-speed': 1000,
'mac-address': '12:34:56:78:90:ab',
'mtu': 1500,
"name": "lo",
"description": "Loopback Interface",
"type": "unknown",
"state": "down",
"link-speed": 1000,
"mac-address": "12:34:56:78:90:ab",
"mtu": 1500,
# Read Only entries
'if-index': 0,
'admin-status': 'up',
'link-status': 'down',
'phys-address': '12:34:56:78:90:ab',
'higher-layer-if': '',
'lower-layer-if': '',
'low-control': True,
'statistics': {
'in-octets': 0,
'in-unicast-pkts': 0,
'in-broadcast-pkts': 0,
'in-multicast-pkts': 0,
'in-discards': 0,
'in-errors': 0,
'out-octets': 0,
'out-unicast-pkts': 0,
'out-broadcast-pkts': 0,
'out-multicast-pkts': 0,
'out-discards': 0,
'out-errors': 0,
"if-index": 0,
"admin-status": "up",
"link-status": "down",
"phys-address": "12:34:56:78:90:ab",
"higher-layer-if": "",
"lower-layer-if": "",
"low-control": True,
"statistics": {
"in-octets": 0,
"in-unicast-pkts": 0,
"in-broadcast-pkts": 0,
"in-multicast-pkts": 0,
"in-discards": 0,
"in-errors": 0,
"out-octets": 0,
"out-unicast-pkts": 0,
"out-broadcast-pkts": 0,
"out-multicast-pkts": 0,
"out-discards": 0,
"out-errors": 0,
},
}
],
ROUTES: {
'config': [
"config": [
{
'table-id': 254,
'metric': 100,
'destination': '0.0.0.0/0',
'next-hop-interface': 'eth0',
'next-hop-address': '192.0.2.1',
"table-id": 254,
"metric": 100,
"destination": "0.0.0.0/0",
"next-hop-interface": "eth0",
"next-hop-address": "192.0.2.1",
}
],
'running': [
"running": [
{
'table-id': 254,
'metric': 100,
'destination': '::/0',
'next-hop-interface': 'eth0',
'next-hop-address': 'fe80::1',
"table-id": 254,
"metric": 100,
"destination": "::/0",
"next-hop-interface": "eth0",
"next-hop-address": "fe80::1",
}
],
},
RouteRule.KEY: {
RouteRule.CONFIG: [
{
RouteRule.IP_FROM: '192.0.2.0/24',
RouteRule.IP_TO: '198.51.100.0/24',
RouteRule.IP_FROM: "192.0.2.0/24",
RouteRule.IP_TO: "198.51.100.0/24",
RouteRule.PRIORITY: 500,
RouteRule.ROUTE_TABLE: 254,
}
@ -127,7 +127,7 @@ def default_data():
def portless_bridge_state():
return {
Interface.NAME: THE_BRIDGE,
Interface.STATE: 'up',
Interface.STATE: "up",
Interface.TYPE: LB.TYPE,
LB.CONFIG_SUBTREE: {LB.PORT_SUBTREE: []},
}
@ -135,7 +135,7 @@ def portless_bridge_state():
@pytest.fixture
def bridge_state(portless_bridge_state):
port = {LB.Port.NAME: 'eth1', LB.Port.VLAN_SUBTREE: {}}
port = {LB.Port.NAME: "eth1", LB.Port.VLAN_SUBTREE: {}}
portless_bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE].append(port)
return portless_bridge_state
@ -144,7 +144,7 @@ def bridge_state(portless_bridge_state):
def portless_ovs_bridge_state():
return {
Interface.NAME: THE_BRIDGE,
Interface.STATE: 'up',
Interface.STATE: "up",
Interface.TYPE: OVSBridge.TYPE,
LB.CONFIG_SUBTREE: {OVSBridge.PORT_SUBTREE: []},
}
@ -152,7 +152,7 @@ def portless_ovs_bridge_state():
@pytest.fixture
def ovs_bridge_state(portless_ovs_bridge_state):
port = {LB.Port.NAME: 'eth1', OVSBridge.Port.VLAN_SUBTREE: {}}
port = {LB.Port.NAME: "eth1", OVSBridge.Port.VLAN_SUBTREE: {}}
ovs_bridge_state_config = portless_ovs_bridge_state[
OVSBridge.CONFIG_SUBTREE
]
@ -165,13 +165,13 @@ class TestIfaceCommon:
libnmstate.validator.validate(default_data)
def test_invalid_instance(self, default_data):
default_data[INTERFACES][0]['state'] = 'bad-state'
default_data[INTERFACES][0]["state"] = "bad-state"
with pytest.raises(js.ValidationError):
libnmstate.validator.validate(default_data)
def test_invalid_type(self, default_data):
default_data[INTERFACES][0]['type'] = 'bad-type'
default_data[INTERFACES][0]["type"] = "bad-type"
with pytest.raises(js.ValidationError):
libnmstate.validator.validate(default_data)
@ -180,13 +180,13 @@ class TestIfaceCommon:
class TestIfaceTypeEthernet:
def test_valid_ethernet_with_auto_neg(self, default_data):
default_data[INTERFACES][0].update(
{'type': 'ethernet', 'auto-negotiation': True}
{"type": "ethernet", "auto-negotiation": True}
)
libnmstate.validator.validate(default_data)
def test_valid_ethernet_without_auto_neg(self, default_data):
default_data[INTERFACES][0].update(
{'auto-negotiation': False, 'link-speed': 1000, 'duplex': 'full'}
{"auto-negotiation": False, "link-speed": 1000, "duplex": "full"}
)
libnmstate.validator.validate(default_data)
@ -197,13 +197,13 @@ class TestIfaceTypeEthernet:
at the moment, deferring the handling to the application code.
"""
default_data[INTERFACES][0].update(
{'type': 'ethernet', 'auto-negotiation': False}
{"type": "ethernet", "auto-negotiation": False}
)
del default_data[INTERFACES][0]['link-speed']
del default_data[INTERFACES][0]["link-speed"]
libnmstate.validator.validate(default_data)
@pytest.mark.parametrize('valid_values', [0, 150, 256])
@pytest.mark.parametrize("valid_values", [0, 150, 256])
def test_valid_with_sriov_total_vfs(self, default_data, valid_values):
default_data[Interface.KEY][0].update(
{
@ -215,7 +215,7 @@ class TestIfaceTypeEthernet:
)
libnmstate.validator.validate(default_data)
@pytest.mark.parametrize('invalid_values', [-50, -1])
@pytest.mark.parametrize("invalid_values", [-50, -1])
def test_over_maximum_total_vfs_is_invalid(
self, default_data, invalid_values
):
@ -239,9 +239,9 @@ class TestIfaceTypeVxlan:
Interface.NAME: VXLAN0,
Interface.TYPE: VXLAN.TYPE,
VXLAN.CONFIG_SUBTREE: {
VXLAN.ID: 'badtype',
VXLAN.BASE_IFACE: 'eth1',
VXLAN.REMOTE: '192.168.3.3',
VXLAN.ID: "badtype",
VXLAN.BASE_IFACE: "eth1",
VXLAN.REMOTE: "192.168.3.3",
},
}
)
@ -256,8 +256,8 @@ class TestIfaceTypeVxlan:
Interface.TYPE: VXLAN.TYPE,
VXLAN.CONFIG_SUBTREE: {
VXLAN.ID: 16777216,
VXLAN.BASE_IFACE: 'eth1',
VXLAN.REMOTE: '192.168.3.3',
VXLAN.BASE_IFACE: "eth1",
VXLAN.REMOTE: "192.168.3.3",
},
}
)
@ -291,7 +291,7 @@ class TestIfaceTypeTeam:
Interface.NAME: TEAM0,
Interface.TYPE: Team.TYPE,
Team.CONFIG_SUBTREE: {
Team.PORT_SUBTREE: [{Team.Port.NAME: 'eth1'}]
Team.PORT_SUBTREE: [{Team.Port.NAME: "eth1"}]
},
}
)
@ -320,7 +320,7 @@ class TestIfaceTypeTeam:
Interface.NAME: TEAM0,
Interface.TYPE: Team.TYPE,
Team.CONFIG_SUBTREE: {
Team.PORT_SUBTREE: [{Team.Port.NAME: 'eth1'}],
Team.PORT_SUBTREE: [{Team.Port.NAME: "eth1"}],
Team.RUNNER_SUBTREE: {
Team.Runner.NAME: Team.Runner.RunnerMode.LOAD_BALANCE
},
@ -333,18 +333,18 @@ class TestIfaceTypeTeam:
class TestRoutes:
def test_valid_state_absent(self, default_data):
default_data[ROUTES]['config'][0]['state'] = 'absent'
default_data[ROUTES]["config"][0]["state"] = "absent"
libnmstate.validator.validate(default_data)
def test_invalid_state(self, default_data):
default_data[ROUTES]['config'][0]['state'] = 'bad-state'
default_data[ROUTES]["config"][0]["state"] = "bad-state"
with pytest.raises(js.ValidationError):
libnmstate.validator.validate(default_data)
class TestLinuxBridgeVlanFiltering:
@pytest.mark.parametrize('port_type', argvalues=['trunk', 'access'])
@pytest.mark.parametrize("port_type", argvalues=["trunk", "access"])
def test_vlan_port_types(self, default_data, bridge_state, port_type):
valid_port_type = self._generate_vlan_filtering_config(port_type)
the_port = bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE][0]
@ -354,7 +354,7 @@ class TestLinuxBridgeVlanFiltering:
libnmstate.validator.validate(default_data)
def test_invalid_vlan_port_type(self, default_data, bridge_state):
invalid_port_type = self._generate_vlan_filtering_config('fake-type')
invalid_port_type = self._generate_vlan_filtering_config("fake-type")
the_port = bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE][0]
the_port.update(invalid_port_type)
default_data[Interface.KEY].append(bridge_state)
@ -364,7 +364,7 @@ class TestLinuxBridgeVlanFiltering:
def test_access_port_accepted(self, default_data, bridge_state):
vlan_access_port_state = self._generate_vlan_filtering_config(
'access', access_tag=101
"access", access_tag=101
)
the_port = bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE][0]
the_port.update(vlan_access_port_state)
@ -374,7 +374,7 @@ class TestLinuxBridgeVlanFiltering:
def test_wrong_access_port_tag_type(self, default_data, bridge_state):
invalid_access_port_tag_type = self._generate_vlan_filtering_config(
'access', access_tag='holy-guacamole!'
"access", access_tag="holy-guacamole!"
)
the_port = bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE][0]
the_port.update(invalid_access_port_tag_type)
@ -385,7 +385,7 @@ class TestLinuxBridgeVlanFiltering:
def test_wrong_access_tag_range(self, default_data, bridge_state):
invalid_vlan_id_range = self._generate_vlan_filtering_config(
'access', access_tag=48000
"access", access_tag=48000
)
the_port = bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE][0]
the_port.update(invalid_vlan_id_range)
@ -395,13 +395,13 @@ class TestLinuxBridgeVlanFiltering:
libnmstate.validator.validate(default_data)
@pytest.mark.parametrize(
'is_native_vlan', argvalues=[True, False], ids=['native', 'not-native']
"is_native_vlan", argvalues=[True, False], ids=["native", "not-native"]
)
def test_trunk_port_native_vlan(
self, default_data, bridge_state, is_native_vlan
):
vlan_access_port_state = self._generate_vlan_filtering_config(
'trunk',
"trunk",
access_tag=101 if is_native_vlan else None,
native_vlan=is_native_vlan,
)
@ -415,7 +415,7 @@ class TestLinuxBridgeVlanFiltering:
trunk_tags = self._generate_vlan_id_config(101, 102, 103)
trunk_tags.append(self._generate_vlan_id_range_config(500, 1000))
vlan_trunk_tags_port_state = self._generate_vlan_filtering_config(
'trunk', trunk_tags=trunk_tags
"trunk", trunk_tags=trunk_tags
)
the_port = bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE][0]
the_port.update(vlan_trunk_tags_port_state)
@ -425,7 +425,7 @@ class TestLinuxBridgeVlanFiltering:
def test_invalid_trunk_port_vlan_range(self, default_data, bridge_state):
invalid_port_vlan_configuration = self._generate_vlan_filtering_config(
'trunk',
"trunk",
trunk_tags=[self._generate_vlan_id_range_config(100, 5000)],
)
the_port = bridge_state[LB.CONFIG_SUBTREE][LB.PORT_SUBTREE][0]
@ -466,7 +466,7 @@ class TestLinuxBridgeVlanFiltering:
class TestOvsBridgeVlan:
@pytest.mark.parametrize('vlan_mode', argvalues=['trunk', 'access'])
@pytest.mark.parametrize("vlan_mode", argvalues=["trunk", "access"])
def test_vlan_port_modes(self, default_data, ovs_bridge_state, vlan_mode):
valid_vlan_mode = self._generate_vlan_config(vlan_mode)
bridge_state_config = ovs_bridge_state[OVSBridge.CONFIG_SUBTREE]
@ -477,7 +477,7 @@ class TestOvsBridgeVlan:
libnmstate.validator.validate(default_data)
def test_invalid_vlan_port_mode(self, default_data, ovs_bridge_state):
invalid_vlan_mode = self._generate_vlan_config('fake-mode')
invalid_vlan_mode = self._generate_vlan_config("fake-mode")
bridge_state_config = ovs_bridge_state[OVSBridge.CONFIG_SUBTREE]
the_port = bridge_state_config[OVSBridge.PORT_SUBTREE][0]
the_port.update(invalid_vlan_mode)
@ -488,7 +488,7 @@ class TestOvsBridgeVlan:
def test_access_port_accepted(self, default_data, ovs_bridge_state):
vlan_access_port_state = self._generate_vlan_config(
'access', access_tag=101
"access", access_tag=101
)
bridge_state_config = ovs_bridge_state[OVSBridge.CONFIG_SUBTREE]
the_port = bridge_state_config[OVSBridge.PORT_SUBTREE][0]
@ -499,7 +499,7 @@ class TestOvsBridgeVlan:
def test_wrong_access_port_tag_mode(self, default_data, ovs_bridge_state):
invalid_access_port_tag_mode = self._generate_vlan_config(
'access', access_tag='holy-guacamole!'
"access", access_tag="holy-guacamole!"
)
bridge_state_config = ovs_bridge_state[OVSBridge.CONFIG_SUBTREE]
the_port = bridge_state_config[OVSBridge.PORT_SUBTREE][0]
@ -511,7 +511,7 @@ class TestOvsBridgeVlan:
def test_wrong_access_tag_range(self, default_data, ovs_bridge_state):
invalid_vlan_id_range = self._generate_vlan_config(
'access', access_tag=48000
"access", access_tag=48000
)
bridge_state_config = ovs_bridge_state[OVSBridge.CONFIG_SUBTREE]
the_port = bridge_state_config[OVSBridge.PORT_SUBTREE][0]
@ -522,13 +522,13 @@ class TestOvsBridgeVlan:
libnmstate.validator.validate(default_data)
@pytest.mark.parametrize(
'is_native_vlan', argvalues=[True, False], ids=['native', 'not-native']
"is_native_vlan", argvalues=[True, False], ids=["native", "not-native"]
)
def test_trunk_port_native_vlan(
self, default_data, ovs_bridge_state, is_native_vlan
):
vlan_access_port_state = self._generate_vlan_config(
'trunk',
"trunk",
access_tag=101 if is_native_vlan else None,
native_vlan=is_native_vlan,
)
@ -543,7 +543,7 @@ class TestOvsBridgeVlan:
trunk_tags = self._generate_vlan_id_config(101, 102, 103)
trunk_tags.append(self._generate_vlan_id_range_config(500, 1000))
vlan_trunk_tags_port_state = self._generate_vlan_config(
'trunk', trunk_tags=trunk_tags
"trunk", trunk_tags=trunk_tags
)
bridge_state_config = ovs_bridge_state[OVSBridge.CONFIG_SUBTREE]
the_port = bridge_state_config[OVSBridge.PORT_SUBTREE][0]
@ -556,7 +556,7 @@ class TestOvsBridgeVlan:
self, default_data, ovs_bridge_state
):
invalid_port_vlan_configuration = self._generate_vlan_config(
'trunk',
"trunk",
trunk_tags=[self._generate_vlan_id_range_config(100, 5000)],
)
bridge_state_config = ovs_bridge_state[OVSBridge.CONFIG_SUBTREE]
@ -603,7 +603,7 @@ class TestOvsBridgeVlan:
class TestRouteRules:
def test_non_interger_route_table(self, default_data):
route_rules = default_data[RouteRule.KEY][RouteRule.CONFIG]
route_rules[0][RouteRule.ROUTE_TABLE] = 'main'
route_rules[0][RouteRule.ROUTE_TABLE] = "main"
with pytest.raises(js.ValidationError):
libnmstate.validator.validate(default_data)
@ -612,18 +612,18 @@ class TestRouteRules:
class TestOVSBridgeLinkAggregation:
def test_valid_link_aggregation_port(self, default_data):
link_aggregation_port = {
OVSBridge.Port.NAME: 'bond',
OVSBridge.Port.NAME: "bond",
OVSBridge.Port.LINK_AGGREGATION_SUBTREE: {
OVSBridge.Port.LinkAggregation.MODE: 'bond-mode',
OVSBridge.Port.LinkAggregation.MODE: "bond-mode",
OVSBridge.Port.LinkAggregation.SLAVES_SUBTREE: [
{OVSBridge.Port.LinkAggregation.Slave.NAME: 'iface1'},
{OVSBridge.Port.LinkAggregation.Slave.NAME: 'iface2'},
{OVSBridge.Port.LinkAggregation.Slave.NAME: "iface1"},
{OVSBridge.Port.LinkAggregation.Slave.NAME: "iface2"},
],
},
}
default_data[Interface.KEY].append(
{
Interface.NAME: 'bridge',
Interface.NAME: "bridge",
Interface.TYPE: InterfaceType.OVS_BRIDGE,
OVSBridge.CONFIG_SUBTREE: {
OVSBridge.PORT_SUBTREE: [link_aggregation_port]

View File

@ -33,7 +33,7 @@ from libnmstate.schema import RouteRule
parametrize_route_property = pytest.mark.parametrize(
'route_property',
"route_property",
[
Route.TABLE_ID,
Route.DESTINATION,
@ -71,27 +71,27 @@ class TestAssertIfaceState:
def test_desired_is_not_equal_to_current(self):
desired_state = self._base_state
current_state = self._base_state
current_state.interfaces['foo-name']['state'] = 'down'
current_state.interfaces["foo-name"]["state"] = "down"
with pytest.raises(NmstateVerificationError):
desired_state.verify_interfaces(current_state)
def test_desired_has_extra_info_when_ip_disabled(self):
desired_state = self._base_state
desired_state.interfaces['foo-name'][Interface.IPV4] = {
desired_state.interfaces["foo-name"][Interface.IPV4] = {
InterfaceIPv4.ENABLED: False,
InterfaceIPv4.DHCP: False,
}
desired_state.interfaces['foo-name'][Interface.IPV6] = {
desired_state.interfaces["foo-name"][Interface.IPV6] = {
InterfaceIPv6.ENABLED: False,
InterfaceIPv6.DHCP: False,
InterfaceIPv6.AUTOCONF: False,
}
current_state = self._base_state
current_state.interfaces['foo-name'][Interface.IPV4] = {
current_state.interfaces["foo-name"][Interface.IPV4] = {
InterfaceIPv4.ENABLED: False
}
current_state.interfaces['foo-name'][Interface.IPV6] = {
current_state.interfaces["foo-name"][Interface.IPV6] = {
InterfaceIPv6.ENABLED: False
}
@ -100,53 +100,53 @@ class TestAssertIfaceState:
def test_sort_multiple_ip(self):
desired_state = self._base_state
current_state = self._base_state
desired_state.interfaces['foo-name']['ipv4'] = {
desired_state.interfaces["foo-name"]["ipv4"] = {
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '192.168.122.10',
InterfaceIPv4.ADDRESS_IP: "192.168.122.10",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
},
{
InterfaceIPv4.ADDRESS_IP: '192.168.121.10',
InterfaceIPv4.ADDRESS_IP: "192.168.121.10",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
},
],
InterfaceIPv4.ENABLED: True,
}
current_state.interfaces['foo-name']['ipv4'] = {
current_state.interfaces["foo-name"]["ipv4"] = {
InterfaceIPv4.ADDRESS: [
{
InterfaceIPv4.ADDRESS_IP: '192.168.121.10',
InterfaceIPv4.ADDRESS_IP: "192.168.121.10",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
},
{
InterfaceIPv4.ADDRESS_IP: '192.168.122.10',
InterfaceIPv4.ADDRESS_IP: "192.168.122.10",
InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24,
},
],
InterfaceIPv4.ENABLED: True,
}
desired_state.interfaces['foo-name']['ipv6'] = {
desired_state.interfaces["foo-name"]["ipv6"] = {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: '2001::2',
InterfaceIPv6.ADDRESS_IP: "2001::2",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
},
{
InterfaceIPv6.ADDRESS_IP: '2001::1',
InterfaceIPv6.ADDRESS_IP: "2001::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
},
],
InterfaceIPv6.ENABLED: True,
}
current_state.interfaces['foo-name']['ipv6'] = {
current_state.interfaces["foo-name"]["ipv6"] = {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: '2001::1',
InterfaceIPv6.ADDRESS_IP: "2001::1",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
},
{
InterfaceIPv6.ADDRESS_IP: '2001::2',
InterfaceIPv6.ADDRESS_IP: "2001::2",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
},
],
@ -158,24 +158,24 @@ class TestAssertIfaceState:
def test_description_is_empty(self):
desired_state = self._base_state
current_state = self._base_state
desired_state.interfaces['foo-name'][Interface.DESCRIPTION] = ''
desired_state.interfaces["foo-name"][Interface.DESCRIPTION] = ""
desired_state.verify_interfaces(current_state)
def test_description_is_not_empty(self):
desired_state = self._base_state
current_state = self._base_state
desired_state.interfaces['foo-name'][Interface.DESCRIPTION] = 'bar'
current_state.interfaces['foo-name'][Interface.DESCRIPTION] = 'bar'
desired_state.interfaces["foo-name"][Interface.DESCRIPTION] = "bar"
current_state.interfaces["foo-name"][Interface.DESCRIPTION] = "bar"
desired_state.verify_interfaces(current_state)
def test_accept_expanded_ipv6_notation(self):
desired_state = self._base_state
current_state = self._base_state
expanded_ipv6_addr = '2001:0db8:85a3:0000:0000:8a2e:0370:7331'
expanded_ipv6_addr = "2001:0db8:85a3:0000:0000:8a2e:0370:7331"
desired_state.interfaces['foo-name']['ipv6'] = {
desired_state.interfaces["foo-name"]["ipv6"] = {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: expanded_ipv6_addr,
@ -184,10 +184,10 @@ class TestAssertIfaceState:
],
InterfaceIPv6.ENABLED: True,
}
current_state.interfaces['foo-name']['ipv6'] = {
current_state.interfaces["foo-name"]["ipv6"] = {
InterfaceIPv6.ADDRESS: [
{
InterfaceIPv6.ADDRESS_IP: '2001:db8:85a3::8a2e:370:7331',
InterfaceIPv6.ADDRESS_IP: "2001:db8:85a3::8a2e:370:7331",
InterfaceIPv6.ADDRESS_PREFIX_LENGTH: 64,
}
],
@ -201,11 +201,11 @@ class TestAssertIfaceState:
{
Interface.KEY: [
{
'name': 'foo-name',
'type': 'foo-type',
'state': 'up',
'bridge': {
'port': [{'name': 'eth0', 'type': 'system'}]
"name": "foo-name",
"type": "foo-type",
"state": "up",
"bridge": {
"port": [{"name": "eth0", "type": "system"}]
},
}
]
@ -217,8 +217,8 @@ class TestAssertIfaceState:
return state.State(
{
Interface.KEY: [
{'name': 'eth0', 'state': 'up', 'type': 'unknown'},
{'name': 'eth1', 'state': 'up', 'type': 'unknown'},
{"name": "eth0", "state": "up", "type": "unknown"},
{"name": "eth1", "state": "up", "type": "unknown"},
]
}
)
@ -226,71 +226,71 @@ class TestAssertIfaceState:
class TestRouteEntry:
def test_hash_unique(self):
route = _create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103)
route = _create_route("198.51.100.0/24", "192.0.2.1", "eth1", 50, 103)
assert hash(route) == hash(route)
def test_obj_unique(self):
route0 = _create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103)
route0 = _create_route("198.51.100.0/24", "192.0.2.1", "eth1", 50, 103)
route1 = _create_route(
'2001:db8:a::/64', '2001:db8:1::a', 'eth2', 51, 104
"2001:db8:a::/64", "2001:db8:1::a", "eth2", 51, 104
)
route0_clone = _create_route(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
assert route0 == route0_clone
assert route0 != route1
def test_obj_unique_without_table_id(self):
route_with_default_table_id = _create_route(
'198.51.100.0/24',
'192.0.2.1',
'eth1',
"198.51.100.0/24",
"192.0.2.1",
"eth1",
Route.USE_DEFAULT_ROUTE_TABLE,
103,
)
route_without_table_id = _create_route(
'198.51.100.0/24', '192.0.2.1', 'eth1', None, 103
"198.51.100.0/24", "192.0.2.1", "eth1", None, 103
)
assert route_without_table_id == route_with_default_table_id
def test_obj_unique_without_metric(self):
route_with_default_metric = _create_route(
'198.51.100.0/24',
'192.0.2.1',
'eth1',
"198.51.100.0/24",
"192.0.2.1",
"eth1",
50,
Route.USE_DEFAULT_METRIC,
)
route_without_metric = _create_route(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, None
"198.51.100.0/24", "192.0.2.1", "eth1", 50, None
)
assert route_without_metric == route_with_default_metric
def test_obj_unique_without_next_hop(self):
route_with_default_next_hop = _create_route(
'198.51.100.0/24', '', 'eth1', 50, 103
"198.51.100.0/24", "", "eth1", 50, 103
)
route_without_next_hop = _create_route(
'198.51.100.0/24', None, 'eth1', 50, 103
"198.51.100.0/24", None, "eth1", 50, 103
)
assert route_without_next_hop == route_with_default_next_hop
def test_normal_route_object_as_dict(self):
route = _create_route_dict(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
route_obj = state.RouteEntry(route)
assert route_obj.to_dict() == route
def test_absent_route_object_as_dict(self):
route = _create_route_dict(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
route[Route.STATE] = Route.STATE_ABSENT
route_obj = state.RouteEntry(route)
@ -300,7 +300,7 @@ class TestRouteEntry:
@parametrize_route_property
def test_absent_route_with_missing_props_as_dict(self, route_property):
absent_route = _create_route_dict(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
absent_route[Route.STATE] = Route.STATE_ABSENT
del absent_route[route_property]
@ -308,16 +308,16 @@ class TestRouteEntry:
assert route_obj.to_dict() == absent_route
def test_absent_route_with_exact_match(self):
route0 = _create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103)
route0 = _create_route("198.51.100.0/24", "192.0.2.1", "eth1", 50, 103)
absent_r0 = _create_route_dict(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
absent_r0[Route.STATE] = Route.STATE_ABSENT
absent_route0 = state.RouteEntry(absent_r0)
route1 = _create_route(
'2001:db8:a::/64', '2001:db8:1::a', 'eth2', 51, 104
"2001:db8:a::/64", "2001:db8:1::a", "eth2", 51, 104
)
assert absent_route0.match(route0)
@ -328,14 +328,14 @@ class TestRouteEntry:
@parametrize_route_property
def test_absent_route_wildcard_match(self, route_property):
original_route0 = _create_route(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
original_route1 = _create_route(
'2001:db8:a::/64', '2001:db8:1::a', 'eth2', 51, 104
"2001:db8:a::/64", "2001:db8:1::a", "eth2", 51, 104
)
absent_route0_state = _create_route_dict(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
absent_route0_state[Route.STATE] = Route.STATE_ABSENT
del absent_route0_state[route_property]
@ -346,7 +346,7 @@ class TestRouteEntry:
def test_absent_route_is_ignored_for_matching_and_equality(self):
route = _create_route_dict(
'198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103
"198.51.100.0/24", "192.0.2.1", "eth1", 50, 103
)
route[Route.STATE] = Route.STATE_ABSENT
obj1 = state.RouteEntry(route)
@ -356,36 +356,36 @@ class TestRouteEntry:
def test_sort_routes(self):
routes = [
_create_route('198.51.100.1/24', '192.0.2.1', 'eth0', 50, 103),
_create_route('198.51.100.0/24', '192.0.2.1', 'eth0', 50, 103),
_create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 10, 103),
_create_route("198.51.100.1/24", "192.0.2.1", "eth0", 50, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth0", 50, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth1", 10, 103),
]
expected_routes = [
_create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 10, 103),
_create_route('198.51.100.0/24', '192.0.2.1', 'eth0', 50, 103),
_create_route('198.51.100.1/24', '192.0.2.1', 'eth0', 50, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth1", 10, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth0", 50, 103),
_create_route("198.51.100.1/24", "192.0.2.1", "eth0", 50, 103),
]
assert expected_routes == sorted(routes)
@parametrize_route_property
def test_sort_routes_with_absent_route(self, route_property):
absent_route = _create_route(
'198.51.100.0/24', '192.0.1.1', 'eth0', 9, 103
"198.51.100.0/24", "192.0.1.1", "eth0", 9, 103
).to_dict()
absent_route[Route.STATE] = Route.STATE_ABSENT
del absent_route[route_property]
absent_route = state.RouteEntry(absent_route)
routes = [
absent_route,
_create_route('198.51.100.1/24', '192.0.2.1', 'eth0', 50, 103),
_create_route('198.51.100.0/24', '192.0.2.1', 'eth0', 50, 103),
_create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 10, 103),
_create_route("198.51.100.1/24", "192.0.2.1", "eth0", 50, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth0", 50, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth1", 10, 103),
]
expected_routes = [
absent_route,
_create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 10, 103),
_create_route('198.51.100.0/24', '192.0.2.1', 'eth0', 50, 103),
_create_route('198.51.100.1/24', '192.0.2.1', 'eth0', 50, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth1", 10, 103),
_create_route("198.51.100.0/24", "192.0.2.1", "eth0", 50, 103),
_create_route("198.51.100.1/24", "192.0.2.1", "eth0", 50, 103),
]
assert expected_routes == sorted(routes)
@ -397,46 +397,46 @@ class TestRouteStateMerge:
s0.merge_routes(s1)
assert {'interfaces': [], 'routes': {'config': []}} == s0.state
assert {"interfaces": [], "routes": {"config": []}} == s0.state
assert {} == s0.config_iface_routes
def test_merge_identical_states(self):
route0_obj = self._create_route0()
route0 = route0_obj.to_dict()
s0 = state.State({'routes': {'config': [route0]}})
s1 = state.State({'routes': {'config': [route0]}})
s0 = state.State({"routes": {"config": [route0]}})
s1 = state.State({"routes": {"config": [route0]}})
s0.merge_routes(s1)
assert {'interfaces': [], 'routes': {'config': [route0]}} == s0.state
assert {'eth1': [route0_obj]} == s0.config_iface_routes
assert {"interfaces": [], "routes": {"config": [route0]}} == s0.state
assert {"eth1": [route0_obj]} == s0.config_iface_routes
def test_merge_unique_states(self):
route0_obj = self._create_route0()
route0 = route0_obj.to_dict()
route1_obj = self._create_route1()
route1 = route1_obj.to_dict()
s0 = state.State({'routes': {'config': [route0]}})
s1 = state.State({'routes': {'config': [route1]}})
s0 = state.State({"routes": {"config": [route0]}})
s1 = state.State({"routes": {"config": [route1]}})
s0.merge_routes(s1)
expected_state = {'interfaces': [], 'routes': {'config': [route0]}}
expected_state = {"interfaces": [], "routes": {"config": [route0]}}
assert expected_state == s0.state
expected_indexed_routes = {'eth1': [route0_obj]}
expected_indexed_routes = {"eth1": [route0_obj]}
assert expected_indexed_routes == s0.config_iface_routes
def test_merge_empty_with_non_empty_state(self):
route0_obj = self._create_route0()
route0 = route0_obj.to_dict()
empty_state = state.State({})
state_with_route0 = state.State({'routes': {'config': [route0]}})
state_with_route0 = state.State({"routes": {"config": [route0]}})
empty_state.merge_routes(state_with_route0)
assert {
'interfaces': [],
'routes': {'config': []},
"interfaces": [],
"routes": {"config": []},
} == empty_state.state
assert {} == empty_state.config_iface_routes
@ -598,15 +598,15 @@ class TestRouteStateMerge:
route0_obj = self._create_route0()
route0 = route0_obj.to_dict()
empty_state = state.State({})
state_with_route0 = state.State({'routes': {'config': [route0]}})
state_with_route0 = state.State({"routes": {"config": [route0]}})
state_with_route0.merge_routes(empty_state)
assert {
'interfaces': [],
'routes': {'config': [route0]},
"interfaces": [],
"routes": {"config": [route0]},
} == state_with_route0.state
assert {'eth1': [route0_obj]} == state_with_route0.config_iface_routes
assert {"eth1": [route0_obj]} == state_with_route0.config_iface_routes
def test_merge_absent_routes_with_no_matching(self):
absent_route_obj = self._create_route0()
@ -614,12 +614,12 @@ class TestRouteStateMerge:
absent_route = absent_route_obj.to_dict()
other_route_obj = self._create_route1()
other_route = other_route_obj.to_dict()
s0 = state.State({'routes': {'config': [absent_route]}})
s1 = state.State({'routes': {'config': [other_route]}})
s0 = state.State({"routes": {"config": [absent_route]}})
s1 = state.State({"routes": {"config": [other_route]}})
s0.merge_routes(s1)
expected_state = {'interfaces': [], 'routes': {'config': []}}
expected_state = {"interfaces": [], "routes": {"config": []}}
assert expected_state == s0.state
assert {} == s0.config_iface_routes
@ -629,20 +629,20 @@ class TestRouteStateMerge:
absent_route = absent_route_obj.to_dict()
other_route_obj = self._create_route0()
other_route = other_route_obj.to_dict()
s0 = state.State({'routes': {'config': [absent_route]}})
s1 = state.State({'routes': {'config': [other_route]}})
s0 = state.State({"routes": {"config": [absent_route]}})
s1 = state.State({"routes": {"config": [other_route]}})
s0.merge_routes(s1)
assert {'interfaces': [], 'routes': {'config': []}} == s0.state
assert {"interfaces": [], "routes": {"config": []}} == s0.state
assert {} == s0.config_iface_routes
def _create_route0(self):
return _create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103)
return _create_route("198.51.100.0/24", "192.0.2.1", "eth1", 50, 103)
def _create_route1(self):
return _create_route(
'2001:db8:a::/64', '2001:db8:1::a', 'eth2', 51, 104
"2001:db8:a::/64", "2001:db8:1::a", "eth2", 51, 104
)
@ -685,10 +685,10 @@ def test_state_iface_routes_with_distinct_ifaces():
def test_state_iface_routes_with_same_iface():
routes = _get_mixed_test_routes()
for route in routes:
route[Route.NEXT_HOP_INTERFACE] = 'eth1'
route[Route.NEXT_HOP_INTERFACE] = "eth1"
route_state = state.State({Route.KEY: {Route.CONFIG: routes}})
expected_indexed_route_state = {
'eth1': sorted([state.RouteEntry(r) for r in routes])
"eth1": sorted([state.RouteEntry(r) for r in routes])
}
assert expected_indexed_route_state == route_state.config_iface_routes
@ -698,7 +698,7 @@ def test_state_iface_routes_order():
# Changing all routes to eth1
routes = _get_mixed_test_routes()
for route in routes:
route[Route.NEXT_HOP_INTERFACE] = 'eth1'
route[Route.NEXT_HOP_INTERFACE] = "eth1"
route_state = state.State(
{Route.KEY: {Route.CONFIG: [routes[0], routes[1]]}}
@ -732,7 +732,7 @@ def test_state_verify_route_diff_route_count():
def test_state_verify_route_diff_route_prop():
routes = _get_mixed_test_routes()
route_state = state.State({Route.KEY: {Route.CONFIG: routes}})
routes[0][Route.NEXT_HOP_INTERFACE] = 'another_nic'
routes[0][Route.NEXT_HOP_INTERFACE] = "another_nic"
route_state_2 = state.State({Route.KEY: {Route.CONFIG: routes}})
with pytest.raises(NmstateVerificationError):
@ -746,8 +746,8 @@ def test_state_verify_route_empty():
def _get_mixed_test_routes():
r0 = _create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103)
r1 = _create_route('2001:db8:a::/64', '2001:db8:1::a', 'eth2', 51, 104)
r0 = _create_route("198.51.100.0/24", "192.0.2.1", "eth1", 50, 103)
r1 = _create_route("2001:db8:a::/64", "2001:db8:1::a", "eth2", 51, 104)
return [r0.to_dict(), r1.to_dict()]
@ -767,8 +767,8 @@ def _gen_iface_states_for_routes(routes):
def _route_sort_key(route):
return (
route.get(Route.TABLE_ID, Route.USE_DEFAULT_ROUTE_TABLE),
route.get(Route.NEXT_HOP_INTERFACE, ''),
route.get(Route.DESTINATION, ''),
route.get(Route.NEXT_HOP_INTERFACE, ""),
route.get(Route.DESTINATION, ""),
)
@ -815,8 +815,8 @@ class TestAssertDnsState:
def _get_test_dns_config(self):
return {
DNS.CONFIG: {
DNS.SERVER: ['192.168.122.1', '2001:db8:a::1'],
DNS.SEARCH: ['example.com', 'example.org'],
DNS.SERVER: ["192.168.122.1", "2001:db8:a::1"],
DNS.SEARCH: ["example.com", "example.org"],
}
}
@ -835,111 +835,111 @@ class TestStateMatch:
assert not state.state_match({}, [])
def test_match_list_vs_string(self):
assert not state.state_match(['a', 'b', 'c'], 'abc')
assert not state.state_match(["a", "b", "c"], "abc")
def test_match_dict_identical(self):
assert state.state_match({'a': 1, 'b': 2}, {'a': 1, 'b': 2})
assert state.state_match({"a": 1, "b": 2}, {"a": 1, "b": 2})
def test_match_dict_current_has_more_data(self):
assert state.state_match({'a': 1}, {'a': 1, 'b': 2})
assert state.state_match({"a": 1}, {"a": 1, "b": 2})
def test_match_dict_desire_has_more_data(self):
assert not state.state_match({'a': 1, 'b': 2}, {'a': 1})
assert not state.state_match({"a": 1, "b": 2}, {"a": 1})
def test_match_dict_different_value_type(self):
assert not state.state_match({'a': 1, 'b': []}, {'a': 1, 'b': 2})
assert not state.state_match({"a": 1, "b": []}, {"a": 1, "b": 2})
def test_match_list_identical(self):
assert state.state_match(['a', 'b', 1], ['a', 'b', 1])
assert state.state_match(["a", "b", 1], ["a", "b", 1])
def test_match_list_different_order(self):
assert not state.state_match(['a', 'b', 1], ['a', 1, 'b'])
assert not state.state_match(["a", "b", 1], ["a", 1, "b"])
def test_match_list_current_contains_more(self):
assert not state.state_match(['a', 'b', 1], ['a', 'b', 'c', 1])
assert not state.state_match(["a", "b", 1], ["a", "b", "c", 1])
def test_match_indentical_set(self):
assert state.state_match(set(['a', 'b', 1]), set(['a', 'b', 1]))
assert state.state_match(set(['a', 1, 'b']), set(['a', 'b', 1]))
assert state.state_match(set(['a', 1, 1, 'b']), set(['a', 'b', 1]))
assert state.state_match(set(["a", "b", 1]), set(["a", "b", 1]))
assert state.state_match(set(["a", 1, "b"]), set(["a", "b", 1]))
assert state.state_match(set(["a", 1, 1, "b"]), set(["a", "b", 1]))
def test_match_parital_set(self):
assert not state.state_match(
set(['a', 'b', 1]), set(['a', 'b', 'c', 1])
set(["a", "b", 1]), set(["a", "b", "c", 1])
)
def test_match_nested_list_in_dict(self):
assert state.state_match({'a': 1, 'b': [1, 2]}, {'a': 1, 'b': [1, 2]})
assert state.state_match({"a": 1, "b": [1, 2]}, {"a": 1, "b": [1, 2]})
def test_match_nested_dict_in_list(self):
assert state.state_match(
[{'a': 1, 'b': [1, 2]}, {'a': 2, 'b': [3, 4]}],
[{'a': 1, 'b': [1, 2]}, {'a': 2, 'b': [3, 4]}],
[{"a": 1, "b": [1, 2]}, {"a": 2, "b": [3, 4]}],
[{"a": 1, "b": [1, 2]}, {"a": 2, "b": [3, 4]}],
)
assert state.state_match(
[{'a': 1}, {'a': 2, 'b': [3, 4]}],
[{'a': 1, 'b': [1, 2]}, {'a': 2, 'b': [3, 4]}],
[{"a": 1}, {"a": 2, "b": [3, 4]}],
[{"a": 1, "b": [1, 2]}, {"a": 2, "b": [3, 4]}],
)
assert not state.state_match(
[{'a': 2, 'b': [3, 4]}, {'a': 1, 'b': [1, 2]}],
[{'a': 1, 'b': [1, 2]}, {'a': 2, 'b': [3, 4]}],
[{"a": 2, "b": [3, 4]}, {"a": 1, "b": [1, 2]}],
[{"a": 1, "b": [1, 2]}, {"a": 2, "b": [3, 4]}],
)
class TestRouteRuleEntry:
def test_hash_unique(self):
rule = _create_route_rule('198.51.100.0/24', '192.0.2.1', 50, 103)
rule = _create_route_rule("198.51.100.0/24", "192.0.2.1", 50, 103)
assert hash(rule) == hash(rule)
def test_obj_unique(self):
rule0 = _create_route_rule('198.51.100.0/24', '192.0.2.1', 50, 103)
rule1 = _create_route_rule('2001:db8:a::/64', '2001:db8:1::a', 51, 104)
rule0 = _create_route_rule("198.51.100.0/24", "192.0.2.1", 50, 103)
rule1 = _create_route_rule("2001:db8:a::/64", "2001:db8:1::a", 51, 104)
rule0_clone = _create_route_rule(
'198.51.100.0/24', '192.0.2.1', 50, 103
"198.51.100.0/24", "192.0.2.1", 50, 103
)
assert rule0 == rule0_clone
assert rule0 != rule1
def test_obj_unique_without_table(self):
rule_with_default_table_id = _create_route_rule(
'198.51.100.0/24',
'192.0.2.1',
"198.51.100.0/24",
"192.0.2.1",
103,
RouteRule.USE_DEFAULT_ROUTE_TABLE,
)
rule_without_table_id = _create_route_rule(
'198.51.100.0/24', '192.0.2.1', 103, None
"198.51.100.0/24", "192.0.2.1", 103, None
)
assert rule_without_table_id == rule_with_default_table_id
def test_obj_unique_without_priority(self):
rule_with_default_priority = _create_route_rule(
'198.51.100.0/24', '192.0.2.1', RouteRule.USE_DEFAULT_PRIORITY, 50
"198.51.100.0/24", "192.0.2.1", RouteRule.USE_DEFAULT_PRIORITY, 50
)
rule_without_priority = _create_route_rule(
'198.51.100.0/24', '192.0.2.1', None, 50
"198.51.100.0/24", "192.0.2.1", None, 50
)
assert rule_without_priority == rule_with_default_priority
def test_normal_object_as_dict(self):
rule = _create_route_rule_dict('198.51.100.0/24', '192.0.2.1', 50, 103)
rule = _create_route_rule_dict("198.51.100.0/24", "192.0.2.1", 50, 103)
rule_obj = state.RouteRuleEntry(rule)
assert rule_obj.to_dict() == rule
def test_sort_routes(self):
rules = [
_create_route_rule('198.51.100.1/24', '192.0.2.1', 50, 103),
_create_route_rule('198.51.100.0/24', '192.0.2.1', 50, 103),
_create_route_rule('198.51.100.0/24', '192.0.2.1', 10, 103),
_create_route_rule("198.51.100.1/24", "192.0.2.1", 50, 103),
_create_route_rule("198.51.100.0/24", "192.0.2.1", 50, 103),
_create_route_rule("198.51.100.0/24", "192.0.2.1", 10, 103),
]
expected_rules = [
_create_route_rule('198.51.100.0/24', '192.0.2.1', 10, 103),
_create_route_rule('198.51.100.0/24', '192.0.2.1', 50, 103),
_create_route_rule('198.51.100.1/24', '192.0.2.1', 50, 103),
_create_route_rule("198.51.100.0/24", "192.0.2.1", 10, 103),
_create_route_rule("198.51.100.0/24", "192.0.2.1", 50, 103),
_create_route_rule("198.51.100.1/24", "192.0.2.1", 50, 103),
]
assert expected_rules == sorted(rules)
@ -949,13 +949,13 @@ class TestRouteRuleEntry:
RouteRule.KEY: {
RouteRule.CONFIG: [
_create_route_rule_dict(
'198.51.100.1/24', '192.0.2.1', 50, 103
"198.51.100.1/24", "192.0.2.1", 50, 103
),
_create_route_rule_dict(
'198.51.100.0/24', '192.0.2.1', 50, 103
"198.51.100.0/24", "192.0.2.1", 50, 103
),
_create_route_rule_dict(
'198.51.100.0/24', '192.0.2.1', 10, 104
"198.51.100.0/24", "192.0.2.1", 10, 104
),
]
}
@ -967,13 +967,13 @@ class TestRouteRuleEntry:
RouteRule.KEY: {
RouteRule.CONFIG: [
_create_route_rule_dict(
'198.51.100.0/24', '192.0.2.1', 10, 104
"198.51.100.0/24", "192.0.2.1", 10, 104
),
_create_route_rule_dict(
'198.51.100.1/24', '192.0.2.1', 50, 103
"198.51.100.1/24", "192.0.2.1", 50, 103
),
_create_route_rule_dict(
'198.51.100.0/24', '192.0.2.1', 50, 103
"198.51.100.0/24", "192.0.2.1", 50, 103
),
]
}
@ -1001,7 +1001,7 @@ def test_remove_unknown_interfaces():
desired_state = state.State(
{
Interface.KEY: [
{Interface.NAME: 'foo', Interface.TYPE: InterfaceType.UNKNOWN}
{Interface.NAME: "foo", Interface.TYPE: InterfaceType.UNKNOWN}
]
}
)

View File

@ -37,8 +37,8 @@ class TestLinkAggregationState:
desired_state = state.State(
{
schema.Interface.KEY: [
{'name': 'bond0', 'link-aggregation': {'slaves': []}},
{'name': 'bond1', 'link-aggregation': {'slaves': []}},
{"name": "bond0", "link-aggregation": {"slaves": []}},
{"name": "bond1", "link-aggregation": {"slaves": []}},
]
}
)
@ -51,15 +51,15 @@ class TestLinkAggregationState:
desired_state = state.State(
{
schema.Interface.KEY: [
{'name': 'slave0'},
{'name': 'slave1'},
{"name": "slave0"},
{"name": "slave1"},
{
'name': 'bond0',
'link-aggregation': {'slaves': ['slave0']},
"name": "bond0",
"link-aggregation": {"slaves": ["slave0"]},
},
{
'name': 'bond1',
'link-aggregation': {'slaves': ['slave1']},
"name": "bond1",
"link-aggregation": {"slaves": ["slave1"]},
},
]
}
@ -72,17 +72,17 @@ class TestLinkAggregationState:
desired_state = state.State(
{
schema.Interface.KEY: [
{'name': 'slave0'},
{'name': 'slave1'},
{'name': 'slave00'},
{'name': 'slave11'},
{"name": "slave0"},
{"name": "slave1"},
{"name": "slave00"},
{"name": "slave11"},
{
'name': 'bond0',
'link-aggregation': {'slaves': ['slave0', 'slave00']},
"name": "bond0",
"link-aggregation": {"slaves": ["slave0", "slave00"]},
},
{
'name': 'bond1',
'link-aggregation': {'slaves': ['slave1', 'slave11']},
"name": "bond1",
"link-aggregation": {"slaves": ["slave1", "slave11"]},
},
]
}
@ -95,16 +95,16 @@ class TestLinkAggregationState:
desired_state = state.State(
{
schema.Interface.KEY: [
{'name': 'slave0'},
{'name': 'slave1'},
{'name': 'slave00'},
{"name": "slave0"},
{"name": "slave1"},
{"name": "slave00"},
{
'name': 'bond0',
'link-aggregation': {'slaves': ['slave0', 'slave00']},
"name": "bond0",
"link-aggregation": {"slaves": ["slave0", "slave00"]},
},
{
'name': 'bond1',
'link-aggregation': {'slaves': ['slave1', 'slave00']},
"name": "bond1",
"link-aggregation": {"slaves": ["slave1", "slave00"]},
},
]
}
@ -118,15 +118,15 @@ class TestLinkAggregationState:
desired_state = state.State(
{
schema.Interface.KEY: [
{'name': 'slave0'},
{'name': 'slave1'},
{"name": "slave0"},
{"name": "slave1"},
{
'name': 'bond0',
'link-aggregation': {'slaves': ['slave0', 'slave00']},
"name": "bond0",
"link-aggregation": {"slaves": ["slave0", "slave00"]},
},
{
'name': 'bond1',
'link-aggregation': {'slaves': ['slave1', 'slave11']},
"name": "bond1",
"link-aggregation": {"slaves": ["slave1", "slave11"]},
},
]
}
@ -139,7 +139,7 @@ class TestLinkAggregationState:
@pytest.mark.xfail(
raises=NmstateNotImplementedError,
reason='https://nmstate.atlassian.net/browse/NMSTATE-220',
reason="https://nmstate.atlassian.net/browse/NMSTATE-220",
strict=True,
)
def test_dns_three_nameservers():
@ -147,7 +147,7 @@ def test_dns_three_nameservers():
{
DNS.KEY: {
DNS.CONFIG: {
DNS.SERVER: ['8.8.8.8', '2001:4860:4860::8888', '8.8.4.4']
DNS.SERVER: ["8.8.8.8", "2001:4860:4860::8888", "8.8.4.4"]
}
}
}
@ -163,7 +163,7 @@ class TestRouteValidation:
validator.validate_routes(state.State({}), state.State({}))
def test_valid_route_based_on_desired_state(self):
iface0 = _create_interface_state('eth1', ipv4=True)
iface0 = _create_interface_state("eth1", ipv4=True)
route0 = self._create_route0()
desired_state = state.State(
{
@ -175,7 +175,7 @@ class TestRouteValidation:
validator.validate_routes(desired_state, state.State({}))
def test_valid_route_based_on_current_state(self):
iface0 = _create_interface_state('eth1', ipv4=True)
iface0 = _create_interface_state("eth1", ipv4=True)
route0 = self._create_route0()
desired_state = state.State(
{
@ -206,7 +206,7 @@ class TestRouteValidation:
def test_invalid_route_due_to_non_up_iface(self):
iface0 = _create_interface_state(
'eth1', state=schema.InterfaceState.DOWN, ipv4=True
"eth1", state=schema.InterfaceState.DOWN, ipv4=True
)
route0 = self._create_route0()
desired_state = state.State(
@ -219,7 +219,7 @@ class TestRouteValidation:
validator.validate_routes(desired_state, state.State({}))
def test_invalid_route_due_to_missing_ipv4(self):
iface0 = _create_interface_state('eth1', ipv4=False)
iface0 = _create_interface_state("eth1", ipv4=False)
route0 = self._create_route0()
desired_state = state.State(
{
@ -231,7 +231,7 @@ class TestRouteValidation:
validator.validate_routes(desired_state, state.State({}))
def test_invalid_route_due_to_missing_ipv6(self):
iface1 = _create_interface_state('eth2', ipv6=False)
iface1 = _create_interface_state("eth2", ipv6=False)
route1 = self._create_route1()
desired_state = state.State(
{
@ -243,7 +243,7 @@ class TestRouteValidation:
validator.validate_routes(desired_state, state.State({}))
def test_valid_route_based_on_desired_state_but_not_current(self):
iface0 = _create_interface_state('eth1', ipv4=True)
iface0 = _create_interface_state("eth1", ipv4=True)
route0 = self._create_route0()
desired_state = state.State(
{
@ -252,7 +252,7 @@ class TestRouteValidation:
}
)
iface0_down = _create_interface_state(
'eth1', state=schema.InterfaceState.DOWN
"eth1", state=schema.InterfaceState.DOWN
)
current_state = state.State(
{
@ -264,7 +264,7 @@ class TestRouteValidation:
validator.validate_routes(desired_state, current_state)
def test_invalid_route_based_on_desired_state_but_not_current(self):
iface0_ipv4_disabled = _create_interface_state('eth1', ipv4=False)
iface0_ipv4_disabled = _create_interface_state("eth1", ipv4=False)
route0 = self._create_route0()
desired_state = state.State(
{
@ -272,7 +272,7 @@ class TestRouteValidation:
schema.Route.KEY: {schema.Route.CONFIG: [route0]},
}
)
iface0_ipv4_enabled = _create_interface_state('eth1', ipv4=True)
iface0_ipv4_enabled = _create_interface_state("eth1", ipv4=True)
current_state = state.State(
{
schema.Interface.KEY: [iface0_ipv4_enabled],
@ -284,18 +284,18 @@ class TestRouteValidation:
validator.validate_routes(desired_state, current_state)
def _create_route0(self):
return _create_route('198.51.100.0/24', '192.0.2.1', 'eth1', 50, 103)
return _create_route("198.51.100.0/24", "192.0.2.1", "eth1", 50, 103)
def _create_route1(self):
return _create_route(
'2001:db8:a::/64', '2001:db8:1::a', 'eth2', 51, 104
"2001:db8:a::/64", "2001:db8:1::a", "eth2", 51, 104
)
class TestVxlanValidation:
parametrize_vxlan_req_fields = pytest.mark.parametrize(
'required_field', [VXLAN.ID, VXLAN.REMOTE, VXLAN.BASE_IFACE]
"required_field", [VXLAN.ID, VXLAN.REMOTE, VXLAN.BASE_IFACE]
)
@parametrize_vxlan_req_fields
@ -303,12 +303,12 @@ class TestVxlanValidation:
desired_state = {
schema.Interface.KEY: [
{
schema.Interface.NAME: 'eth0.101',
schema.Interface.NAME: "eth0.101",
schema.Interface.TYPE: VXLAN.TYPE,
VXLAN.CONFIG_SUBTREE: {
VXLAN.ID: 99,
VXLAN.REMOTE: '192.168.3.3',
VXLAN.BASE_IFACE: 'eth0',
VXLAN.REMOTE: "192.168.3.3",
VXLAN.BASE_IFACE: "eth0",
},
}
]
@ -327,11 +327,11 @@ class TestVxlanValidation:
desired_state = {
schema.Interface.KEY: [
{
schema.Interface.NAME: 'eth0.101',
schema.Interface.NAME: "eth0.101",
schema.Interface.TYPE: VXLAN.TYPE,
VXLAN.CONFIG_SUBTREE: {
VXLAN.ID: 99,
VXLAN.REMOTE: '192.168.3.3',
VXLAN.REMOTE: "192.168.3.3",
VXLAN.BASE_IFACE: "eth0",
},
}
@ -356,12 +356,12 @@ class TestVlanFilteringValidation:
desired_state = {
schema.Interface.KEY: [
{
schema.Interface.NAME: 'br0',
schema.Interface.NAME: "br0",
schema.Interface.TYPE: LB.TYPE,
schema.Interface.STATE: schema.InterfaceState.UP,
LB.PORT_SUBTREE: [
{
LB.Port.NAME: 'eth1',
LB.Port.NAME: "eth1",
LB.Port.VLAN_SUBTREE: invalid_vlan_config,
}
],
@ -369,7 +369,7 @@ class TestVlanFilteringValidation:
]
}
with pytest.raises(
NmstateValueError, match='Access port cannot have trunk tags'
NmstateValueError, match="Access port cannot have trunk tags"
):
libnmstate.validator.validate_bridge(desired_state)
@ -381,12 +381,12 @@ class TestVlanFilteringValidation:
desired_state = {
schema.Interface.KEY: [
{
schema.Interface.NAME: 'br0',
schema.Interface.NAME: "br0",
schema.Interface.TYPE: LB.TYPE,
schema.Interface.STATE: schema.InterfaceState.UP,
LB.PORT_SUBTREE: [
{
LB.Port.NAME: 'eth1',
LB.Port.NAME: "eth1",
LB.Port.VLAN_SUBTREE: invalid_vlan_config,
}
],
@ -395,7 +395,7 @@ class TestVlanFilteringValidation:
}
with pytest.raises(
NmstateValueError,
match='A trunk port needs to specify trunk tags',
match="A trunk port needs to specify trunk tags",
):
libnmstate.validator.validate_bridge(desired_state)
@ -415,12 +415,12 @@ class TestVlanFilteringValidation:
desired_state = {
schema.Interface.KEY: [
{
schema.Interface.NAME: 'br0',
schema.Interface.NAME: "br0",
schema.Interface.TYPE: LB.TYPE,
schema.Interface.STATE: schema.InterfaceState.UP,
LB.PORT_SUBTREE: [
{
LB.Port.NAME: 'eth1',
LB.Port.NAME: "eth1",
LB.Port.VLAN_SUBTREE: invalid_vlan_config,
}
],
@ -430,26 +430,26 @@ class TestVlanFilteringValidation:
with pytest.raises(NmstateValueError) as err:
libnmstate.validator.validate_bridge(desired_state)
assert (
'Trunk port cannot be configured by both id and range'
"Trunk port cannot be configured by both id and range"
in err.value.args[0]
)
@pytest.mark.parametrize(
'range_key',
"range_key",
[LB.Port.Vlan.TrunkTags.MIN_RANGE, LB.Port.Vlan.TrunkTags.MAX_RANGE],
ids=['only_min', 'only_max'],
ids=["only_min", "only_max"],
)
def test_vlan_ranges_must_have_min_and_max(self, range_key):
vlan_tag = 101
desired_state = {
schema.Interface.KEY: [
{
schema.Interface.NAME: 'br0',
schema.Interface.NAME: "br0",
schema.Interface.TYPE: LB.TYPE,
schema.Interface.STATE: schema.InterfaceState.UP,
LB.PORT_SUBTREE: [
{
LB.Port.NAME: 'eth1',
LB.Port.NAME: "eth1",
LB.Port.VLAN_SUBTREE: {
LB.Port.Vlan.MODE: LB.Port.Vlan.Mode.TRUNK,
LB.Port.Vlan.TRUNK_TAGS: [
@ -467,7 +467,7 @@ class TestVlanFilteringValidation:
}
with pytest.raises(NmstateValueError) as err:
libnmstate.validator.validate_bridge(desired_state)
assert 'Trunk port range requires min / max keys' in err.value.args[0]
assert "Trunk port range requires min / max keys" in err.value.args[0]
def _create_interface_state(