URL: https://github.com/freeipa/freeipa/pull/182
Author: tiran
 Title: #182: Use env var IPA_CONFDIR to get confdir for 'cli' context
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/182/head:pr182
git checkout pr182
From f47356a8a14cfec8454d52fff71a21e4d8ad2ff3 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Mon, 24 Oct 2016 10:35:41 +0200
Subject: [PATCH] Use env var IPA_CONFDIR to get confdir

The environment variable IPA_CONFDIR overrides the default confdir path.
The value of the environment variable must be an absolute path to an existing
directory. The new variable makes it much simpler to use the 'ipa'
command and ipalib with a local configuration directory.

Some contexts like server, installer and upgrades do not support the env
var.

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 client/man/ipa.1                      |  4 ++++
 install/tools/ipa-httpd-kdcproxy      |  2 +-
 install/tools/ipa-replica-conncheck   |  2 +-
 ipalib/config.py                      | 18 +++++++++++++++-
 ipatests/test_ipalib/test_plugable.py | 40 +++++++++++++++++++++++++++++++++--
 ipatests/util.py                      |  6 ++++++
 6 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/client/man/ipa.1 b/client/man/ipa.1
index cc5641b..f35f557 100644
--- a/client/man/ipa.1
+++ b/client/man/ipa.1
@@ -190,6 +190,10 @@ The ipa client will determine which server to connect to in this order:
 
 .TP
 If a kerberos error is raised by any of the requests then it will stop processing and display the error message.
+.SH "ENVIRONMENT VARIABLES"
+.TP
+\fBIPA_CONFDIR\fR
+Override path to confdir (default: \fB/etc/ipa\fR).
 .SH "FILES"
 .TP
 \fB/etc/ipa/default.conf\fR
diff --git a/install/tools/ipa-httpd-kdcproxy b/install/tools/ipa-httpd-kdcproxy
index 329565c..34cdd88 100755
--- a/install/tools/ipa-httpd-kdcproxy
+++ b/install/tools/ipa-httpd-kdcproxy
@@ -184,7 +184,7 @@ class KDCProxyConfig(object):
 def main(debug=DEBUG, time_limit=TIME_LIMIT):
     # initialize API without file logging
     if not api.isdone('bootstrap'):
-        api.bootstrap(context='ipa-httpd-kdcproxy', log=None, debug=debug)
+        api.bootstrap(context='server', log=None, debug=debug)
         standard_logging_setup(verbose=True, debug=debug)
 
     try:
diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index 4045e41..fbe2dd5 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -478,7 +478,7 @@ def main():
                     else:
                         nss_dir = None
 
-                    api.bootstrap(context='client', xmlrpc_uri=xmlrpc_uri,
+                    api.bootstrap(context='installer', xmlrpc_uri=xmlrpc_uri,
                                   nss_dir=nss_db.secdir)
                     api.finalize()
                     try:
diff --git a/ipalib/config.py b/ipalib/config.py
index 1075d62..9eeb763 100644
--- a/ipalib/config.py
+++ b/ipalib/config.py
@@ -43,6 +43,7 @@
 from ipalib.base import check_name
 from ipalib.constants import CONFIG_SECTION
 from ipalib.constants import OVERRIDE_ERROR, SET_ERROR, DEL_ERROR
+from ipapython.admintool import ScriptError
 
 if six.PY3:
     unicode = str
@@ -200,6 +201,10 @@ class provides high-level methods for bootstraping a fresh `Env` instance
 
     __locked = False
 
+    # Reserved contexts do not support IPA_CONFDIR env var
+    _reserved_contexts = {'backup', 'cli_installer', 'installer', 'ipactl',
+                          'renew', 'restore', 'server', 'updates'}
+
     def __init__(self, **initialize):
         object.__setattr__(self, '_Env__d', {})
         object.__setattr__(self, '_Env__done', set())
@@ -461,7 +466,18 @@ def _bootstrap(self, **overrides):
 
         # Set confdir:
         if 'confdir' not in self:
-            if self.in_tree:
+            ipa_confdir = os.environ.get('IPA_CONFDIR')
+            if ipa_confdir is not None:
+                if self.context in self._reserved_contexts:
+                    raise ScriptError(
+                        'IPA_CONFDIR env var is not allowed for context '
+                        '"{}".'.format(self.context))
+                if not path.isabs(ipa_confdir) or not path.isdir(ipa_confdir):
+                    raise ScriptError(
+                        'IPA_CONFDIR env var must be an absolute path to an '
+                        'existing directory.')
+                self.confdir = ipa_confdir
+            elif self.in_tree:
                 self.confdir = self.dot_ipa
             else:
                 self.confdir = path.join('/', 'etc', 'ipa')
diff --git a/ipatests/test_ipalib/test_plugable.py b/ipatests/test_ipalib/test_plugable.py
index 1ee1102..ff22446 100644
--- a/ipatests/test_ipalib/test_plugable.py
+++ b/ipatests/test_ipalib/test_plugable.py
@@ -24,9 +24,13 @@
 # FIXME: Pylint errors
 # pylint: disable=no-member
 
+import os
+import textwrap
+
+from ipalib import plugable, errors, create_api
+from ipapython.admintool import ScriptError
 from ipatests.util import raises, read_only
-from ipatests.util import ClassChecker, create_test_api
-from ipalib import plugable, errors
+from ipatests.util import ClassChecker, create_test_api, TempHome
 
 import pytest
 
@@ -272,3 +276,35 @@ def test_load_plugins(self):
         assert o.isdone('load_plugins') is True
         e = raises(Exception, o.load_plugins)
         assert str(e) == 'API.load_plugins() already called'
+
+    def test_ipaconf_env(self):
+        ipa_confdir = os.environ.get('IPA_CONFDIR', None)
+        try:
+            with TempHome() as home:
+                defaultconf = home.join('default.conf')
+                with open(defaultconf, 'w') as f:
+                    f.write(textwrap.dedent("""
+                        [global]
+                        basedn = dc=ipa,dc=test
+                        realm = IPA.TEST
+                        domain = ipa.test
+                        """)
+                    )
+                os.environ['IPA_CONFDIR'] = home.path
+                api = create_api(mode='unit_test')
+                api.bootstrap()
+                api.finalize()
+                assert api.env.confdir == home.path
+                assert api.env.conf_default == defaultconf
+                assert api.env.realm == 'IPA.TEST'
+                assert api.env.domain == 'ipa.test'
+
+                os.environ['IPA_CONFDIR'] = home.join('invalid')
+                api = create_api(mode='unit_test')
+                with pytest.raises(ScriptError):
+                    api.bootstrap()
+        finally:
+            if ipa_confdir:
+                os.environ['IPA_CONFDIR'] = ipa_confdir
+            else:
+                os.environ.pop('IPA_CONFDIR')
diff --git a/ipatests/util.py b/ipatests/util.py
index bca8e9c..38edaf9 100644
--- a/ipatests/util.py
+++ b/ipatests/util.py
@@ -97,6 +97,12 @@ def join(self, *parts):
     def __del__(self):
         self.rmtree()
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.rmtree()
+
 
 class TempHome(TempDir):
     def __init__(self):
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to