From: Ondrej Lichtner <olichtne(a)redhat.com>
This commit adds functions verify_ip_address and verify_mac_address that
return a boolean value depending on the validity of given ip or mac
addresses.
These will be used in the new Config parsing module.
I also added their usage to the address generation code in the same
module.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
Common/NetUtils.py | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/Common/NetUtils.py b/Common/NetUtils.py
index 8594a23..d7db077 100644
--- a/Common/NetUtils.py
+++ b/Common/NetUtils.py
@@ -37,6 +37,21 @@ def scan_netdevs():
scan.append({"name": d, "hwaddr": addr})
return scan
+def verify_ip_address(addr):
+ if len(addr.split('.')) != 4:
+ return False
+ try:
+ socket.inet_aton(addr)
+ return True
+ except:
+ return False
+
+def verify_mac_address(addr):
+ if re.match("^[0-9a-f]{2}([:][0-9a-f]{2}){5}$", addr, re.I):
+ return True
+ else:
+ return False
+
def get_corespond_local_ip(query_ip):
"""
Get ip address in local system which can communicate with query_ip.
@@ -85,10 +100,10 @@ class AddressPool:
class MacPool(AddressPool):
def _addr_to_byte_string(self, addr):
- bs = [int(byte, 16) for byte in addr.split(":")]
+ if not verify_mac_address(addr):
+ raise Exception("Invalid MAC address")
- if len(bs) != 6:
- raise Exception("Malformed MAC address")
+ bs = [int(byte, 16) for byte in addr.split(":")]
return bs
@@ -97,10 +112,10 @@ class MacPool(AddressPool):
class IpPool(AddressPool):
def _addr_to_byte_string(self, addr):
- bs = [int(byte) for byte in addr.split(".")]
+ if not verify_ip_address(addr):
+ raise Exception("Invalid IP address")
- if len(bs) != 4:
- raise Exception("Malformed IP address")
+ bs = [int(byte) for byte in addr.split(".")]
return bs
--
1.7.11.4
Show replies by thread
From: Ondrej Lichtner <olichtne(a)redhat.com>
This patch adds a module for parsing config files.
The class Config uses the module ConfigParser for parsing .ini files.
Parsed data is then read and checked for invalid sections, options or
option values.
The main method for this class is load_config() where we check for
invalid sections. Next in methods section*() we check for invalid
options. Finally values are checked in methods option*().
Correctly parsed options are stored in a dictionary
options[section][option].
It is important to add that parts of this class are not fully complete
and it is highly possible more sections/options will be added during the
process of integrating this class with the rest of the project.
For the same reason some option methods are there only as place holders
until they can be fully implemented.
Default values should be stored in a separate config file. For now I am
using default.conf that is located in the main project directory. I
don't know if this is the best way so I am not including this file in
this commit.
Currently the accepted configuration files are of this format, you can
use this as the default.conf file:
[environment]
mac_pool_range = 52:54:01:00:00:01 52:54:01:FF:FF:FF
rpcport = 9001
[log]
local_ip = 127.0.0.1
port = 9000
log_path = ~/.lnst/logs
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
Common/Config.py | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
create mode 100644 Common/Config.py
diff --git a/Common/Config.py b/Common/Config.py
new file mode 100644
index 0000000..8a1ad56
--- /dev/null
+++ b/Common/Config.py
@@ -0,0 +1,115 @@
+"""
+Module containing class used for loading config files.
+
+Copyright 2012 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__autor__ = """
+olichtne(a)redhat.com (Ondrej Lichtner)
+"""
+
+import os
+import logging
+from ConfigParser import ConfigParser
+from NetUtils import verify_ip_address, verify_mac_address
+
+class ConfigError(Exception):
+ pass
+
+class Config():
+ options = None
+ _parser = None
+
+ def __init__(self):
+ self._parser = ConfigParser(dict_type=dict)
+
+ # defaults.conf should contain all possible sections and options
+ # sections and options not listed there will be undefined which
+ # can cause problems
+ self.options = dict()
+ self.load_config("default.conf")
+
+ def get_config(self):
+ return self.options
+
+ def get_section(self, section):
+ return self.options[section]
+
+ def get_option(self, section, option):
+ return self.options[section][option]
+
+ def load_config(self, path):
+ '''Parse and load the config file'''
+ self._parser.read(path)
+
+ sections = self._parser._sections
+ for section in sections:
+ if section == "log":
+ self.sectionLogs(sections[section])
+ elif section == "environment":
+ self.sectionEnvironment(sections[section])
+ else:
+ msg = "Unknown section: %s" % section
+ raise ConfigError(msg)
+
+ def sectionLogs(self, config):
+ if 'log' not in self.options:
+ self.options['log'] = dict()
+ section = self.options['log']
+
+ config.pop('__name__', None)
+ for option in config:
+ if option == 'local_ip':
+ section['local_ip'] = self.optionLocalIP(config[option])
+ elif option == 'port':
+ section['port'] = self.optionPort(config[option])
+ elif option == 'path':
+ section['path'] = self.optionLogPath(config[option])
+ else:
+ msg = "Unknown option: %s in section log" % option
+ raise ConfigError(msg)
+
+ def sectionEnvironment(self, config):
+ if 'environment' not in self.options:
+ self.options['environment'] = dict()
+ section = self.options['environment']
+
+ config.pop('__name__', None)
+ for option in config:
+ if option == 'mac_pool_range':
+ section['mac_pool_range'] = self.optionMacRange(config[option])
+ elif option == 'rpcport':
+ section['rpcport'] = self.optionPort(config[option])
+ else:
+ msg = "Unknown option: %s in section environment" % option
+ raise ConfigError(msg)
+
+ def optionLocalIP(self, option):
+ if not verify_ip_address(option):
+ msg = "Invalid IP address: %s" % option
+ raise ConfigError(msg)
+ return option
+
+ def optionPort(self, option):
+ try:
+ int(option)
+ except ValueError:
+ msg = "Option port expects a number."
+ raise ConfigError(msg)
+ return int(option)
+
+ def optionLogPath(self, option):
+ return option
+
+ def optionMacRange(self, option):
+ vals = option.split()
+ if len(vals) != 2:
+ msg = "Option mac_pool_range expects 2"\
+ " values sepparated by whitespaces."
+ raise ConfigError(msg)
+ if not verify_mac_address(option):
+ msg = "Invalid MAC address: %s" % option
+ raise ConfigError(msg)
+ return vals
--
1.7.11.4