Skip to content

Commit

Permalink
configverify: T6642: verify_interface_exists requires config_dict arg
Browse files Browse the repository at this point in the history
The function verify_interface_exists requires a reference to the ambient
config_dict rather than creating an instance. As access is required to
the 'interfaces' path, provide as attribute of class ConfigDict, so as
not to confuse path searches of script-specific config_dict instances.
  • Loading branch information
jestabro committed Aug 9, 2024
1 parent ed63c9d commit 81b7917
Show file tree
Hide file tree
Showing 26 changed files with 33 additions and 32 deletions.
3 changes: 3 additions & 0 deletions python/vyos/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ def get_config_dict(self, path=[], effective=False, key_mangling=None,

conf_dict['pki'] = pki_dict

interfaces_root = root_dict.get('interfaces', {})
setattr(conf_dict, 'interfaces_root', interfaces_root)

# save optional args for a call to get_config_defaults
setattr(conf_dict, '_dict_kwargs', kwargs)

Expand Down
6 changes: 2 additions & 4 deletions python/vyos/configverify.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,22 +237,20 @@ def verify_bridge_delete(config):
raise ConfigError(f'Interface "{interface}" cannot be deleted as it '
f'is a member of bridge "{bridge_name}"!')

def verify_interface_exists(ifname, state_required=False, warning_only=False):
def verify_interface_exists(config, ifname, state_required=False, warning_only=False):
"""
Common helper function used by interface implementations to perform
recurring validation if an interface actually exists. We first probe
if the interface is defined on the CLI, if it's not found we try if
it exists at the OS level.
"""
from vyos.base import Warning
from vyos.configquery import ConfigTreeQuery
from vyos.utils.dict import dict_search_recursive
from vyos.utils.network import interface_exists

if not state_required:
# Check if interface is present in CLI config
config = ConfigTreeQuery()
tmp = config.get_config_dict(['interfaces'], get_first_key=True)
tmp = getattr(config, 'interfaces_root', {})
if bool(list(dict_search_recursive(tmp, ifname))):
return True

Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/firewall.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def verify(firewall):
raise ConfigError(f'Flowtable "{flowtable}" requires at least one interface')

for ifname in flowtable_conf['interface']:
verify_interface_exists(ifname)
verify_interface_exists(firewall, ifname)

if dict_search_args(flowtable_conf, 'offload') == 'hardware':
interfaces = flowtable_conf['interface']
Expand Down
4 changes: 2 additions & 2 deletions src/conf_mode/interfaces_ethernet.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def verify_bond_member(ethernet):
:type ethernet: dict
"""
ifname = ethernet['ifname']
verify_interface_exists(ifname)
verify_interface_exists(ethernet, ifname)
verify_eapol(ethernet)
verify_mirror_redirect(ethernet)
ethtool = Ethtool(ifname)
Expand All @@ -327,7 +327,7 @@ def verify_ethernet(ethernet):
:type ethernet: dict
"""
ifname = ethernet['ifname']
verify_interface_exists(ifname)
verify_interface_exists(ethernet, ifname)
verify_mtu(ethernet)
verify_mtu_ipv6(ethernet)
verify_dhcpv6(ethernet)
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/interfaces_wwan.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def verify(wwan):
if not 'apn' in wwan:
raise ConfigError(f'No APN configured for "{ifname}"!')

verify_interface_exists(ifname)
verify_interface_exists(wwan, ifname)
verify_authentication(wwan)
verify_vrf(wwan)
verify_mirror_redirect(wwan)
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/policy_local-route.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def verify(pbr):

if 'inbound_interface' in pbr_route['rule'][rule]:
interface = pbr_route['rule'][rule]['inbound_interface']
verify_interface_exists(interface)
verify_interface_exists(pbr, interface)

return None

Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/protocols_igmp-proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def verify(igmp_proxy):

upstream = 0
for interface, config in igmp_proxy['interface'].items():
verify_interface_exists(interface)
verify_interface_exists(igmp_proxy, interface)
if dict_search('role', config) == 'upstream':
upstream += 1

Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/protocols_isis.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def verify(isis):
raise ConfigError('Interface used for routing updates is mandatory!')

for interface in isis['interface']:
verify_interface_exists(interface)
verify_interface_exists(isis, interface)
# Interface MTU must be >= configured lsp-mtu
mtu = Interface(interface).get_mtu()
area_mtu = isis['lsp_mtu']
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/protocols_mpls.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def verify(mpls):

if 'interface' in mpls:
for interface in mpls['interface']:
verify_interface_exists(interface)
verify_interface_exists(mpls, interface)

# Checks to see if LDP is properly configured
if 'ldp' in mpls:
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/protocols_ospf.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def verify(ospf):

if 'interface' in ospf:
for interface, interface_config in ospf['interface'].items():
verify_interface_exists(interface)
verify_interface_exists(ospf, interface)
# One can not use dead-interval and hello-multiplier at the same
# time. FRR will only activate the last option set via CLI.
if {'hello_multiplier', 'dead_interval'} <= set(interface_config):
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/protocols_ospfv3.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def verify(ospfv3):

if 'interface' in ospfv3:
for interface, interface_config in ospfv3['interface'].items():
verify_interface_exists(interface)
verify_interface_exists(ospfv3, interface)
if 'ifmtu' in interface_config:
mtu = Interface(interface).get_mtu()
if int(interface_config['ifmtu']) > int(mtu):
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/protocols_pim.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def verify(pim):
raise ConfigError('PIM require defined interfaces!')

for interface, interface_config in pim['interface'].items():
verify_interface_exists(interface)
verify_interface_exists(pim, interface)

# Check join group in reserved net
if 'igmp' in interface_config and 'join' in interface_config['igmp']:
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/protocols_pim6.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def verify(pim6):
return

for interface, interface_config in pim6.get('interface', {}).items():
verify_interface_exists(interface)
verify_interface_exists(pim6, interface)
if 'mld' in interface_config:
mld = interface_config['mld']
for group in mld.get('join', {}).keys():
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/qos.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ def apply(qos):
return None

for interface, interface_config in qos['interface'].items():
if not verify_interface_exists(interface, state_required=True, warning_only=True):
if not verify_interface_exists(qos, interface, state_required=True, warning_only=True):
# When shaper is bound to a dialup (e.g. PPPoE) interface it is
# possible that it is yet not availbale when to QoS code runs.
# Skip the configuration and inform the user via warning_only=True
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_broadcast-relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def verify(relay):
raise ConfigError('At least two interfaces are required for UDP broadcast relay "{instance}"')

for interface in config.get('interface', []):
verify_interface_exists(interface)
verify_interface_exists(relay, interface)
if not is_afi_configured(interface, AF_INET):
raise ConfigError(f'Interface "{interface}" has no IPv4 address configured!')

Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_conntrack-sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def verify(conntrack):

has_peer = False
for interface, interface_config in conntrack['interface'].items():
verify_interface_exists(interface)
verify_interface_exists(conntrack, interface)
# Interface must not only exist, it must also carry an IP address
if len(get_ipv4(interface)) < 1:
raise ConfigError(f'Interface {interface} requires an IP address!')
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_dns_dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def verify(dyndns):
Warning(f'Interface "{config["address"]["interface"]}" does not exist yet and '
f'cannot be used for Dynamic DNS service "{service}" until it is up!')
else:
verify_interface_exists(config['address']['interface'])
verify_interface_exists(dyndns, config['address']['interface'])

if 'web' in config['address']:
# If 'skip' is specified, 'url' is required as well
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_ipoe-server.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def verify(ipoe):
raise ConfigError('No IPoE interface configured')

for interface, iface_config in ipoe['interface'].items():
verify_interface_exists(interface, warning_only=True)
verify_interface_exists(ipoe, interface, warning_only=True)
if 'client_subnet' in iface_config and 'vlan' in iface_config:
raise ConfigError('Option "client-subnet" and "vlan" are mutually exclusive, '
'use "client-ip-pool" instead!')
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_mdns_repeater.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def verify(mdns):
# For mdns-repeater to work it is essential that the interfaces has
# an IPv4 address assigned
for interface in mdns['interface']:
verify_interface_exists(interface)
verify_interface_exists(mdns, interface)

if mdns['ip_version'] in ['ipv4', 'both'] and AF_INET not in ifaddresses(interface):
raise ConfigError('mDNS repeater requires an IPv4 address to be '
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_ndp-proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def verify(ndpp):

if 'interface' in ndpp:
for interface, interface_config in ndpp['interface'].items():
verify_interface_exists(interface)
verify_interface_exists(ndpp, interface)

if 'rule' in interface_config:
for rule, rule_config in interface_config['rule'].items():
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_ntp.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def verify(ntp):
if 'interface' in ntp:
# If ntpd should listen on a given interface, ensure it exists
interface = ntp['interface']
verify_interface_exists(interface)
verify_interface_exists(ntp, interface)

# If we run in a VRF, our interface must belong to this VRF, too
if 'vrf' in ntp:
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_pppoe-server.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def verify(pppoe):

# Check is interface exists in the system
for interface in pppoe['interface']:
verify_interface_exists(interface, warning_only=True)
verify_interface_exists(pppoe, interface, warning_only=True)

return None

Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/service_salt-minion.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def verify(salt):
Warning('Do not use sha1 hashing algorithm, upgrade to sha256 or later!')

if 'source_interface' in salt:
verify_interface_exists(salt['source_interface'])
verify_interface_exists(salt, salt['source_interface'])

return None

Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/system_flow-accounting.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def verify(flow_config):

# check that all configured interfaces exists in the system
for interface in flow_config['interface']:
verify_interface_exists(interface, warning_only=True)
verify_interface_exists(flow_config, interface, warning_only=True)

# check sFlow configuration
if 'sflow' in flow_config:
Expand Down
2 changes: 1 addition & 1 deletion src/conf_mode/system_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def verify(options):
if 'http_client' in options:
config = options['http_client']
if 'source_interface' in config:
verify_interface_exists(config['source_interface'])
verify_interface_exists(options, config['source_interface'])

if {'source_address', 'source_interface'} <= set(config):
raise ConfigError('Can not define both HTTP source-interface and source-address')
Expand Down
8 changes: 4 additions & 4 deletions src/conf_mode/vpn_ipsec.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ def verify(ipsec):
for interface in ipsec['interface']:
# exclude check interface for dynamic interfaces
if tmp.match(interface):
verify_interface_exists(interface, warning_only=True)
verify_interface_exists(ipsec, interface, warning_only=True)
else:
verify_interface_exists(interface)
verify_interface_exists(ipsec, interface)

if 'l2tp' in ipsec:
if 'esp_group' in ipsec['l2tp']:
Expand Down Expand Up @@ -273,7 +273,7 @@ def verify(ipsec):
if 'dhcp_interface' in ra_conf:
dhcp_interface = ra_conf['dhcp_interface']

verify_interface_exists(dhcp_interface)
verify_interface_exists(ipsec, dhcp_interface)
dhcp_base = directories['isc_dhclient_dir']

if not os.path.exists(f'{dhcp_base}/dhclient_{dhcp_interface}.conf'):
Expand Down Expand Up @@ -502,7 +502,7 @@ def verify(ipsec):
if 'dhcp_interface' in peer_conf:
dhcp_interface = peer_conf['dhcp_interface']

verify_interface_exists(dhcp_interface)
verify_interface_exists(ipsec, dhcp_interface)
dhcp_base = directories['isc_dhclient_dir']

if not os.path.exists(f'{dhcp_base}/dhclient_{dhcp_interface}.conf'):
Expand Down

0 comments on commit 81b7917

Please sign in to comment.