Add uninstallation support.
authorPatrick Uiterwijk <puiterwijk@redhat.com>
Wed, 4 Feb 2015 09:58:14 +0000 (10:58 +0100)
committerRob Crittenden <rcritten@redhat.com>
Thu, 26 Feb 2015 20:18:02 +0000 (15:18 -0500)
As part of this, made all plugins use a Installer baseclass.

https://fedorahosted.org/ipsilon/ticket/38

Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
Reviewed-by: Rob Crittenden <rcritten@redhat.com>
15 files changed:
ipsilon/helpers/common.py
ipsilon/helpers/ipa.py
ipsilon/info/common.py
ipsilon/install/ipsilon-server-install
ipsilon/login/authfas.py
ipsilon/login/authform.py
ipsilon/login/authkrb.py
ipsilon/login/authldap.py
ipsilon/login/authpam.py
ipsilon/login/authtest.py
ipsilon/login/common.py
ipsilon/providers/common.py
ipsilon/providers/openidp.py
ipsilon/providers/personaidp.py
ipsilon/providers/saml2idp.py

index e2839bf..dcbde2b 100644 (file)
@@ -21,6 +21,22 @@ from ipsilon.util.plugin import PluginInstaller
 FACILITY = 'environment_helpers'
 
 
+class EnvHelpersInstaller(object):
+    def __init__(self):
+        self.facility = FACILITY
+        self.ptype = 'helper'
+        self.name = None
+
+    def unconfigure(self, opts):
+        return
+
+    def install_args(self, group):
+        raise NotImplementedError
+
+    def configure_server(self, opts):
+        raise NotImplementedError
+
+
 class EnvHelpersInstall(object):
 
     def __init__(self):
index 58a77df..9298c08 100644 (file)
@@ -22,6 +22,8 @@ import socket
 import subprocess
 import sys
 
+from ipsilon.helpers.common import EnvHelpersInstaller
+
 
 IPA_CONFIG_FILE = '/etc/ipa/default.conf'
 HTTPD_IPA_KEYTAB = '/etc/httpd/conf/ipa.keytab'
