mirror of
				https://github.com/CumulusNetworks/ifupdown2.git
				synced 2024-05-06 15:54:50 +00:00 
			
		
		
		
	Ticket: CM-8101
Reviewed By: CCR-4949
Testing Done: smoke tests + ran ifup -a -s on every interface configuration file from GSS cl-supports collection
This commit is introducing ~20 keywords. The value of the different attributes
will be check against raw values and <keywords>:
'<mac>'
'<text>'
'<ipv4>'
'<ipv6>'
'<auto>': "auto"
'<ipaddr>': ipv4/6 with preflix len
'<number>'
'<interface>'
'<ipv4-vrf-text>': equivalent to: <ipv4> "vrf" <text>
'<number-ipv4-list>': example: "100=172.16.100.1 101=172.16.101.1"
'<interface-list>': example: "swp1 swp2 swp3"
'<ipv4/prefixlen>'
'<ipv6/prefixlen>'
'<ipaddr/prefixlen>'
'<number-range-list>': example: "2000 2200-3000"
'<interface-range-list>': example: "swp1=100 swp2=100" ('validrange' : ['0', '65535'])
'<mac-ipaddr/prefixlen-list>'
'<number-interface-list>': example: "4 swp1 swp2"
'<interface-yes-no-list>': example: "swp1=yes swp2=no"
'<interface-yes-no-0-1-list>'
'<interface-yes-no-auto-list>'
It's possible to combine a keyword with a range from validrange. example:
validrange: 10-50
validvals: <intrface-range-list>
value: swp1=21 swp2=42 ...
Signed-off-by: Julien Fortin <julien@cumulusnetworks.com>
		
	
		
			
				
	
	
		
			172 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| #
 | |
| # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
 | |
| # Author: Roopa Prabhu, roopa@cumulusnetworks.com
 | |
| #
 | |
| 
 | |
| try:
 | |
|     from ipaddr import IPNetwork
 | |
|     from sets import Set
 | |
|     from ifupdown.iface import *
 | |
|     from ifupdown.utils import utils
 | |
|     from ifupdownaddons.modulebase import moduleBase
 | |
|     from ifupdownaddons.iproute2 import iproute2
 | |
|     import ifupdown.ifupdownflags as ifupdownflags
 | |
|     import os
 | |
|     import glob
 | |
|     import logging
 | |
|     import signal
 | |
|     import re
 | |
| except ImportError, e:
 | |
|     raise ImportError (str(e) + "- required module not found")
 | |
| 
 | |
| class vrrpd(moduleBase):
 | |
|     """  ifupdown2 addon module to configure vrrpd attributes """
 | |
| 
 | |
|     _modinfo = {'mhelp' : 'ethtool configuration module for interfaces',
 | |
|                 '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' : ['<ipv4>', ],
 | |
|                              'example' : ['vrrp-virtual-ip 10.0.1.254']}}}
 | |
| 
 | |
|     def __init__(self, *args, **kargs):
 | |
|         moduleBase.__init__(self, *args, **kargs)
 | |
|         self.ipcmd = None
 | |
| 
 | |
|     def _check_if_process_is_running(self, cmdname, cmdline):
 | |
|         targetpids = []
 | |
|         pidstr = ''
 | |
|         try:
 | |
|             cmdl = ['/bin/pidof', cmdname]
 | |
|             pidstr = utils.exec_commandl(cmdl, stderr=None).strip('\n')
 | |
|         except:
 | |
|             pass
 | |
|         if not pidstr:
 | |
|            return []
 | |
| 
 | |
|         pids = pidstr.split()
 | |
|         if not pids:
 | |
|            return targetpids
 | |
|         for pid in pids:
 | |
|             tmpcmdline = cmdline.replace(' ', '')
 | |
|             try:
 | |
|                 pcmdline = self.read_file_oneline('/proc/%s/cmdline' %pid)
 | |
|                 pcmdline = re.sub(r'\\(.)', r'\1', pcmdline)
 | |
|                 self.logger.info('(%s)' %(pcmdline))
 | |
|                 self.logger.info('(%s)' %(tmpcmdline))
 | |
|                 self.logger.info('(%d) (%d)' %(len(pcmdline), len(tmpcmdline)))
 | |
|                 if pcmdline and pcmdline == tmpcmdline:
 | |
|                    targetpids.append(pid)
 | |
|             except:
 | |
|                 pass
 | |
|         return targetpids
 | |
|             
 | |
|     def _up(self, ifaceobj):
 | |
|         """ up vrrpd -n -D -i $IFACE -v 1 -p 20 10.0.1.254
 | |
|             up ifplugd -i $IFACE -b -f -u0 -d1 -I -p -q """
 | |
| 
 | |
