forked from ftao/python-ifcfg
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
BJ Dierkes
committed
Jun 5, 2012
1 parent
cb1d59e
commit 9becf7c
Showing
7 changed files
with
260 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
|
||
Copyright (c) 2012, BJ Dierkes | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, | ||
this list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
* Neither the name of BJ Dierkes nor the names of his contributors | ||
may be used to endorse or promote products derived from this software | ||
without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,35 @@ | ||
python-ifcfg | ||
============ | ||
Python Wrapper Around the Ifconfig Utility on Unix/Linux/MacOSX | ||
============================================================================= | ||
|
||
Python Wrapper Around the Ifconfig Utility on Unix/Linux/MacOSX | ||
Ifcfg is a cross-platform (*nix) library for parsing 'ifconfig' output in | ||
Python. It is useful for pulling information such as IP, Netmask, MAC Address, | ||
Hostname, etc. | ||
|
||
Some Limitations: | ||
|
||
* Targeted for Unix-like operating systems including Linux and Mac OSX | ||
* Relies on parsing 'ifconfig' output | ||
|
||
|
||
Usage | ||
----- | ||
|
||
import ifcfg | ||
parser = ifcfg.parse() | ||
|
||
for interface in parser.interfaces: | ||
print interface['name'] | ||
print interface['ether'] | ||
print interface['inet'] | ||
print interface['inet6] | ||
print interface['netmask'] | ||
print interface['flags'] | ||
print interface['hostname'] | ||
print interface['mtu'] | ||
|
||
|
||
License | ||
------- | ||
|
||
The dRest library is Open Source and is distributed under the BSD License | ||
(three clause). Please see the LICENSE file included with this software. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
|
||
import platform | ||
|
||
def parse(parser=None): | ||
if not parser: | ||
s = platform.system() | ||
if s == 'Linux': | ||
from .parser import LinuxParser | ||
parser = LinuxParser() | ||
elif s == 'Darwin': | ||
from .parser import MacOSXParser | ||
parser = MacOSXParser() | ||
else: | ||
raise IfcfgParserError("Unknown system type '%s'." % s) | ||
|
||
return parser | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""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__() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
|
||
import re | ||
import socket | ||
|
||
from .meta import MetaMixin | ||
from .tools import exec_cmd, hex2dotted | ||
|
||
class IfcfgParser(MetaMixin): | ||
class Meta: | ||
ifconfig_cmd_args = ['ifconfig', '-a'] | ||
patterns = [ | ||
'(?P<name>^[a-zA-Z0-9]+): flags=(?P<flags>.*) mtu (?P<mtu>.*)', | ||
'.*(inet )(?P<inet>[^\s]*).*', | ||
'.*(inet6 )(?P<inet6>[^\s]*).*', | ||
'.*(broadcast )(?P<broadcast>[^\s]*).*', | ||
'.*(netmask )(?P<netmask>[^\s]*).*', | ||
'.*(ether )(?P<ether>[^\s]*).*', | ||
'.*(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 = None | ||
self.parse() | ||
|
||
def _get_patterns(self): | ||
return self._meta.patterns + self._meta.override_patterns | ||
|
||
def parse(self): | ||
_interfaces = {} | ||
out, err, retcode = exec_cmd(self._meta.ifconfig_cmd_args) | ||
self.ifconfig_data = out | ||
cur = None | ||
all_keys = [] | ||
|
||
for line in self.ifconfig_data.splitlines(): | ||
for pattern in self._get_patterns(): | ||
m = re.match(pattern, line) | ||
if m: | ||
groupdict = m.groupdict() | ||
# Special treatment to trigger which interface we're | ||
# setting for if 'name' is in the line. Presumably the | ||
# name of the interface is within the first line of the | ||
# device block. | ||
if 'name' in groupdict: | ||
cur = groupdict['name'] | ||
if not self._interfaces.has_key(cur): | ||
self._interfaces[cur] = {} | ||
|
||
for key in groupdict: | ||
if key not in all_keys: | ||
all_keys.append(key) | ||
self._interfaces[cur][key] = groupdict[key] | ||
|
||
# fixup some things | ||
for device,device_dict in self.interfaces.items(): | ||
if 'inet' in device_dict: | ||
try: | ||
host = socket.gethostbyaddr(device_dict['inet'])[0] | ||
self.interfaces[device]['hostname'] = host | ||
except socket.herror as e: | ||
self.interfaces[device]['hostname'] = None | ||
|
||
# standardize | ||
for key in all_keys: | ||
for device,device_dict in self.interfaces.items(): | ||
if key not in device_dict: | ||
self.interfaces[device][key] = None | ||
if type(device_dict[key]) == str: | ||
self.interfaces[device][key] = device_dict[key].lower() | ||
|
||
|
||
def interface_names(self): | ||
names = [] | ||
for line in self.ifconfig_data.splitlines(): | ||
m = re.match(self._meta.re_name, line) | ||
if m: | ||
names.append(m.group(1)) | ||
return names | ||
|
||
@property | ||
def interfaces(self): | ||
return self._interfaces | ||
|
||
class UnixParser(IfcfgParser): | ||
def __init__(self, *args, **kw): | ||
super(UnixParser, self).__init__(*args, **kw) | ||
|
||
class LinuxParser(UnixParser): | ||
def __init__(self, *args, **kw): | ||
super(LinuxParser, self).__init__(*args, **kw) | ||
|
||
class MacOSXParser(UnixParser): | ||
class Meta: | ||
override_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) | ||
|
||
# fix up netmask address for mac | ||
for device,device_dict in self.interfaces.items(): | ||
if device_dict['netmask'] is not None: | ||
netmask = self.interfaces[device]['netmask'] | ||
self.interfaces[device]['netmask'] = hex2dotted(netmask) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
|
||
from subprocess import Popen, PIPE | ||
|
||
def exec_cmd(cmd_args): | ||
proc = Popen(cmd_args, stdout=PIPE, stderr=PIPE) | ||
(stdout, stderr) = proc.communicate() | ||
proc.wait() | ||
return (stdout, stderr, proc.returncode) | ||
|
||
def hex2dotted(hex_num): | ||
num = hex_num.split('x')[1] | ||
w = int(num[0:2], 16) | ||
x = int(num[2:4], 16) | ||
y = int(num[4:6], 16) | ||
z = int(num[6:8], 16) | ||
|
||
return "%d.%d.%d.%d" % (w, x, y, z) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
import ifcfg | ||
import json | ||
|
||
i = ifcfg.parse() | ||
print json.dumps(i.interfaces) |