@@ -42,9 +44,10 @@ failure (see logs) and retry.
 """
 
 
-class Installer(object):
+class Installer(EnvHelpersInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'ipa'
         self.ptype = 'helper'
         self.logger = None
index 0a5cb74..725f0fa 100644 (file)
@@ -94,6 +94,9 @@ class InfoProviderInstaller(object):
     def install_args(self, group):
         raise NotImplementedError
 
+    def unconfigure(self, opts):
+        return
+
     def configure(self, opts):
         raise NotImplementedError
 
index dfd2ffe..307f1e4 100755 (executable)
@@ -206,9 +206,59 @@ def install(plugins, args):
     except Exception:  # pylint: disable=broad-except
         pass
 
+
 def uninstall(plugins, args):
     logger.info('Uninstallation initiated')
-    raise Exception('Not Implemented')
+    instance_conf = os.path.join(CONFDIR, args['instance'])
+
+    httpd_conf = os.path.join(HTTPDCONFD,
+                              'ipsilon-%s.conf' % args['instance'])
+    data_dir = os.path.join(DATADIR, args['instance'])
+
+    if not os.path.exists(instance_conf):
+        raise Exception('Could not find instance %s configuration'
+                        % args['instance'])
+    if not os.path.exists(httpd_conf):
+        raise Exception('Could not find instance %s httpd configuration'
+                        % args['instance'])
+    if not args['yes']:
+        sure = raw_input(('Are you certain you want to erase instance %s ' +
+                          '[yes/NO]: ')
+                         % args['instance'])
+        if sure != 'yes':
+            raise Exception('Aborting')
+
+    logger.info('Removing environment helpers')
+    for plugin_name in plugins['Environment Helpers']:
+        plugin = plugins['Environment Helpers'][plugin_name]
+        if plugin.unconfigure(args) == False:
+            print 'Removal of environment helper %s failed' % plugin_name
+
+    logger.info('Removing login managers')
+    for plugin_name in args['lm_order']:
+        plugin = plugins['Login Managers'][plugin_name]
+        if plugin.unconfigure(args) == False:
+            print 'Removal of login manager %s failed' % plugin_name
+
+    logger.info('Removing Info providers')
+    for plugin_name in plugins['Info Provider']:
+        plugin = plugins['Info Provider'][plugin_name]
+        if plugin.unconfigure(args) == False:
+            print 'Removal of info provider %s failed' % plugin_name
+
+    logger.info('Removing Authentication Providers')
+    for plugin_name in plugins['Auth Providers']:
+        plugin = plugins['Auth Providers'][plugin_name]
+        if plugin.unconfigure(args) == False:
+            print 'Removal of auth provider %s failed' % plugin_name
+
+    logger.info('Removing httpd configuration')
+    os.remove(httpd_conf)
+    logger.info('Erasing instance configuration')
+    shutil.rmtree(instance_conf)
+    logger.info('Erasing instance data')
+    shutil.rmtree(data_dir)
+    logger.info('Uninstalled instance %s' % args['instance'])
 
 
 def find_plugins():
@@ -273,6 +323,8 @@ def parse_args(plugins):
                         help="Enable debugging")
     parser.add_argument('--uninstall', action='store_true',
                         help="Uninstall the server and all data")
+    parser.add_argument('--yes', action='store_true',
+                        help="Always answer yes")
 
     lms = []
 
@@ -335,9 +387,12 @@ if __name__ == '__main__':
             logger.info('%s: %s', k, opts[k])
 
         if 'uninstall' in opts and opts['uninstall'] is True:
+            if not os.path.exists(os.path.join(CONFDIR, opts['instance'])):
+                print 'Instance %s could not be found' % opts['instance']
+                sys.exit(0)
             uninstall(fplugins, opts)
-
-        install(fplugins, opts)
+        else:
+            install(fplugins, opts)
     except Exception, e:  # pylint: disable=broad-except
         logger.exception(e)
         if 'uninstall' in opts and opts['uninstall'] is True:
index a44b470..46dd7b7 100644 (file)
@@ -1,7 +1,8 @@
 # Copyright (C) 2014 Ipsilon contributors, see COPYING file for license
 
 
-from ipsilon.login.common import LoginFormBase, LoginManagerBase
+from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
+    LoginManagerInstaller
 from ipsilon.util.plugin import PluginObject
 from ipsilon.util.policy import Policy
 from ipsilon.util import config as pconfig
@@ -170,11 +171,11 @@ Form based login Manager that uses the Fedora Authentication Server
         return self.page
 
 
-class Installer(object):
+class Installer(LoginManagerInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'fas'
-        self.ptype = 'login'
         self.pargs = pargs
 
     def install_args(self, group):
index 7d84a95..808c32c 100644 (file)
@@ -15,7 +15,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from ipsilon.login.common import LoginFormBase, LoginManagerBase
+from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
+    LoginManagerInstaller
 from ipsilon.util.plugin import PluginObject
 from ipsilon.util.user import UserSession
 from ipsilon.util import config as pconfig
@@ -100,11 +101,11 @@ LoadModule authnz_pam_module modules/mod_authnz_pam.so
 """
 
 
