aboutsummaryrefslogtreecommitdiff
path: root/rpki/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpki/config.py')
-rw-r--r--rpki/config.py87
1 files changed, 46 insertions, 41 deletions
diff --git a/rpki/config.py b/rpki/config.py
index 0e30982b..b8d25896 100644
--- a/rpki/config.py
+++ b/rpki/config.py
@@ -32,23 +32,16 @@ logger = logging.getLogger(__name__)
## @var default_filename
# Default name of config file if caller doesn't specify one explictly.
-default_filename = "rpki.conf"
-
-## @var default_dirname
-# Default name of directory to check for global config file, or None
-# if no global config file. Autoconf-generated code may set this to a
-# non-None value during script startup.
-
try:
import rpki.autoconf
- default_dirname = rpki.autoconf.sysconfdir
+ default_filename = os.path.join(rpki.autoconf.sysconfdir, "rpki.conf")
except ImportError:
- default_dirname = None
+ default_filename = None
-## @var default_envname
+## @var rpki_conf_envname
# Name of environment variable containing config file name.
-default_envname = "RPKI_CONF"
+rpki_conf_envname = "RPKI_CONF"
class parser(object):
"""
@@ -61,44 +54,48 @@ class parser(object):
get-methods with default values and default section name.
- If no filename is given to the constructor (filename = None), we
- check for an environment variable naming the config file, then we
- check for a default filename in the current directory, then finally
- we check for a global config file if autoconf provided a directory
- name to check.
+ If no filename is given to the constructor (filename and
+ set_filename both None), we check for an environment variable naming
+ the config file, then finally we check for a global config file if
+ autoconf provided a directory name to check.
+
+ NB: Programs which accept a configuration filename on the command
+ lines should pass that filename using set_filename so that we can
+ set the magic environment variable. Constraints from some external
+ libraries (principally Django) sometimes require library code to
+ look things up in the configuration file without the knowledge of
+ the controlling program, but setting the environment variable
+ insures that everybody's reading from the same script, as it were.
"""
- def __init__(self, filename = None, section = None, allow_missing = False):
+ # Odd keyword-only calling sequence is a defense against old code
+ # that thinks it knows how __init__() handles positional arguments.
+
+ def __init__(self, **kwargs):
+ section = kwargs.pop("section", None)
+ allow_missing = kwargs.pop("allow_missing", False)
+ set_filename = kwargs.pop("set_filename", None)
+ filename = kwargs.pop("filename", set_filename)
+
+ assert not kwargs, "Unexpected keyword arguments: " + ", ".join("%s = %r" % kv for kv in kwargs.iteritems())
+
+ if set_filename is not None:
+ os.environ[rpki_conf_envname] = set_filename
self.cfg = ConfigParser.RawConfigParser()
self.default_section = section
- filenames = []
- if filename is not None:
- filenames.append(filename)
- else:
- if default_envname in os.environ:
- filenames.append(os.environ[default_envname])
- filenames.append(default_filename)
- if default_dirname is not None:
- filenames.append("%s/%s" % (default_dirname, default_filename))
+ self.filename = filename or os.getenv(rpki_conf_envname) or default_filename
- f = fn = None
+ try:
+ with open(self.filename, "r") as f:
+ self.cfg.readfp(f)
+ except IOError:
+ if allow_missing:
+ self.filename = None
+ else:
+ raise
- for fn in filenames:
- try:
- f = open(fn)
- break
- except IOError:
- f = None
-
- if f is not None:
- self.filename = fn
- self.cfg.readfp(f, fn)
- elif allow_missing:
- self.filename = None
- else:
- raise
def has_section(self, section):
"""
@@ -107,6 +104,7 @@ class parser(object):
return self.cfg.has_section(section)
+
def has_option(self, option, section = None):
"""
Test whether an option exists.
@@ -116,6 +114,7 @@ class parser(object):
section = self.default_section
return self.cfg.has_option(section, option)
+
def multiget(self, option, section = None):
"""
Parse OpenSSL-style foo.0, foo.1, ... subscripted options.
@@ -134,6 +133,7 @@ class parser(object):
for option in matches:
yield self.cfg.get(section, option)
+
_regexp = re.compile("\\${(.*?)::(.*?)}")
def _repl(self, m):
@@ -148,6 +148,7 @@ class parser(object):
else:
return self.cfg.get(section, option)
+
def get(self, option, default = None, section = None):
"""
Get an option, perhaps with a default value.
@@ -163,6 +164,7 @@ class parser(object):
if not modified:
return val
+
def getboolean(self, option, default = None, section = None):
"""
Get a boolean option, perhaps with a default value.
@@ -176,6 +178,7 @@ class parser(object):
v = self.cfg._boolean_states[v]
return v
+
def getint(self, option, default = None, section = None):
"""
Get an integer option, perhaps with a default value.
@@ -183,6 +186,7 @@ class parser(object):
return int(self.get(option, default, section))
+
def getlong(self, option, default = None, section = None):
"""
Get a long integer option, perhaps with a default value.
@@ -190,6 +194,7 @@ class parser(object):
return long(self.get(option, default, section))
+
def set_global_flags(self):
"""
Consolidated control for all the little global control flags