|         if (not ifupdownflags.flags.DRYRUN and
 | |
|             not os.path.exists('/sys/class/net/%s' %ifaceobj.name)):
 | |
|             return
 | |
| 
 | |
|         cmd = ''
 | |
|         attrval = ifaceobj.get_attr_value_first('vrrp-id')
 | |
|         if attrval:
 | |
|             cmd += ' -v %s' %attrval
 | |
|         else:
 | |
|             return
 | |
|         attrval = ifaceobj.get_attr_value_first('vrrp-priority')
 | |
|         if attrval:
 | |
|             cmd += ' -p %s' %attrval
 | |
|         else:
 | |
|             self.logger.warn('%s: incomplete vrrp parameters ' %ifaceobj.name,
 | |
|                     '(priority not found)')
 | |
|         attrval = ifaceobj.get_attr_value_first('vrrp-virtual-ip')
 | |
|         if attrval:
 | |
|             cmd += ' %s' %attrval
 | |
|         else:
 | |
|             self.logger.warn('%s: incomplete vrrp arguments ' %ifaceobj.name,
 | |
|                     '(virtual ip not found)')
 | |
|             return
 | |
|         cmd = '/usr/sbin/vrrpd -n -D -i %s %s' %(ifaceobj.name, cmd)
 | |
|         utils.exec_command(cmd)
 | |
| 
 | |
|         cmd = '/usr/sbin/ifplugd -i %s -b -f -u0 -d1 -I -p -q' %ifaceobj.name
 | |
|         if self._check_if_process_is_running('/usr/sbin/ifplugd', cmd):
 | |
|            self.logger.info('%s: ifplugd already running' %ifaceobj.name)
 | |
|            return
 | |
|         utils.exec_command(cmd)
 | |
| 
 | |
|     def _kill_pid_from_file(self, pidfilename):
 | |
|         if os.path.exists(pidfilename):
 | |
|             pid = self.read_file_oneline(pidfilename)
 | |
|             if os.path.exists('/proc/%s' %pid):
 | |
|                os.kill(int(pid), signal.SIGTERM)
 | |
| 
 | |
|     def _down(self, ifaceobj):
 | |
|         """ down ifplugd -k -i $IFACE
 | |
|              down kill $(cat /var/run/vrrpd_$IFACE_*.pid) """
 | |
|         attrval = ifaceobj.get_attr_value_first('vrrp-id')
 | |
|         if not attrval:
 | |
|             return
 | |
|         try:
 | |
|             utils.exec_command('/usr/sbin/ifplugd -k -i %s' % ifaceobj.name)
 | |
|         except Exception, e:
 | |
|             self.logger.debug('%s: ifplugd down error (%s)'
 | |
|                               %(ifaceobj.name, str(e)))
 | |
|             pass
 | |
| 
 | |
|         for pidfile in glob.glob('/var/run/vrrpd_%s_*.pid' %ifaceobj.name):
 | |
|             try:
 | |
|                 self._kill_pid_from_file(pidfile)
 | |
|             except Exception, e:
 | |
|                 self.logger.debug('%s: vrrpd down error (%s)'
 | |
|                                   %(ifaceobj.name, str(e)))
 | |
|                 pass
 | |
| 
 | |
|     def _query_check(self, ifaceobj, ifaceobjcurr):
 | |
|         # XXX
 | |
|         return
 | |
| 
 | |
| 
 | |
|     _run_ops = {'post-up' : _up,
 | |
|                 'pre-down' : _down}
 | |
| 
 | |
|     def get_ops(self):
 | |
|         """ returns list of ops supported by this module """
 | |
|         return self._run_ops.keys()
 | |
| 
 | |
|     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
 | |
|         """ run ethtool configuration on the interface object passed as
 | |
|             argument
 | |
| 
 | |
|         Args:
 | |
|             **ifaceobj** (object): iface object
 | |
| 
 | |
|             **operation** (str): any of 'post-up', 'query-checkcurr',
 | |
|                 'query-running'
 | |
|         Kwargs:
 | |
|             **query_ifaceobj** (object): query check ifaceobject. This is only
 | |
|                 valid when op is 'query-checkcurr'. It is an object same as
 | |
|                 ifaceobj, but contains running attribute values and its config
 | |
|                 status. The modules can use it to return queried running state
 | |
|                 of interfaces. status is success if the running state is same
 | |
|                 as user required state in ifaceobj. error otherwise.
 | |
|         """
 | |
|         op_handler = self._run_ops.get(operation)
 | |
|         if not op_handler:
 | |
|             return
 | |
|         if operation == 'query-checkcurr':
 | |
|             op_handler(self, ifaceobj, query_ifaceobj)
 | |
|         else:
 | |
|             op_handler(self, ifaceobj)
 |