nmstate: Centralize 'interfaces' constant
Signed-off-by: Edward Haas <edwardh@redhat.com>
This commit is contained in:
parent
234fb15967
commit
2b6b0526da
@ -27,6 +27,7 @@ from libnmstate import nm
|
||||
from libnmstate import validator
|
||||
from libnmstate.nm import nmclient
|
||||
from libnmstate.prettystate import format_desired_current_state_diff
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
class ApplyError(Exception):
|
||||
@ -41,7 +42,7 @@ def apply(desired_state, verify_change=True):
|
||||
validator.verify(desired_state)
|
||||
validator.verify_capabilities(desired_state, netinfo.capabilities())
|
||||
|
||||
_apply_ifaces_state(desired_state['interfaces'], verify_change)
|
||||
_apply_ifaces_state(desired_state[Constants.INTERFACES], verify_change)
|
||||
|
||||
|
||||
def _apply_ifaces_state(interfaces_desired_state, verify_change):
|
||||
|
@ -18,6 +18,7 @@ from __future__ import absolute_import
|
||||
|
||||
from libnmstate import nm
|
||||
from libnmstate import validator
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
def show(include_status_data=False):
|
||||
@ -30,7 +31,7 @@ def show(include_status_data=False):
|
||||
When include_status_data is set, both are reported, otherwise only the
|
||||
configuration data is reported.
|
||||
"""
|
||||
report = {'interfaces': interfaces()}
|
||||
report = {Constants.INTERFACES: interfaces()}
|
||||
if include_status_data:
|
||||
report['capabilities'] = capabilities()
|
||||
|
||||
|
@ -24,6 +24,8 @@ from operator import itemgetter
|
||||
|
||||
import yaml
|
||||
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
def format_desired_current_state_diff(desired_state, current_state):
|
||||
pretty_desired_state = PrettyState(desired_state).yaml
|
||||
@ -83,12 +85,12 @@ def represent_ordereddict(dumper, data):
|
||||
|
||||
|
||||
def order_state(state):
|
||||
iface_states = state.pop('interfaces', None)
|
||||
iface_states = state.pop(Constants.INTERFACES, None)
|
||||
|
||||
state = order_iface_state(state)
|
||||
|
||||
if iface_states is not None:
|
||||
state['interfaces'] = [
|
||||
state[Constants.INTERFACES] = [
|
||||
order_iface_state(iface_state) for iface_state in sorted(
|
||||
iface_states, key=itemgetter('name')
|
||||
)
|
||||
|
@ -26,3 +26,7 @@ def load(schema_name):
|
||||
|
||||
|
||||
ifaces_schema = load('operational-state')
|
||||
|
||||
|
||||
class Constants(object):
|
||||
INTERFACES = 'interfaces'
|
||||
|
@ -20,6 +20,7 @@ import jsonschema as js
|
||||
|
||||
from . import nm
|
||||
from . import schema
|
||||
from .schema import Constants
|
||||
|
||||
|
||||
class LinkAggregationSlavesMissingError(Exception):
|
||||
@ -39,7 +40,7 @@ def verify(data, validation_schema=schema.ifaces_schema):
|
||||
|
||||
|
||||
def verify_capabilities(state, capabilities):
|
||||
verify_interface_capabilities(state['interfaces'], capabilities)
|
||||
verify_interface_capabilities(state[Constants.INTERFACES], capabilities)
|
||||
|
||||
|
||||
def verify_interface_capabilities(ifaces_state, capabilities):
|
||||
|
@ -31,6 +31,7 @@ import yaml
|
||||
from libnmstate import netapplier
|
||||
from libnmstate import netinfo
|
||||
from libnmstate.prettystate import PrettyState
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
def main():
|
||||
@ -56,7 +57,7 @@ def setup_subcommand_edit(subparsers):
|
||||
parser_edit.add_argument('--json', help='Edit as JSON', default=True,
|
||||
action='store_false', dest='yaml')
|
||||
parser_edit.add_argument(
|
||||
'only', default='*', nargs='?', metavar='interfaces',
|
||||
'only', default='*', nargs='?', metavar=Constants.INTERFACES,
|
||||
help='Edit only specified interfaces (comma-separated)'
|
||||
)
|
||||
parser_edit.add_argument(
|
||||
@ -71,7 +72,7 @@ def setup_subcommand_show(subparsers):
|
||||
parser_show.add_argument('--yaml', help='Output as yaml', default=False,
|
||||
action='store_true')
|
||||
parser_show.add_argument(
|
||||
'only', default='*', nargs='?', metavar='interfaces',
|
||||
'only', default='*', nargs='?', metavar=Constants.INTERFACES,
|
||||
help='Show only specified interfaces (comma-separated)'
|
||||
)
|
||||
|
||||
@ -92,7 +93,7 @@ def setup_subcommand_set(subparsers):
|
||||
def edit(args):
|
||||
state = _filter_state(netinfo.show(), args.only)
|
||||
|
||||
if not state['interfaces']:
|
||||
if not state[Constants.INTERFACES]:
|
||||
sys.stderr.write('ERROR: No such interface\n')
|
||||
return os.EX_USAGE
|
||||
|
||||
@ -146,7 +147,7 @@ def apply(args):
|
||||
def _filter_state(state, whitelist):
|
||||
if whitelist != '*':
|
||||
patterns = [p for p in whitelist.split(',')]
|
||||
state['interfaces'] = _filter_interfaces(state, patterns)
|
||||
state[Constants.INTERFACES] = _filter_interfaces(state, patterns)
|
||||
return state
|
||||
|
||||
|
||||
@ -157,7 +158,7 @@ def _filter_interfaces(state, patterns):
|
||||
"""
|
||||
showinterfaces = []
|
||||
|
||||
for interface in state['interfaces']:
|
||||
for interface in state[Constants.INTERFACES]:
|
||||
for pattern in patterns:
|
||||
if fnmatch.fnmatch(interface['name'], pattern):
|
||||
showinterfaces.append(interface)
|
||||
@ -214,7 +215,7 @@ def _parse_state(txtstate, parse_yaml):
|
||||
except ValueError as e:
|
||||
error = 'Invalid JSON syntax: %s\n' % e
|
||||
|
||||
if not error and 'interfaces' not in state:
|
||||
if not error and Constants.INTERFACES not in state:
|
||||
error = 'Invalid state: should contain "interfaces" entry.\n'
|
||||
|
||||
return state, error
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import json
|
||||
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
from .testlib import cmd as libcmd
|
||||
|
||||
@ -66,7 +67,7 @@ def test_show_command_with_no_flags():
|
||||
assert LOOPBACK_JSON_CONFIG in out
|
||||
|
||||
state = json.loads(out)
|
||||
assert len(state['interfaces']) > 1
|
||||
assert len(state[Constants.INTERFACES]) > 1
|
||||
|
||||
|
||||
def test_show_command_with_yaml_format():
|
||||
@ -84,8 +85,8 @@ def test_show_command_only_lo():
|
||||
assert_rc(rc, RC_SUCCESS, ret)
|
||||
|
||||
state = json.loads(out)
|
||||
assert len(state['interfaces']) == 1
|
||||
assert state['interfaces'][0]['name'] == 'lo'
|
||||
assert len(state[Constants.INTERFACES]) == 1
|
||||
assert state[Constants.INTERFACES][0]['name'] == 'lo'
|
||||
|
||||
|
||||
def test_show_command_only_non_existing():
|
||||
@ -95,7 +96,7 @@ def test_show_command_only_non_existing():
|
||||
assert_rc(rc, RC_SUCCESS, ret)
|
||||
|
||||
state = json.loads(out)
|
||||
assert len(state['interfaces']) == 0
|
||||
assert len(state[Constants.INTERFACES]) == 0
|
||||
|
||||
|
||||
def assert_rc(actual, expected, return_tuple):
|
||||
|
@ -16,9 +16,10 @@
|
||||
#
|
||||
|
||||
from libnmstate import netinfo
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
INTERFACES = 'interfaces'
|
||||
INTERFACES = Constants.INTERFACES
|
||||
|
||||
|
||||
def show_only(ifnames):
|
||||
|
@ -21,8 +21,10 @@ import pytest
|
||||
from .compat import mock
|
||||
|
||||
from libnmstate import netapplier
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
INTERFACES = Constants.INTERFACES
|
||||
BOND_TYPE = 'bond'
|
||||
OVS_BR_TYPE = 'ovs-bridge'
|
||||
BOND_NAME = 'bond99'
|
||||
@ -52,7 +54,7 @@ def netinfo_nm_mock():
|
||||
|
||||
def test_iface_admin_state_change(netinfo_nm_mock, netapplier_nm_mock):
|
||||
current_config = {
|
||||
'interfaces': [
|
||||
INTERFACES: [
|
||||
{
|
||||
'name': 'foo',
|
||||
'type': 'unknown',
|
||||
@ -70,22 +72,22 @@ def test_iface_admin_state_change(netinfo_nm_mock, netapplier_nm_mock):
|
||||
|
||||
netinfo_nm_mock.device.list_devices.return_value = ['one-item']
|
||||
netinfo_nm_mock.translator.Nm2Api.get_common_device_info.return_value = (
|
||||
current_config['interfaces'][0])
|
||||
current_config[INTERFACES][0])
|
||||
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_config['interfaces'][0]['ipv4'])
|
||||
current_config[INTERFACES][0]['ipv4'])
|
||||
netinfo_nm_mock.ipv6.get_info.return_value = (
|
||||
current_config['interfaces'][0]['ipv6'])
|
||||
current_config[INTERFACES][0]['ipv6'])
|
||||
|
||||
desired_config['interfaces'][0]['state'] = 'down'
|
||||
desired_config[INTERFACES][0]['state'] = 'down'
|
||||
netapplier.apply(desired_config, verify_change=False)
|
||||
|
||||
netapplier_nm_mock.applier.set_ifaces_admin_state.assert_has_calls(
|
||||
[
|
||||
mock.call([]),
|
||||
mock.call(desired_config['interfaces'])
|
||||
mock.call(desired_config[INTERFACES])
|
||||
]
|
||||
)
|
||||
|
||||
@ -94,7 +96,7 @@ def test_add_new_bond(netinfo_nm_mock, netapplier_nm_mock):
|
||||
netinfo_nm_mock.device.list_devices.return_value = []
|
||||
|
||||
desired_config = {
|
||||
'interfaces': [
|
||||
INTERFACES: [
|
||||
{
|
||||
'name': 'bond99',
|
||||
'type': BOND_TYPE,
|
||||
@ -116,12 +118,12 @@ def test_add_new_bond(netinfo_nm_mock, netapplier_nm_mock):
|
||||
m_prepare.assert_called_once_with([])
|
||||
|
||||
m_prepare = netapplier_nm_mock.applier.prepare_new_ifaces_configuration
|
||||
m_prepare.assert_called_once_with(desired_config['interfaces'])
|
||||
m_prepare.assert_called_once_with(desired_config[INTERFACES])
|
||||
|
||||
|
||||
def test_edit_existing_bond(netinfo_nm_mock, netapplier_nm_mock):
|
||||
current_config = {
|
||||
'interfaces': [
|
||||
INTERFACES: [
|
||||
{
|
||||
'name': 'bond99',
|
||||
'type': BOND_TYPE,
|
||||
@ -145,27 +147,27 @@ def test_edit_existing_bond(netinfo_nm_mock, netapplier_nm_mock):
|
||||
|
||||
netinfo_nm_mock.device.list_devices.return_value = ['one-item']
|
||||
netinfo_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'],
|
||||
}
|
||||
netinfo_nm_mock.bond.is_bond_type_id.return_value = True
|
||||
netinfo_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']
|
||||
}
|
||||
netinfo_nm_mock.ipv4.get_info.return_value = (
|
||||
current_config['interfaces'][0]['ipv4'])
|
||||
current_config[INTERFACES][0]['ipv4'])
|
||||
netinfo_nm_mock.ipv6.get_info.return_value = (
|
||||
current_config['interfaces'][0]['ipv6'])
|
||||
current_config[INTERFACES][0]['ipv6'])
|
||||
|
||||
desired_config = copy.deepcopy(current_config)
|
||||
options = desired_config['interfaces'][0]['link-aggregation']['options']
|
||||
options = desired_config[INTERFACES][0]['link-aggregation']['options']
|
||||
options['miimon'] = 200
|
||||
|
||||
netapplier.apply(desired_config, verify_change=False)
|
||||
|
||||
m_prepare = netapplier_nm_mock.applier.prepare_edited_ifaces_configuration
|
||||
m_prepare.assert_called_once_with(desired_config['interfaces'])
|
||||
m_prepare.assert_called_once_with(desired_config[INTERFACES])
|
||||
|
||||
m_prepare = netapplier_nm_mock.applier.prepare_new_ifaces_configuration
|
||||
m_prepare.assert_called_once_with([])
|
||||
|
@ -19,6 +19,10 @@ import pytest
|
||||
from .compat import mock
|
||||
|
||||
from libnmstate import netinfo
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
INTERFACES = Constants.INTERFACES
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -29,7 +33,7 @@ def nm_mock():
|
||||
|
||||
def test_netinfo_show_generic_iface(nm_mock):
|
||||
current_config = {
|
||||
'interfaces': [
|
||||
INTERFACES: [
|
||||
{
|
||||
'name': 'foo',
|
||||
'type': 'unknown',
|
||||
@ -46,12 +50,12 @@ def test_netinfo_show_generic_iface(nm_mock):
|
||||
|
||||
nm_mock.device.list_devices.return_value = ['one-item']
|
||||
nm_mock.translator.Nm2Api.get_common_device_info.return_value = (
|
||||
current_config['interfaces'][0])
|
||||
current_config[INTERFACES][0])
|
||||
nm_mock.bond.is_bond_type_id.return_value = False
|
||||
nm_mock.ipv4.get_info.return_value = (
|
||||
current_config['interfaces'][0]['ipv4'])
|
||||
current_config[INTERFACES][0]['ipv4'])
|
||||
nm_mock.ipv6.get_info.return_value = (
|
||||
current_config['interfaces'][0]['ipv6'])
|
||||
current_config[INTERFACES][0]['ipv6'])
|
||||
|
||||
report = netinfo.show()
|
||||
|
||||
@ -60,7 +64,7 @@ def test_netinfo_show_generic_iface(nm_mock):
|
||||
|
||||
def test_netinfo_show_bond_iface(nm_mock):
|
||||
current_config = {
|
||||
'interfaces': [
|
||||
INTERFACES: [
|
||||
{
|
||||
'name': 'bond99',
|
||||
'type': 'bond',
|
||||
@ -84,18 +88,18 @@ def test_netinfo_show_bond_iface(nm_mock):
|
||||
|
||||
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'])
|
||||
current_config[INTERFACES][0]['ipv4'])
|
||||
nm_mock.ipv6.get_info.return_value = (
|
||||
current_config['interfaces'][0]['ipv6'])
|
||||
current_config[INTERFACES][0]['ipv6'])
|
||||
|
||||
report = netinfo.show()
|
||||
|
||||
|
@ -23,10 +23,14 @@ import pytest
|
||||
import jsonschema as js
|
||||
|
||||
import libnmstate
|
||||
from libnmstate.schema import Constants
|
||||
|
||||
|
||||
INTERFACES = Constants.INTERFACES
|
||||
|
||||
|
||||
COMMON_IFACE_DATA = {
|
||||
'interfaces': [
|
||||
INTERFACES: [
|
||||
{
|
||||
'name': 'lo',
|
||||
'description': 'Loopback Interface',
|
||||
@ -73,14 +77,14 @@ class TestIfaceCommon(object):
|
||||
libnmstate.validator.verify(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) as err:
|
||||
libnmstate.validator.verify(default_data)
|
||||
assert 'bad-state' in err.value.args[0]
|
||||
|
||||
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) as err:
|
||||
libnmstate.validator.verify(default_data)
|
||||
@ -90,14 +94,14 @@ class TestIfaceCommon(object):
|
||||
class TestIfaceTypeEthernet(object):
|
||||
|
||||
def test_valid_ethernet_with_auto_neg(self, default_data):
|
||||
default_data['interfaces'][0].update({
|
||||
default_data[INTERFACES][0].update({
|
||||
'type': 'ethernet',
|
||||
'auto-negotiation': True,
|
||||
})
|
||||
libnmstate.validator.verify(default_data)
|
||||
|
||||
def test_valid_ethernet_without_auto_neg(self, default_data):
|
||||
default_data['interfaces'][0].update({
|
||||
default_data[INTERFACES][0].update({
|
||||
'auto-negotiation': False,
|
||||
'link-speed': 1000,
|
||||
'duplex': 'full',
|
||||
@ -110,10 +114,10 @@ class TestIfaceTypeEthernet(object):
|
||||
not a valid configuration, however, this is not handled by the schema
|
||||
at the moment, deferring the handling to the application code.
|
||||
"""
|
||||
default_data['interfaces'][0].update({
|
||||
default_data[INTERFACES][0].update({
|
||||
'type': 'ethernet',
|
||||
'auto-negotiation': False,
|
||||
})
|
||||
del default_data['interfaces'][0]['link-speed']
|
||||
del default_data[INTERFACES][0]['link-speed']
|
||||
|
||||
libnmstate.validator.verify(default_data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user