diff --git a/ifcfg/__init__.py b/ifcfg/__init__.py index 0650698..2b2a476 100644 --- a/ifcfg/__init__.py +++ b/ifcfg/__init__.py @@ -1,13 +1,15 @@ import os import platform import re -from . import meta from . import parser from . import tools from . import exc +__version__ = "0.10.1" + Log = tools.minimal_logger(__name__) + def get_parser(**kw): """ Detect the proper parser class, and return it instantiated. @@ -27,9 +29,9 @@ def get_parser(**kw): The ifconfig (stdout) to pass to the parser (used for testing). """ - parser = kw.get('parser', None) + Parser = kw.get('parser', None) ifconfig = kw.get('ifconfig', None) - if not parser: + if not Parser: distro = kw.get('distro', platform.system()) full_kernel = kw.get('kernel', platform.uname()[2]) split_kernel = full_kernel.split('.')[0:2] @@ -42,24 +44,24 @@ def get_parser(**kw): if distro == 'Linux': if kernel_version < 3 and kernel_major_rev < 3: - from .parser import Linux2Parser as LinuxParser + from .parser import Linux2Parser + Parser = Linux2Parser else: from .parser import LinuxParser - parser = LinuxParser(ifconfig=ifconfig) + Parser = LinuxParser elif distro in ['Darwin', 'MacOSX']: from .parser import MacOSXParser - parser = MacOSXParser(ifconfig=ifconfig) + Parser = MacOSXParser else: raise exc.IfcfgParserError("Unknown distro type '%s'." % distro) Log.debug("Distro detected as '%s'" % distro) - Log.debug("Using '%s'" % parser) - if not os.path.exists(parser._meta.ifconfig_cmd): + Log.debug("Using '%s'" % Parser) + if not os.path.exists(Parser.get_command()[0]): Log.debug("Could not find 'ifconfig' cmd, falling back to 'ip' cmd") from .parser import UnixIPParser - parser = UnixIPParser(ifconfig=ifconfig) - else: - parser = parser(ifconfig=ifconfig) - return parser + Parser = UnixIPParser + + return Parser(ifconfig=ifconfig) def interfaces(): """ diff --git a/ifcfg/meta.py b/ifcfg/meta.py deleted file mode 100644 index be494a9..0000000 --- a/ifcfg/meta.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Ifcfg core meta functionality. Barrowed from http://slumber.in/.""" - -class Meta(object): - """ - Model that acts as a container class for a meta attributes for a larger - class. It stuffs any kwarg it gets in it's init as an attribute of itself. - - """ - - def __init__(self, **kw): - self._merge(kw) - - def _merge(self, dict_obj): - for key, value in dict_obj.items(): - setattr(self, key, value) - -class MetaMixin(object): - """ - Mixin that provides the Meta class support to add settings to instances - of slumber objects. Meta settings cannot start with a _. - - """ - - def __init__(self, *args, **kw): - # Get a List of all the Classes we in our MRO, find any attribute named - # Meta on them, and then merge them together in order of MRO - metas = reversed([x.Meta for x in self.__class__.mro() \ - if hasattr(x, "Meta")]) - final_meta = {} - - # Merge the Meta classes into one dict - for meta in metas: - final_meta.update(dict([x for x in list(meta.__dict__.items()) \ - if not x[0].startswith("_")])) - - # Update the final Meta with any kw passed in - for key in list(final_meta.keys()): - if key in kw: - final_meta[key] = kw.pop(key) - - self._meta = Meta(**final_meta) - - # FIX ME: object.__init__() doesn't take params without exception - super(MetaMixin, self).__init__() \ No newline at end of file diff --git a/ifcfg/parser.py b/ifcfg/parser.py index 173c95d..7c065a2 100644 --- a/ifcfg/parser.py +++ b/ifcfg/parser.py @@ -3,21 +3,31 @@ import re import socket -from .meta import MetaMixin from .tools import exec_cmd, hex2dotted, minimal_logger Log = minimal_logger(__name__) -class IfcfgParser(MetaMixin): - class Meta: +class IfcfgParser(object): + + def __init__(self, *args, **kw): + self._interfaces = {} + self.ifconfig_data = kw.get('ifconfig', None) + self.encoding = kw.get('encoding', 'latin1') + self.parse(self.ifconfig_data) + + @classmethod + def get_command(cls): ifconfig_cmd = 'ifconfig' for path in ['/sbin','/usr/sbin','/bin','/usr/bin']: if os.path.exists(os.path.join(path, ifconfig_cmd)): ifconfig_cmd = os.path.join(path, ifconfig_cmd) break - ifconfig_cmd_args = [ifconfig_cmd, '-a'] - patterns = [ + return [ifconfig_cmd, '-a'] + + @classmethod + def get_patterns(cls): + return [ '(?P^[a-zA-Z0-9]+): flags=(?P.*) mtu (?P.*)', '.*(inet )(?P[^\s]*).*', '.*(inet6 )(?P[^\s]*).*', @@ -27,18 +37,7 @@ class Meta: '.*(prefixlen )(?P[^\s]*).*', '.*(scopeid )(?P[^\s]*).*', '.*(ether )(?P[^\s]*).*', - ] - override_patterns = [] - - def __init__(self, *args, **kw): - super(IfcfgParser, self).__init__(*args, **kw) - self._interfaces = {} - self.ifconfig_data = kw.get('ifconfig', None) - self.encoding = kw.get('encoding', 'latin1') - self.parse(self.ifconfig_data) - - def _get_patterns(self): - return self._meta.patterns + self._meta.override_patterns + ] def parse(self, ifconfig=None): """ @@ -48,12 +47,12 @@ def parse(self, ifconfig=None): ifconfig The data (stdout) from the ifconfig command. Default is to - call self._meta.ifconfig_cmd_args for the stdout. + call exec_cmd(self.get_command()). """ _interfaces = [] if not ifconfig: - ifconfig, err, retcode = exec_cmd(self._meta.ifconfig_cmd_args) + ifconfig, __, __ = exec_cmd(self.get_command()) if hasattr(ifconfig, 'decode'): ifconfig = ifconfig.decode(self.encoding) self.ifconfig_data = ifconfig @@ -61,7 +60,7 @@ def parse(self, ifconfig=None): all_keys = [] for line in self.ifconfig_data.splitlines(): - for pattern in self._get_patterns(): + for pattern in self.get_patterns(): m = re.match(pattern, line) if m: groupdict = m.groupdict() @@ -110,7 +109,7 @@ def alter(self, interfaces): try: host = socket.gethostbyaddr(device_dict['inet'])[0] interfaces[device]['hostname'] = host - except socket.herror as e: + except socket.herror: interfaces[device]['hostname'] = None return interfaces @@ -129,7 +128,7 @@ def default_interface(self): Returns the default interface device. """ - out, err, ret = exec_cmd(['/sbin/route', '-n']) + out, __, __ = exec_cmd(['/sbin/route', '-n']) lines = out.splitlines() for line in lines[2:]: if line.split()[0] == '0.0.0.0': @@ -147,8 +146,9 @@ def __init__(self, *args, **kw): class LinuxParser(UnixParser): - class Meta: - override_patterns = [ + @classmethod + def get_patterns(cls): + return super(LinuxParser, cls).get_patterns() + [ '(?P^[a-zA-Z0-9:]+)(.*)Link encap:(.*).*', '(.*)Link encap:(.*)(HWaddr )(?P[^\s]*).*', '.*(inet addr:)(?P[^\s]*).*', @@ -159,32 +159,33 @@ class Meta: '.*(Scope:)(?P[^\s]*).*', '.*(RX bytes:)(?P\d+).*', '.*(TX bytes:)(?P\d+).*', - ] - - def __init__(self, *args, **kw): - super(LinuxParser, self).__init__(*args, **kw) + ] def alter(self, interfaces): return interfaces class Linux2Parser(LinuxParser): - def __init__(self, *args, **kw): - super(Linux2Parser, self).__init__(*args, **kw) + pass class UnixIPParser(IfcfgParser): """ Because ifconfig is getting deprecated, we can use ip address instead """ - class Meta: + + @classmethod + def get_command(cls): ifconfig_cmd = 'ip' for path in ['/sbin','/usr/sbin','/bin','/usr/bin']: if os.path.exists(os.path.join(path, ifconfig_cmd)): ifconfig_cmd = os.path.join(path, ifconfig_cmd) break - ifconfig_cmd_args = [ifconfig_cmd, 'address', 'show'] - patterns = [ + return [ifconfig_cmd, 'address', 'show'] + + @classmethod + def get_patterns(cls): + return [ '\s*[0-9]+:\s+(?P[a-zA-Z0-9]+):.*mtu (?P.*)', '.*(inet )(?P[^/]+).*', '.*(inet6 )(?P[^/]*).*', @@ -194,21 +195,17 @@ class Meta: #'.*(prefixlen )(?P[^\s]*).*', #'.*(scopeid )(?P[^\s]*).*', #'.*(ether )(?P[^\s]*).*', - ] - - override_patterns = [] - + ] class MacOSXParser(UnixParser): - class Meta: - override_patterns = [ + + @classmethod + def get_patterns(cls): + return super(MacOSXParser, cls).get_patterns() + [ '.*(status: )(?P[^\s]*).*', '.*(media: )(?P.*)', - ] - - def __init__(self, *args, **kw): - super(MacOSXParser, self).__init__(*args, **kw) + ] def parse(self, *args, **kw): super(MacOSXParser, self).parse(*args, **kw) diff --git a/setup.py b/setup.py index 018b917..9e757c4 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,11 @@ from setuptools import setup, find_packages -import sys, os + +import ifcfg setup( name='ifcfg', - version='0.10', + version=ifcfg.__version__, description="Python Ifconfig Wrapper for Unix/Linux/MacOSX", long_description="Python Ifconfig Wrapper for Unix/Linux/MacOSX", classifiers=[], diff --git a/tests/meta_tests.py b/tests/meta_tests.py deleted file mode 100644 index 71c04a9..0000000 --- a/tests/meta_tests.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Tests for ifcfg.meta.""" - -from nose.tools import eq_ -import ifcfg - -class Test(ifcfg.meta.MetaMixin): - class Meta: - some_param = None - - def __init__(self, **kw): - super(Test, self).__init__(**kw) - -def test_meta(): - test = Test(some_param='some_value') - eq_(test._meta.some_param, 'some_value') \ No newline at end of file