Skip to content

Commit

Permalink
Merge pull request #5 from learningequality/rm-metaclass-pattern
Browse files Browse the repository at this point in the history
[WIP] Minimally intrusive removal of metaclass pattern
  • Loading branch information
benjaoming authored May 11, 2017
2 parents 141caca + 7f750ab commit f33de35
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 116 deletions.
26 changes: 14 additions & 12 deletions ifcfg/__init__.py
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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]
Expand All @@ -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():
"""
Expand Down
44 changes: 0 additions & 44 deletions ifcfg/meta.py

This file was deleted.

83 changes: 40 additions & 43 deletions ifcfg/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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<device>^[a-zA-Z0-9]+): flags=(?P<flags>.*) mtu (?P<mtu>.*)',
'.*(inet )(?P<inet>[^\s]*).*',
'.*(inet6 )(?P<inet6>[^\s]*).*',
Expand All @@ -27,18 +37,7 @@ class Meta:
'.*(prefixlen )(?P<prefixlen>[^\s]*).*',
'.*(scopeid )(?P<scopeid>[^\s]*).*',
'.*(ether )(?P<ether>[^\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):
"""
Expand All @@ -48,20 +47,20 @@ 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
cur = 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()
Expand Down Expand Up @@ -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
Expand All @@ -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':
Expand All @@ -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<device>^[a-zA-Z0-9:]+)(.*)Link encap:(.*).*',
'(.*)Link encap:(.*)(HWaddr )(?P<ether>[^\s]*).*',
'.*(inet addr:)(?P<inet>[^\s]*).*',
Expand All @@ -159,32 +159,33 @@ class Meta:
'.*(Scope:)(?P<scopeid>[^\s]*).*',
'.*(RX bytes:)(?P<rxbytes>\d+).*',
'.*(TX bytes:)(?P<txbytes>\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<device>[a-zA-Z0-9]+):.*mtu (?P<mtu>.*)',
'.*(inet )(?P<inet>[^/]+).*',
'.*(inet6 )(?P<inet6>[^/]*).*',
Expand All @@ -194,21 +195,17 @@ class Meta:
#'.*(prefixlen )(?P<prefixlen>[^\s]*).*',
#'.*(scopeid )(?P<scopeid>[^\s]*).*',
#'.*(ether )(?P<ether>[^\s]*).*',
]

override_patterns = []

]


class MacOSXParser(UnixParser):
class Meta:
override_patterns = [

@classmethod
def get_patterns(cls):
return super(MacOSXParser, cls).get_patterns() + [
'.*(status: )(?P<status>[^\s]*).*',
'.*(media: )(?P<media>.*)',
]

def __init__(self, *args, **kw):
super(MacOSXParser, self).__init__(*args, **kw)
]

def parse(self, *args, **kw):
super(MacOSXParser, self).parse(*args, **kw)
Expand Down
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -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=[],
Expand Down
15 changes: 0 additions & 15 deletions tests/meta_tests.py

This file was deleted.

0 comments on commit f33de35

Please sign in to comment.