From c6370b563b97ce5d9a6fbb3b3e3ce2afe7352a37 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 31 May 2016 13:12:21 -0700 Subject: [PATCH] Add validvals to addons, to be used by iface/ifedit wrapper Ticket: CM-8669 Reviewed By: Julien Testing Done: --- .gitignore | 3 +++ addons/__init__.py | 0 addons/address.py | 14 ++++++++++- addons/addressvirtual.py | 6 ++--- addons/bond.py | 6 +++++ addons/bridge.py | 46 +++++++++++++++++++++++++++++++----- addons/bridgevlan.py | 2 ++ addons/ethtool.py | 1 + addons/link.py | 1 + addons/mstpctl.py | 37 ++++++++++++++++++++++------- addons/usercmds.py | 18 +++++++++----- addons/vlan.py | 6 +++-- addons/vrrpd.py | 3 +++ addons/vxlan.py | 7 ++++++ ifupdownaddons/modulebase.py | 22 +++++++++++++---- 15 files changed, 140 insertions(+), 32 deletions(-) create mode 100644 .gitignore create mode 100644 addons/__init__.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b55d73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.pyc +*.swp +build diff --git a/addons/__init__.py b/addons/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/addons/address.py b/addons/address.py index 60d9487..661eae0 100644 --- a/addons/address.py +++ b/addons/address.py @@ -7,7 +7,7 @@ import os try: - from ipaddr import IPNetwork + from ipaddr import IPNetwork, IPv4Network, IPv6Network, IPv4Address, IPv6Address from sets import Set from ifupdown.iface import * from ifupdownaddons.modulebase import moduleBase @@ -28,34 +28,44 @@ class address(moduleBase): 'attrs': { 'address' : {'help' : 'ipv4 or ipv6 addresses', + 'validvals' : [IPv4Network, IPv6Network], + 'multiline' : True, 'example' : ['address 10.0.12.3/24', 'address 2000:1000:1000:1000:3::5/128']}, 'netmask' : {'help': 'netmask', + 'validvals' : [IPv4Address, ], 'example' : ['netmask 255.255.255.0'], 'compat' : True}, 'broadcast' : {'help': 'broadcast address', + 'validvals' : [IPv4Address, ], 'example' : ['broadcast 10.0.1.255']}, 'scope' : {'help': 'scope', + 'validvals' : ['universe', 'site', 'link', 'host', 'nowhere'], 'example' : ['scope host']}, 'preferred-lifetime' : {'help': 'preferred lifetime', + 'validrange' : ['0', '65535'], 'example' : ['preferred-lifetime forever', 'preferred-lifetime 10']}, 'gateway' : {'help': 'default gateway', + 'validvals' : [IPv4Address, IPv6Address], 'example' : ['gateway 255.255.255.0']}, 'mtu' : { 'help': 'interface mtu', + 'validrange' : ['552', '9216'], 'example' : ['mtu 1600'], 'default' : '1500'}, 'hwaddress' : {'help' : 'hw address', + 'validvals' : ['',], 'example': ['hwaddress 44:38:39:00:27:b8']}, 'alias' : { 'help': 'description/alias', + 'validvals' : ['',], 'example' : ['alias testnetwork']}, 'address-purge' : { 'help': 'purge existing addresses. By default ' + @@ -63,11 +73,13 @@ class address(moduleBase): 'purged to match persistant addresses in the ' + 'interfaces file. Set this attribute to \'no\'' + 'if you want to preserve existing addresses', + 'validvals' : ['yes', 'no'], 'default' : 'yes', 'example' : ['address-purge yes/no']}, 'clagd-vxlan-anycast-ip' : { 'help' : 'Anycast local IP address for ' + 'dual connected VxLANs', + 'validvals' : [IPv4Address, ], 'example' : ['clagd-vxlan-anycast-ip 36.0.0.11']}}} def __init__(self, *args, **kargs): diff --git a/addons/addressvirtual.py b/addons/addressvirtual.py index 7d1b330..73f2d4c 100644 --- a/addons/addressvirtual.py +++ b/addons/addressvirtual.py @@ -7,13 +7,12 @@ from ifupdown.iface import * from ifupdownaddons.modulebase import moduleBase from ifupdownaddons.iproute2 import iproute2 - import ifupdown.ifupdownconfig as ifupdownConfig import ifupdown.statemanager as statemanager from ifupdown.netlink import netlink import ifupdown.ifupdownflags as ifupdownflags -from ipaddr import IPNetwork +from ipaddr import IPNetwork, IPv4Network import logging import os import glob @@ -27,7 +26,8 @@ class addressvirtual(moduleBase): 'attrs' : { 'address-virtual' : { 'help' : 'bridge router virtual mac and ip', - 'example' : ['address-virtual 00:11:22:33:44:01 11.0.1.254/24 11.0.1.254/24']} + 'validvals' : [('', IPv4Network), ], + 'example' : ['address-virtual 00:11:22:33:44:01 11.0.1.1/24 11.0.1.2/24']} }} diff --git a/addons/bond.py b/addons/bond.py index c4f4e00..0bc5095 100644 --- a/addons/bond.py +++ b/addons/bond.py @@ -62,25 +62,30 @@ class bond(moduleBase): 'bond-min-links': {'help' : 'bond min links', 'default' : '0', + 'validrange' : ['0', '255'], 'example' : ['bond-min-links 0']}, 'bond-ad-sys-priority': {'help' : '802.3ad system priority', 'default' : '65535', + 'validrange' : ['0', '65535'], 'example' : ['bond-ad-sys-priority 65535'], 'deprecated' : True, 'new-attribute' : 'bond-ad-actor-sys-prio'}, 'bond-ad-actor-sys-prio': {'help' : '802.3ad system priority', 'default' : '65535', + 'validrange' : ['0', '65535'], 'example' : ['bond-ad-actor-sys-prio 65535']}, 'bond-ad-sys-mac-addr': {'help' : '802.3ad system mac address', + 'validvals' : ['',], 'default' : '00:00:00:00:00:00', 'example' : ['bond-ad-sys-mac-addr 00:00:00:00:00:00'], 'deprecated' : True, 'new-attribute' : 'bond-ad-actor-system'}, 'bond-ad-actor-system': {'help' : '802.3ad system mac address', + 'validvals' : ['',], 'default' : '00:00:00:00:00:00', 'example' : ['bond-ad-actor-system 00:00:00:00:00:00'],}, 'bond-lacp-bypass-allow': @@ -91,6 +96,7 @@ class bond(moduleBase): 'bond-slaves' : {'help' : 'bond slaves', 'required' : True, + 'multivalue' : True, 'example' : ['bond-slaves swp1 swp2', 'bond-slaves glob swp1-2', 'bond-slaves regex (swp[1|2)']}}} diff --git a/addons/bridge.py b/addons/bridge.py index 8b9f38f..93e38fa 100644 --- a/addons/bridge.py +++ b/addons/bridge.py @@ -35,9 +35,11 @@ class bridge(moduleBase): {'help' : 'vlan aware bridge. Setting this ' + 'attribute to yes enables vlan filtering' + ' on the bridge', + 'validvals' : ['yes', 'no'], 'example' : ['bridge-vlan-aware yes/no']}, 'bridge-ports' : {'help' : 'bridge ports', + 'multivalue' : True, 'required' : True, 'example' : ['bridge-ports swp1.100 swp2.100 swp3.100', 'bridge-ports glob swp1-3.100', @@ -49,109 +51,137 @@ class bridge(moduleBase): 'default' : 'no'}, 'bridge-bridgeprio' : {'help': 'bridge priority', + 'validrange' : ['0', '65535'], 'example' : ['bridge-bridgeprio 32768'], 'default' : '32768'}, 'bridge-ageing' : {'help': 'bridge ageing', + 'validrange' : ['0', '65535'], 'example' : ['bridge-ageing 300'], 'default' : '300'}, 'bridge-fd' : { 'help' : 'bridge forward delay', + 'validrange' : ['0', '255'], 'example' : ['bridge-fd 15'], 'default' : '15'}, 'bridge-gcint' : # XXX: recheck values { 'help' : 'bridge garbage collection interval in secs', + 'validrange' : ['0', '255'], 'example' : ['bridge-gcint 4'], 'default' : '4', 'compat' : True, 'deprecated': True}, 'bridge-hello' : { 'help' : 'bridge set hello time', + 'validrange' : ['0', '255'], 'example' : ['bridge-hello 2'], 'default' : '2'}, 'bridge-maxage' : { 'help' : 'bridge set maxage', + 'validrange' : ['0', '255'], 'example' : ['bridge-maxage 20'], 'default' : '20'}, 'bridge-pathcosts' : { 'help' : 'bridge set port path costs', - 'example' : ['bridge-pathcosts swp1=100 swp2=100'], + 'validrange' : ['0', '65535'], + 'example' : ['under the bridge: bridge-pathcosts swp1=100 swp2=100', + 'under the port (recommended): bridge-pathcosts 100'], 'default' : '100'}, 'bridge-portprios' : { 'help' : 'bridge port prios', - 'example' : ['bridge-portprios swp1=32 swp2=32'], + 'validrange' : ['0', '65535'], + 'example' : ['under the bridge: bridge-portprios swp1=32 swp2=32', + 'under the port (recommended): bridge-portprios 32'], 'default' : '32'}, 'bridge-mclmc' : { 'help' : 'set multicast last member count', + 'validrange' : ['0', '255'], 'example' : ['bridge-mclmc 2'], 'default' : '2'}, 'bridge-mcrouter' : { 'help' : 'set multicast router', + 'validvals' : ['0', '1'], 'default' : '1', 'example' : ['bridge-mcrouter 1']}, 'bridge-mcsnoop' : { 'help' : 'set multicast snooping', + 'validvals' : ['0', '1'], 'default' : '1', 'example' : ['bridge-mcsnoop 1']}, 'bridge-mcsqc' : { 'help' : 'set multicast startup query count', + 'validrange' : ['0', '255'], 'default' : '2', 'example' : ['bridge-mcsqc 2']}, 'bridge-mcqifaddr' : { 'help' : 'set multicast query to use ifaddr', + 'validvals' : ['0', '1'], 'default' : '0', 'example' : ['bridge-mcqifaddr 0']}, 'bridge-mcquerier' : { 'help' : 'set multicast querier', + 'validvals' : ['0', '1'], 'default' : '0', 'example' : ['bridge-mcquerier 0']}, 'bridge-hashel' : { 'help' : 'set hash elasticity', + 'validrange' : ['0', '4096'], 'default' : '4096', 'example' : ['bridge-hashel 4096']}, 'bridge-hashmax' : { 'help' : 'set hash max', + 'validrange' : ['0', '4096'], 'default' : '4096', 'example' : ['bridge-hashmax 4096']}, 'bridge-mclmi' : { 'help' : 'set multicast last member interval (in secs)', + 'validrange' : ['0', '255'], 'default' : '1', 'example' : ['bridge-mclmi 1']}, 'bridge-mcmi' : { 'help' : 'set multicast membership interval (in secs)', + 'validrange' : ['0', '255'], 'default' : '260', 'example' : ['bridge-mcmi 260']}, 'bridge-mcqpi' : { 'help' : 'set multicast querier interval (in secs)', + 'validrange' : ['0', '255'], 'default' : '255', 'example' : ['bridge-mcqpi 255']}, 'bridge-mcqi' : { 'help' : 'set multicast query interval (in secs)', + 'validrange' : ['0', '255'], 'default' : '125', 'example' : ['bridge-mcqi 125']}, 'bridge-mcqri' : { 'help' : 'set multicast query response interval (in secs)', + 'validrange' : ['0', '255'], 'default' : '10', 'example' : ['bridge-mcqri 10']}, 'bridge-mcsqi' : { 'help' : 'set multicast startup query interval (in secs)', + 'validrange' : ['0', '255'], 'default' : '31', 'example' : ['bridge-mcsqi 31']}, 'bridge-mcqv4src' : { 'help' : 'set per VLAN v4 multicast querier source address', + 'validvals' : ['', ], + 'multivalue' : True, 'compat' : True, 'example' : ['bridge-mcqv4src 100=172.16.100.1 101=172.16.101.1']}, 'bridge-portmcrouter' : { 'help' : 'set port multicast routers', + 'validvals' : ['0', '1'], 'default' : '1', 'example' : ['under the bridge: bridge-portmcrouter swp1=1 swp2=1', - 'under the port: bridge-portmcrouter 1']}, + 'under the port (recommended): bridge-portmcrouter 1']}, 'bridge-portmcfl' : { 'help' : 'port multicast fast leave.', + 'validrange' : ['0', '65535'], 'default' : '0', 'example' : ['under the bridge: bridge-portmcfl swp1=0 swp2=0', - 'under the port: bridge-portmcfl 0']}, + 'under the port (recommended): bridge-portmcfl 0']}, 'bridge-waitport' : { 'help' : 'wait for a max of time secs for the' + ' specified ports to become available,' + @@ -165,11 +195,12 @@ class bridge(moduleBase): 'example' : ['bridge-waitport 4 swp1 swp2']}, 'bridge-maxwait' : { 'help' : 'forces to time seconds the maximum time ' + - 'that the Debian bridge setup scripts will ' + + 'that the Debian bridge setup scripts will ' + 'wait for the bridge ports to get to the ' + 'forwarding status, doesn\'t allow factional ' + 'part. If it is equal to 0 then no waiting' + ' is done', + 'validrange' : ['0', '255'], 'default' : '0', 'example' : ['bridge-maxwait 3']}, 'bridge-vids' : @@ -177,22 +208,25 @@ class bridge(moduleBase): 'under the bridge or under the port. ' + 'If specified under the bridge the ports ' + 'inherit it unless overridden by a ' + - 'bridge-vids attribuet under the port', + 'bridge-vids attribute under the port', 'example' : ['bridge-vids 4000', 'bridge-vids 2000 2200-3000']}, 'bridge-pvid' : { 'help' : 'bridge port pvid. Must be specified under' + ' the bridge port', + 'validrange' : ['0', '4096'], 'example' : ['bridge-pvid 1']}, 'bridge-access' : { 'help' : 'bridge port access vlan. Must be ' + 'specified under the bridge port', + 'validrange' : ['0', '4096'], 'example' : ['bridge-access 300']}, 'bridge-allow-untagged' : { 'help' : 'indicate if the bridge port accepts ' + 'untagged packets or not. Must be ' + 'specified under the bridge port. ' + 'Default is \'yes\'', + 'validvals' : ['yes', 'no'], 'example' : ['bridge-allow-untagged yes'], 'default' : 'yes'}, 'bridge-port-vids' : diff --git a/addons/bridgevlan.py b/addons/bridgevlan.py index fe26196..80245cc 100644 --- a/addons/bridgevlan.py +++ b/addons/bridgevlan.py @@ -8,6 +8,7 @@ from ifupdown.iface import * from ifupdownaddons.modulebase import moduleBase from ifupdownaddons.iproute2 import iproute2 from ifupdownaddons.bridgeutils import brctl +from ipaddr import IPv4Address import ifupdown.ifupdownflags as ifupdownflags import logging @@ -24,6 +25,7 @@ class bridgevlan(moduleBase): 'bridge-igmp-querier-src' : { 'help' : 'bridge igmp querier src. Must be ' + 'specified under the vlan interface', + 'validvals' : [IPv4Address, ], 'example' : ['bridge-igmp-querier-src 172.16.101.1']}}} def __init__(self, *args, **kargs): diff --git a/addons/ethtool.py b/addons/ethtool.py index 1fbda65..548cd89 100644 --- a/addons/ethtool.py +++ b/addons/ethtool.py @@ -25,6 +25,7 @@ class ethtool(moduleBase,utilsBase): 'attrs': { 'link-speed' : {'help' : 'set link speed', + 'validvals' : ['100', '1000', '10000', '40000', '100000'], 'example' : ['link-speed 1000'], 'default' : 'varies by platform and port'}, 'link-duplex' : diff --git a/addons/link.py b/addons/link.py index 98f315d..1682000 100644 --- a/addons/link.py +++ b/addons/link.py @@ -17,6 +17,7 @@ class link(moduleBase): 'attrs' : { 'link-type' : {'help' : 'type of link as in \'ip link\' command.', + 'validvals' : ['dummy', 'veth'], 'example' : ['link-type ']}}} def __init__(self, *args, **kargs): diff --git a/addons/mstpctl.py b/addons/mstpctl.py index 4501b3e..442c63f 100644 --- a/addons/mstpctl.py +++ b/addons/mstpctl.py @@ -30,6 +30,7 @@ class mstpctl(moduleBase): 'new-attribute': 'bridge-ports'}, 'mstpctl-stp' : {'help': 'bridge stp yes/no', + 'validvals' : ['yes', 'no'], 'compat' : True, 'default' : 'no', 'deprecated': True, @@ -42,47 +43,56 @@ class mstpctl(moduleBase): 'example' : ['mstpctl-treeprio 32768']}, 'mstpctl-ageing' : {'help': 'ageing time', + 'validrange' : ['0', '4096'], 'default' : '300', 'required' : False, 'example' : ['mstpctl-ageing 300']}, 'mstpctl-maxage' : { 'help' : 'max message age', + 'validrange' : ['0', '255'], 'default' : '20', 'required' : False, 'example' : ['mstpctl-maxage 20']}, 'mstpctl-fdelay' : { 'help' : 'set forwarding delay', + 'validrange' : ['0', '255'], 'default' : '15', 'required' : False, 'example' : ['mstpctl-fdelay 15']}, 'mstpctl-maxhops' : { 'help' : 'bridge max hops', + 'validrange' : ['0', '255'], 'default' : '15', 'required' : False, 'example' : ['mstpctl-maxhops 15']}, 'mstpctl-txholdcount' : { 'help' : 'bridge transmit holdcount', + 'validrange' : ['0', '255'], 'default' : '6', 'required' : False, 'example' : ['mstpctl-txholdcount 6']}, 'mstpctl-forcevers' : { 'help' : 'bridge force stp version', + 'validvals' : ['rstp', ], 'default' : 'rstp', 'required' : False, 'example' : ['mstpctl-forcevers rstp']}, 'mstpctl-portpathcost' : { 'help' : 'bridge port path cost', + 'validrange' : ['0', '65535'], 'default' : '0', 'jsonAttr' : 'adminExtPortCost', 'required' : False, - 'example' : ['mstpctl-portpathcost swp1=0 swp2=1']}, + 'example' : ['under the bridge: mstpctl-portpathcost swp1=0 swp2=1', + 'under the port (recommended): mstpctl-portpathcost 0']}, 'mstpctl-portp2p' : { 'help' : 'bridge port p2p detection mode', 'default' : 'auto', 'jsonAttr' : 'adminPointToPoint', 'validvals' : ['yes', 'no', 'auto'], 'required' : False, - 'example' : ['mstpctl-portp2p swp1=no swp2=no']}, + 'example' : ['under the bridge: mstpctl-portp2p swp1=yes swp2=no', + 'under the port (recommended): mstpctl-portp2p yes']}, 'mstpctl-portrestrrole' : { 'help' : 'enable/disable port ability to take root role of the port', @@ -90,7 +100,8 @@ class mstpctl(moduleBase): 'jsonAttr' : 'restrictedRole', 'validvals' : ['yes', 'no'], 'required' : False, - 'example' : ['mstpctl-portrestrrole swp1=no swp2=no']}, + 'example' : ['under the bridge: mstpctl-portrestrrole swp1=yes swp2=no', + 'under the port (recommended): mstpctl-portrestrrole yes']}, 'mstpctl-portrestrtcn' : { 'help' : 'enable/disable port ability to propagate received topology change notification of the port', @@ -98,7 +109,8 @@ class mstpctl(moduleBase): 'jsonAttr' : 'restrictedTcn', 'validvals' : ['yes', 'no'], 'required' : False, - 'example' : ['mstpctl-portrestrtcn swp1=no swp2=no']}, + 'example' : ['under the bridge: mstpctl-portrestrtcn swp1=yes swp2=no', + 'under the port (recommended): mstpctl-portrestrtcn yes']}, 'mstpctl-bpduguard' : { 'help' : 'enable/disable bpduguard', @@ -106,16 +118,19 @@ class mstpctl(moduleBase): 'jsonAttr' : 'bpduGuardPort', 'validvals' : ['yes', 'no'], 'required' : False, - 'example' : ['mstpctl-bpduguard swp1=no swp2=no']}, + 'example' : ['under the bridge: mstpctl-bpduguard swp1=yes swp2=no', + 'under the port (recommended): mstpctl-bpduguard yes']}, 'mstpctl-treeportprio' : { 'help' : 'port priority for MSTI instance', 'default' : '128', 'validrange' : ['0', '240'], 'required' : False, - 'example' : ['mstpctl-treeportprio swp1=128 swp2=128']}, + 'example' : ['under the bridge: mstpctl-treeportprio swp1=128 swp2=128', + 'under the port (recommended): mstpctl-treeportprio 128']}, 'mstpctl-hello' : { 'help' : 'set hello time', + 'validrange' : ['0', '255'], 'default' : '2', 'required' : False, 'example' : ['mstpctl-hello 2']}, @@ -125,23 +140,27 @@ class mstpctl(moduleBase): 'default' : 'no', 'jsonAttr' : 'networkPort', 'required' : False, - 'example' : ['mstpctl-portnetwork swp1=no swp2=no']}, + 'example' : ['under the bridge: mstpctl-portnetwork swp1=yes swp2=no', + 'under the port (recommended): mstpctl-portnetwork yes']}, 'mstpctl-portadminedge' : { 'help' : 'enable/disable initial edge state of the port', 'validvals' : ['yes', 'no'], 'default' : 'no', 'jsonAttr' : 'adminEdgePort', 'required' : False, - 'example' : ['mstpctl-portadminedge swp1=no swp2=no']}, + 'example' : ['under the bridge: mstpctl-portadminedge swp1=yes swp2=no', + 'under the port (recommended): mstpctl-portadminedge yes']}, 'mstpctl-portautoedge' : { 'help' : 'enable/disable auto transition to/from edge state of the port', 'validvals' : ['yes', 'no'], 'default' : 'yes', 'jsonAttr' : 'autoEdgePort', 'required' : False, - 'example' : ['mstpctl-portautoedge swp1=yes swp2=yes']}, + 'example' : ['under the bridge: mstpctl-portautoedge swp1=yes swp2=no', + 'under the port (recommended): mstpctl-portautoedge yes']}, 'mstpctl-treeportcost' : { 'help' : 'port tree cost', + 'validrange' : ['0', '255'], 'required' : False}, 'mstpctl-portbpdufilter' : { 'help' : 'enable/disable bpdu filter on a port. ' + diff --git a/addons/usercmds.py b/addons/usercmds.py index 738a8ac..57e8dce 100644 --- a/addons/usercmds.py +++ b/addons/usercmds.py @@ -15,17 +15,23 @@ class usercmds(ifupdownaddons.modulebase.moduleBase): _modinfo = {'mhelp' : 'user commands for interfaces', 'attrs' : { 'pre-up' : - {'help' : 'run command before bringing the interface up'}, + {'help' : 'run command before bringing the interface up', + 'multiline' : True}, 'up' : - {'help' : 'run command at interface bring up'}, + {'help' : 'run command at interface bring up', + 'multiline' : True}, 'post-up' : - {'help' : 'run command after interface bring up'}, + {'help' : 'run command after interface bring up', + 'multiline' : True}, 'pre-down' : - {'help' : 'run command before bringing the interface down'}, + {'help' : 'run command before bringing the interface down', + 'multiline' : True}, 'down' : - {'help' : 'run command at interface down'}, + {'help' : 'run command at interface down', + 'multiline' : True}, 'post-down' : - {'help' : 'run command after bringing interface down'}}} + {'help' : 'run command after bringing interface down', + 'multiline' : True}}} def _run_command(self, ifaceobj, op): cmd_list = ifaceobj.get_attr_value(op) diff --git a/addons/vlan.py b/addons/vlan.py index 9d36002..ec2e2e5 100644 --- a/addons/vlan.py +++ b/addons/vlan.py @@ -24,9 +24,11 @@ class vlan(moduleBase): 'attributes', 'attrs' : { 'vlan-raw-device' : - {'help' : 'vlan raw device'}, + {'help' : 'vlan raw device', + 'validvals' : ['' ,]}, 'vlan-id' : - {'help' : 'vlan id'}}} + {'help' : 'vlan id', + 'validrange' : ['0', '4096']}}} def __init__(self, *args, **kargs): diff --git a/addons/vrrpd.py b/addons/vrrpd.py index 8385ac7..575e992 100644 --- a/addons/vrrpd.py +++ b/addons/vrrpd.py @@ -27,12 +27,15 @@ class vrrpd(moduleBase): 'attrs': { 'vrrp-id' : {'help' : 'vrrp instance id', + 'validrange' : ['1', '4096'], 'example' : ['vrrp-id 1']}, 'vrrp-priority' : {'help': 'set vrrp priority', + 'validrange' : ['0', '255'], 'example' : ['vrrp-priority 20']}, 'vrrp-virtual-ip' : {'help': 'set vrrp virtual ip', + 'validvals' : [IPv4Address, ], 'example' : ['vrrp-virtual-ip 10.0.1.254']}}} def __init__(self, *args, **kargs): diff --git a/addons/vxlan.py b/addons/vxlan.py index 2dba83c..db2d9b1 100644 --- a/addons/vxlan.py +++ b/addons/vxlan.py @@ -5,6 +5,7 @@ from ifupdownaddons.modulebase import moduleBase from ifupdownaddons.iproute2 import iproute2 from ifupdownaddons.systemutils import systemUtils from ifupdown.netlink import netlink +from ipaddr import IPv4Address import ifupdown.ifupdownflags as ifupdownflags import logging import os @@ -15,23 +16,29 @@ class vxlan(moduleBase): 'attrs' : { 'vxlan-id' : {'help' : 'vxlan id', + 'validrange' : ['0', '4096'], 'required' : True, 'example': ['vxlan-id 100']}, 'vxlan-local-tunnelip' : {'help' : 'vxlan local tunnel ip', + 'validvals' : [IPv4Address, ], 'example': ['vxlan-local-tunnelip 172.16.20.103']}, 'vxlan-svcnodeip' : {'help' : 'vxlan id', + 'validvals' : [IPv4Address, ], 'example': ['vxlan-svcnodeip 172.16.22.125']}, 'vxlan-remoteip' : {'help' : 'vxlan remote ip', + 'validvals' : [IPv4Address, ], 'example': ['vxlan-remoteip 172.16.22.127']}, 'vxlan-learning' : {'help' : 'vxlan learning on/off', + 'validvals' : ['on', 'off'], 'example': ['vxlan-learning off'], 'default': 'on'}, 'vxlan-ageing' : {'help' : 'vxlan aging timer', + 'validrange' : ['0', '4096'], 'example': ['vxlan-ageing 300'], 'default': '300'}, }} diff --git a/ifupdownaddons/modulebase.py b/ifupdownaddons/modulebase.py index c017841..6333270 100644 --- a/ifupdownaddons/modulebase.py +++ b/ifupdownaddons/modulebase.py @@ -29,6 +29,12 @@ class moduleBase(object): # here so that all modules can use it self.vrf_exec_cmd_prefix = policymanager.policymanager_api.get_module_globals('vrf', attr='vrf-exec-cmd-prefix') + # explanations are shown in parse_glob + self.glob_regexs = [re.compile(r"([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\]([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\](.*)"), + re.compile(r"([A-Za-z0-9\-]+[A-Za-z])(\d+)\-(\d+)(.*)"), + re.compile(r"([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\](.*)")] + + def log_warn(self, str, ifaceobj=None): """ log a warning if err str is not one of which we should ignore """ if not self.ignore_error(str): @@ -93,15 +99,21 @@ class moduleBase(object): raise Exception('%s: error searching regex \'%s\' in %s (%s)' %(ifacename, expr, ifacename, str(e))) + def ifname_is_glob(self, ifname): + """ + Used by iface where ifname could be swp7 or swp[1-10].300 + """ + if (self.glob_regexs[0].match(ifname) or + self.glob_regexs[1].match(ifname) or + self.glob_regexs[2].match(ifname)): + return True + return False + def parse_glob(self, ifacename, expr): errmsg = ('error parsing glob expression \'%s\'' %expr + ' (supported glob syntax: swp1-10.300 or swp[1-10].300' + ' or swp[1-10]sub[0-4].300') - - # explanations are shown below in each if clause - regexs = [re.compile(r"([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\]([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\](.*)"), - re.compile(r"([A-Za-z0-9\-]+[A-Za-z])(\d+)\-(\d+)(.*)"), - re.compile(r"([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\](.*)")] + regexs = self.glob_regexs if regexs[0].match(expr): # the first regex checks for exactly two levels of ranges defined only with square brackets