-class Installer(object):
+class Installer(LoginManagerInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'form'
-        self.ptype = 'login'
         self.pargs = pargs
 
     def install_args(self, group):
index e352aa2..60eeb6b 100644 (file)
@@ -15,7 +15,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from ipsilon.login.common import LoginPageBase, LoginManagerBase
+from ipsilon.login.common import LoginPageBase, LoginManagerBase, \
+    LoginManagerInstaller
 from ipsilon.util.plugin import PluginObject
 from ipsilon.util.user import UserSession
 from string import Template
@@ -113,11 +114,11 @@ CONF_TEMPLATE = """
 """
 
 
-class Installer(object):
+class Installer(LoginManagerInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'krb'
-        self.ptype = 'login'
         self.pargs = pargs
 
     def install_args(self, group):
index 8958410..0161abc 100644 (file)
@@ -1,6 +1,7 @@
 # Copyright (C) 2014  Ipsilon Contributors, see COPYING for license
 
-from ipsilon.login.common import LoginFormBase, LoginManagerBase
+from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
+    LoginManagerInstaller
 from ipsilon.util.plugin import PluginObject
 from ipsilon.util.log import Log
 from ipsilon.util import config as pconfig
@@ -163,11 +164,11 @@ authentication. """
         return self.page
 
 
-class Installer(object):
+class Installer(LoginManagerInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'ldap'
-        self.ptype = 'login'
         self.pargs = pargs
 
     def install_args(self, group):
index 1de8e0f..104dd4c 100644 (file)
@@ -15,7 +15,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from ipsilon.login.common import LoginFormBase, LoginManagerBase
+from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
+    LoginManagerInstaller
 from ipsilon.util.plugin import PluginObject
 from ipsilon.util import config as pconfig
 import pam
@@ -115,11 +116,11 @@ for authentication. """
         return self.page
 
 
-class Installer(object):
+class Installer(LoginManagerInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'pam'
-        self.ptype = 'login'
         self.pargs = pargs
 
     def install_args(self, group):
index 39e0f39..6c11ba1 100644 (file)
@@ -15,7 +15,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from ipsilon.login.common import LoginFormBase, LoginManagerBase
+from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
+    LoginManagerInstaller
 from ipsilon.util.plugin import PluginObject
 from ipsilon.util import config as pconfig
 import cherrypy
@@ -97,11 +98,11 @@ Form based TEST login Manager, DO NOT EVER ACTIVATE IN PRODUCTION """
         return self.page
 
 
-class Installer(object):
+class Installer(LoginManagerInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'testauth'
-        self.ptype = 'login'
         self.pargs = pargs
 
     def install_args(self, group):
index 3002d78..4b715f3 100644 (file)
@@ -292,6 +292,22 @@ class Cancel(Page):
             return op(*args, **kwargs)
 
 
+class LoginManagerInstaller(object):
+    def __init__(self):
+        self.facility = FACILITY
+        self.ptype = 'login'
+        self.name = None
+
+    def unconfigure(self, opts):
+        return
+
+    def install_args(self, group):
+        raise NotImplementedError
+
+    def configure(self, opts):
+        raise NotImplementedError
+
+
 class LoginMgrsInstall(object):
 
     def __init__(self):
index dfa2627..4206387 100644 (file)
@@ -111,6 +111,22 @@ class ProviderPageBase(Page):
 FACILITY = 'provider_config'
 
 
+class ProviderInstaller(object):
+    def __init__(self):
+        self.facility = FACILITY
+        self.ptype = 'provider'
+        self.name = None
+
+    def unconfigure(self, opts):
+        return
+
+    def install_args(self, group):
+        raise NotImplementedError
+
+    def configure(self, opts):
+        raise NotImplementedError
+
+
 class LoadProviders(Log):
 
     def __init__(self, root, site):
index 6bdf557..f79435f 100644 (file)
@@ -2,7 +2,7 @@
 
 from __future__ import absolute_import
 
-from ipsilon.providers.common import ProviderBase
+from ipsilon.providers.common import ProviderBase, ProviderInstaller
 from ipsilon.providers.openid.store import OpenIDStore
 from ipsilon.providers.openid.auth import OpenID
 from ipsilon.providers.openid.extensions.common import LoadExtensions
@@ -131,11 +131,11 @@ Provides OpenID 2.0 authentication infrastructure. """
         self.extensions.enable(self._config['enabled extensions'].get_value())
 
 
-class Installer(object):
+class Installer(ProviderInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'openid'
-        self.ptype = 'provider'
         self.pargs = pargs
 
     def install_args(self, group):
index 0096c7a..74e19d3 100644 (file)
@@ -2,7 +2,7 @@
 
 from __future__ import absolute_import
 
-from ipsilon.providers.common import ProviderBase
+from ipsilon.providers.common import ProviderBase, ProviderInstaller
 from ipsilon.util.plugin import PluginObject
 from ipsilon.util import config as pconfig
 from ipsilon.info.common import InfoMapping
@@ -74,11 +74,11 @@ Provides Persona authentication infrastructure. """
         self.init_idp()
 
 
-class Installer(object):
+class Installer(ProviderInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'persona'
-        self.ptype = 'provider'
         self.pargs = pargs
 
     def install_args(self, group):
index 9fa2fd6..89e1346 100644 (file)
@@ -15,7 +15,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from ipsilon.providers.common import ProviderBase, ProviderPageBase
+from ipsilon.providers.common import ProviderBase, ProviderPageBase, \
+    ProviderInstaller
 from ipsilon.providers.saml2.auth import AuthenticateRequest
 from ipsilon.providers.saml2.logout import LogoutRequest
 from ipsilon.providers.saml2.admin import Saml2AdminPage
@@ -330,11 +331,11 @@ class IdpMetadataGenerator(object):
         return self.meta.output(path)
 
 
-class Installer(object):
+class Installer(ProviderInstaller):
 
     def __init__(self, *pargs):
+        super(Installer, self).__init__()
         self.name = 'saml2'
-        self.ptype = 'provider'
         self.pargs = pargs
 
     def install_args(self, group):