X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Futil%2Fconfig.py;h=c25ec4422184867a69a690a4ca1e33ad2bbdfa50;hb=f9ca4f5241efee10e93801df459e0b764cc0d912;hp=cef2fdd8b0d68e538ba6a0baba519477dc429bdf;hpb=f13173726f8382eef380f1e754f24dd2b126a77b;p=sfa.git diff --git a/sfa/util/config.py b/sfa/util/config.py index cef2fdd8..c25ec442 100644 --- a/sfa/util/config.py +++ b/sfa/util/config.py @@ -1,101 +1,311 @@ -## -# Geniwrapper Configuration Info -# -# This module holds configuration parameters for geniwrapper. There are two -# main pieces of information that are used: the database connection and -# the PLCAPI connection -## +#!/usr/bin/python +import sys +import os +import time +import ConfigParser +import tempfile +import codecs +from StringIO import StringIO +from sfa.util.xml import XML -## -# Geniwrapper uses a MYSQL database to store records. This database may be -# co-located with the PLC database, or it may be a separate database. The -# following parameters define the connection to the database. -# -# Note that Geniwrapper does not access any of the PLC databases directly via -# a mysql connection; All PLC databases are accessed via PLCAPI. +default_config = \ +""" +""" -### $Id$ -### $URL$ +def isbool(v): + return v.lower() in ("true", "false") -import os.path -import traceback +def str2bool(v): + return v.lower() in ("true", "1") -from sfa.util.debug import log +class Config: + + def __init__(self, config_file='/etc/sfa/sfa_config'): + self._files = [] + self.config_path = os.path.dirname(config_file) + self.config = ConfigParser.ConfigParser() + self.filename = config_file + if not os.path.isfile(self.filename): + self.create(self.filename) + self.load(self.filename) + -# xxx the path-search part could use a cleanup; -# why would anyone want to store the config in /usr/share/geniwrapper at all ? -# also, if users want to use this, it might help to store stuff in ~/.sfirc or something + def _header(self): + header = """ +DO NOT EDIT. This file was automatically generated at +%s from: -# this would denote "/usr/share/geniwrapper/geni" -# geni = join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "geni") +%s +""" % (time.asctime(), os.linesep.join(self._files)) -class Config: - """ - Parse the bash/Python/PHP version of the configuration file. Very - fast but no type conversions. - """ - - def __init__(self, filepath = "/etc/sfa/sfa_config"): - # Load plc_config - - loaded = False - # path to config.py source - this would be '/usr/share/geniwrapper/geni/util' - path = os.path.dirname(os.path.abspath(__file__)) - # parent directory of config.py source - self.basepath = os.path.dirname(path) - # path to actual config file - filename = os.path.basename(filepath) - alt_file = os.path.join(path, 'util', filename) - files = [filepath, alt_file] - - for config_file in files: + # Get rid of the surrounding newlines + return header.strip().split(os.linesep) + + def create(self, filename): + if not os.path.exists(os.path.dirname(filename)): + os.makedirs(os.path.dirname(filename)) + configfile = open(filename, 'w') + configfile.write(default_config) + configfile.close() + + + def load(self, filename): + if filename: + try: + self.config.read(filename) + except ConfigParser.MissingSectionHeaderError: + if filename.endswith('.xml'): + self.load_xml(filename) + else: + self.load_shell(filename) + self._files.append(filename) + self.set_attributes() + + def load_xml(self, filename): + xml = XML(filename) + categories = xml.xpath('//configuration/variables/category') + for category in categories: + section_name = category.get('id') + if not self.config.has_section(section_name): + self.config.add_section(section_name) + options = category.xpath('./variablelist/variable') + for option in options: + option_name = option.get('id') + value = option.xpath('./value')[0].text + if not value: + value = "" + self.config.set(section_name, option_name, value) + + def load_shell(self, filename): + f = open(filename, 'r') + for line in f: try: - execfile(config_file, self.__dict__) - loaded = True - self.config_file = config_file - self.config_path = os.path.dirname(config_file) - break + if line.startswith('#'): + continue + parts = line.strip().split("=") + if len(parts) < 2: + continue + option = parts[0] + value = parts[1].replace('"', '').replace("'","") + section, var = self.locate_varname(option, strict=False) + if section and var: + self.set(section, var, value) except: pass + f.close() + + def locate_varname(self, varname, strict=True): + varname = varname.lower() + sections = self.config.sections() + section_name = "" + var_name = "" + for section in sections: + if varname.startswith(section.lower()) and len(section) > len(section_name): + section_name = section.lower() + var_name = varname.replace(section_name, "")[1:] + if strict and not self.config.has_option(section_name, var_name): + raise ConfigParser.NoOptionError(var_name, section_name) + return (section_name, var_name) + + def set_attributes(self): + sections = self.config.sections() + for section in sections: + for item in self.config.items(section): + name = "%s_%s" % (section, item[0]) + value = item[1] + if isbool(value): + value = str2bool(value) + elif value.isdigit(): + value = int(value) + setattr(self, name, value) + setattr(self, name.upper(), value) + + def variables(self): + """ + Return all variables. + + Returns: - if not loaded: - raise Exception, "Could not find config in " + ", ".join(files) + variables = { 'category_id': (category, variablelist) } - # set up some useful variables + category = { 'id': "category_identifier", + 'name': "Category name", + 'description': "Category description" } - def load(self, filepath): + variablelist = { 'variable_id': variable } + + variable = { 'id': "variable_identifier", + 'type': "variable_type", + 'value': "variable_value", + 'name': "Variable name", + 'description': "Variable description" } + """ + + variables = {} + for section in self.config.sections(): + category = { + 'id': section, + 'name': section, + 'description': section, + } + variable_list = {} + for item in self.config.items(section): + var_name = item[0] + name = "%s_%s" % (section, var_name) + value = item[1] + if isbool(value): + value_type = bool + elif value.isdigit(): + value_type = int + else: + value_type = str + variable = { + 'id': var_name, + 'type': value_type, + 'value': value, + 'name': name, + 'description': name, + } + variable_list[name] = variable + variables[section] = (category, variable_list) + return variables + + def verify(self, config1, config2, validate_method): + return True + + def validate_type(self, var_type, value): + return True + + @staticmethod + def is_xml(config_file): try: - execfile(filepath, self.__dict__) + x = Xml(config_file) + return True except: - raise Exception, "Could not find config in " + filepath - -plcConfig = Config("/etc/planetlab/plc_config") - -def get_default_dbinfo(): - dbinfo={ 'dbname' : plcConfig.PLC_DB_NAME, - 'address' : plcConfig.PLC_DB_HOST, - 'port' : plcConfig.PLC_DB_PORT, - 'user' : plcConfig.PLC_DB_USER, - 'password' : plcConfig.PLC_DB_PASSWORD - } - - return dbinfo - -## -# Geniwrapper uses a PLCAPI connection to perform operations on the registry, -# such as creating and deleting slices. This connection requires an account -# on the PLC server with full administrator access. -# -# The Url parameter controls whether the connection uses PLCAPI directly (i.e. -# Geniwrapper is located on the same machine as PLC), or uses a XMLRPC connection -# to the PLC machine. If you wish to use the API directly, then remove the Url -# field from the dictionary. - -def get_pl_auth(): - pl_auth = {'Username': plcConfig.PLC_API_MAINTENANCE_USER, - 'AuthMethod': 'capability', - 'AuthString': plcConfig.PLC_API_MAINTENANCE_PASSWORD, - "Url": 'https://%s:%s%s' %(plcConfig.PLC_API_HOST, plcConfig.PLC_API_PORT, plcConfig.PLC_API_PATH) - } - - return pl_auth + return False + + @staticmethod + def is_ini(config_file): + try: + c = ConfigParser.ConfigParser() + c.read(config_file) + return True + except ConfigParser.MissingSectionHeaderError: + return False + + + def dump(self, sections = []): + sys.stdout.write(output_python()) + + def output_python(self, encoding = "utf-8"): + buf = codecs.lookup(encoding)[3](StringIO()) + buf.writelines(["# " + line + os.linesep for line in self._header()]) + + for section in self.sections(): + buf.write("[%s]%s" % (section, os.linesep)) + for (name,value) in self.items(section): + buf.write("%s=%s%s" % (name,value,os.linesep)) + buf.write(os.linesep) + return buf.getvalue() + + def output_shell(self, show_comments = True, encoding = "utf-8"): + """ + Return variables as a shell script. + """ + + buf = codecs.lookup(encoding)[3](StringIO()) + buf.writelines(["# " + line + os.linesep for line in self._header()]) + + for section in self.sections(): + for (name,value) in self.items(section): + # bash does not have the concept of NULL + if value: + option = "%s_%s" % (section.upper(), name.upper()) + if isbool(value): + value = str(str2bool(value)) + elif not value.isdigit(): + value = '"%s"' % value + buf.write(option + "=" + value + os.linesep) + return buf.getvalue() + + def output_php(selfi, encoding = "utf-8"): + """ + Return variables as a PHP script. + """ + + buf = codecs.lookup(encoding)[3](StringIO()) + buf.write("" + os.linesep) + + return buf.getvalue() + + def output_xml(self, encoding = "utf-8"): + pass + + def output_variables(self, encoding="utf-8"): + """ + Return list of all variable names. + """ + + buf = codecs.lookup(encoding)[3](StringIO()) + for section in self.sections(): + for (name,value) in self.items(section): + option = "%s_%s" % (section,name) + buf.write(option + os.linesep) + + return buf.getvalue() + pass + + def write(self, filename=None): + if not filename: + filename = self.filename + configfile = open(filename, 'w') + self.config.write(configfile) + + def save(self, filename=None): + self.write(filename) + + + def get_trustedroots_dir(self): + return self.config_path + os.sep + 'trusted_roots' + + def get_openflow_aggrMgr_info(self): + aggr_mgr_ip = 'localhost' + if (hasattr(self,'openflow_aggregate_manager_ip')): + aggr_mgr_ip = self.OPENFLOW_AGGREGATE_MANAGER_IP + + aggr_mgr_port = 2603 + if (hasattr(self,'openflow_aggregate_manager_port')): + aggr_mgr_port = self.OPENFLOW_AGGREGATE_MANAGER_PORT + + return (aggr_mgr_ip,aggr_mgr_port) + + def get_interface_hrn(self): + if (hasattr(self,'sfa_interface_hrn')): + return self.SFA_INTERFACE_HRN + else: + return "plc" + + def __getattr__(self, attr): + return getattr(self.config, attr) + +if __name__ == '__main__': + filename = None + if len(sys.argv) > 1: + filename = sys.argv[1] + config = Config(filename) + else: + config = Config() + config.dump() +