Dne 26.5.2015 v 17:49 Jan Cholasta napsal(a):
Dne 20.5.2015 v 17:27 Jan Cholasta napsal(a):
Hi,

the attached patch implements the initial bits for
<https://fedorahosted.org/freeipa/ticket/2888>.

Test by running ipa-client-install and then ipa-replica-install on the
same host.

Updated patch attached.

Another update, patch attached.

--
Jan Cholasta
>From 2699db4a40657cc5bbf57eca87a5e1b3dae4209c Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 20 May 2015 15:20:31 +0000
Subject: [PATCH] replica-install: Allow install on top of already configured
 client

https://fedorahosted.org/freeipa/ticket/2888
---
 install/tools/ipa-replica-install | 187 ++++++++++++++++++++++++++++----------
 ipaserver/install/krbinstance.py  |   6 +-
 2 files changed, 142 insertions(+), 51 deletions(-)

diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 1df782b..d23a462 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -24,10 +24,12 @@ import socket
 import os, pwd, shutil
 from optparse import OptionGroup
 from contextlib import contextmanager
+from ConfigParser import RawConfigParser
 
 import dns.resolver
 import dns.reversename
 import dns.exception
+import SSSDConfig
 
 from ipapython import ipautil
 
@@ -151,6 +153,24 @@ def parse_options():
     elif options.reverse_zones and options.no_reverse:
         parser.error("You cannot specify a --reverse-zone option together with --no-reverse")
 
+    client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
+    if client_fstore.has_files():
+        if options.mkhomedir:
+            parser.error("You cannot specify a --mkhomedir option "
+                         "when IPA client is already configured")
+        if options.trust_sshfp:
+            parser.error("You cannot specify a --ssh-trust-dns option "
+                         "when IPA client is already configured")
+        if not options.conf_ssh:
+            parser.error("You cannot specify a --no-ssh option "
+                         "when IPA client is already configured")
+        if not options.conf_sshd:
+            parser.error("You cannot specify a --no-sshd option "
+                         "when IPA client is already configured")
+        if not options.create_sshfp:
+            parser.error("You cannot specify a --no-dns-sshfp option "
+                         "when IPA client is already configured")
+
     options.zonemgr = None
     options.dnssec_master = False
 
@@ -204,7 +224,7 @@ def install_replica_ds(config):
 
     return ds
 
-def install_krb(config, setup_pkinit=False):
+def install_krb(config, setup_pkinit=False, client_configured=False):
     krb = krbinstance.KrbInstance()
 
     #pkinit files
@@ -214,7 +234,7 @@ def install_krb(config, setup_pkinit=False):
     krb.create_replica(config.realm_name,
                        config.master_host_name, config.host_name,
                        config.domain_name, config.dirman_password,
-                       setup_pkinit, pkcs12_info)
+                       setup_pkinit, pkcs12_info, None, client_configured)
 
     return krb
 
@@ -418,11 +438,40 @@ def main():
     if not ipautil.file_exists(filename):
         sys.exit("Replica file %s does not exist" % filename)
 
+    if installutils.is_ipa_configured():
+        sys.exit("IPA server is already configured on this system.\n"
+                 "If you want to reinstall the IPA server, please uninstall "
+                 "it first using 'ipa-server-install --uninstall'.")
+
     client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
-    if client_fstore.has_files():
-        sys.exit("IPA client is already configured on this system.\n" +
-            "Please uninstall it first before configuring the replica, " +
-            "using 'ipa-client-install --uninstall'.")
+    client_configured = client_fstore.has_files()
+    if client_configured:
+        try:
+            sssdconfig = SSSDConfig.SSSDConfig()
+            sssdconfig.import_config()
+
+            domains = sssdconfig.list_active_domains()
+            for name in domains:
+                domain = sssdconfig.get_domain(name)
+                try:
+                    provider = domain.get_option('id_provider')
+                except SSSDConfig.NoOptionError:
+                    continue
+                if provider == 'ipa':
+                    break
+            else:
+                raise RuntimeError("IPA domain not configured in SSSD")
+
+            if not services.service('sssd').is_enabled():
+                raise RuntimeError("SSSD is not enabled")
+
+            if not services.service('sssd').is_running():
+                raise RuntimeError("SSSD is not running")
+        except Exception as e:
+            root_logger.error("%s", e)
+            sys.exit("SSSD is not configured for IPA client on this system.\n"
+                     "Please uninstall IPA client using 'ipa-client-install "
+                     "--uninstall' and re-run ipa-replica-install.")
 
     global sstore
     sstore = sysrestore.StateFile(paths.SYSRESTORE)
@@ -495,32 +544,41 @@ def main():
             config.master_host_name, config.host_name, config.realm_name,
             options.setup_ca, config.ca_ds_port, options.admin_password)
 
-
     # Create the management framework config file
     # Note: We must do this before bootstraping and finalizing ipalib.api
     old_umask = os.umask(022)   # must be readable for httpd
     try:
-        fd = open(paths.IPA_DEFAULT_CONF, "w")
-        fd.write("[global]\n")
-        fd.write("host=%s\n" % config.host_name)
-        fd.write("basedn=%s\n" % str(ipautil.realm_to_suffix(config.realm_name)))
-        fd.write("realm=%s\n" % config.realm_name)
-        fd.write("domain=%s\n" % config.domain_name)
-        fd.write("xmlrpc_uri=https://%s/ipa/xml\n"; % ipautil.format_netloc(config.host_name))
-        fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" %
-                 installutils.realm_to_serverid(config.realm_name))
+        parser = RawConfigParser()
+        if not client_configured:
+            parser.add_section('global')
+            parser.set('global', 'host', config.host_name)
+            parser.set('global', 'basedn',
+                       ipautil.realm_to_suffix(config.realm_name))
+            parser.set('global', 'realm', config.realm_name)
+            parser.set('global', 'domain', config.domain_name)
+        else:
+            parser.read(paths.IPA_DEFAULT_CONF)
+            parser.remove_option('global', 'server')
+
+        parser.set('global', 'xmlrpc_uri',
+                   ('https://%s/ipa/xml' %
+                    ipautil.format_netloc(config.host_name)))
+        parser.set('global', 'ldap_uri',
+                   ('ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' %
+                    installutils.realm_to_serverid(config.realm_name)))
         if ipautil.file_exists(config.dir + "/cacert.p12"):
-            fd.write("enable_ra=True\n")
-            fd.write("ra_plugin=dogtag\n")
-            fd.write("dogtag_version=%s\n" %
-                dogtag.install_constants.DOGTAG_VERSION)
+            parser.set('global', 'enable_ra', 'True')
+            parser.set('global', 'ra_plugin', 'dogtag')
+            parser.set('global', 'dogtag_version',
+                       dogtag.install_constants.DOGTAG_VERSION)
         else:
-            fd.write("enable_ra=False\n")
-            fd.write("ra_plugin=none\n")
+            parser.set('global', 'enable_ra', 'False')
+            parser.set('global', 'ra_plugin', 'none')
+        parser.set('global', 'enable_kra', config.setup_kra)
+        parser.set('global', 'mode', 'production')
 
-        fd.write("enable_kra=%s\n" % config.setup_kra)
-
-        fd.write("mode=production\n")
+        fd = open(paths.IPA_DEFAULT_CONF, "w")
+        parser.write(fd)
         fd.close()
     finally:
         os.umask(old_umask)
@@ -594,17 +652,23 @@ def main():
                 exit(3)
 
             # Check pre-existing host entry
-            try:
-                entry = conn.find_entries(u'fqdn=%s' % config.host_name, ['fqdn'], DN(api.env.container_host, api.env.basedn))
-            except errors.NotFound:
-                pass
-            else:
-                root_logger.info(
-                    'Error: Host %s already exists on the master server.' % config.host_name)
-                print 'The host %s already exists on the master server.' % config.host_name
-                print "You should remove it before proceeding:"
-                print "    %% ipa host-del %s" % config.host_name
-                exit(3)
+            if not client_configured:
+                try:
+                    entry = conn.find_entries(u'fqdn=%s' % config.host_name,
+                                              ['fqdn'],
+                                              DN(api.env.container_host,
+                                                 api.env.basedn))
+                except errors.NotFound:
+                    pass
+                else:
+                    root_logger.info(
+                        "Error: Host %s already exists on the master server." %
+                        config.host_name)
+                    print ("The host %s already exists on the master server." %
+                           config.host_name)
+                    print "You should remove it before proceeding:"
+                    print "    %% ipa host-del %s" % config.host_name
+                    exit(3)
 
             # Install CA cert so that we can do SSL connections with ldap
             install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)
@@ -663,7 +727,8 @@ def main():
         # This is done within stopped_service context, which restarts CA
         CA.enable_client_auth_to_db(CA.dogtag_constants.CS_CFG_PATH)
 
-    krb = install_krb(config, setup_pkinit=options.setup_pkinit)
+    krb = install_krb(config, setup_pkinit=options.setup_pkinit,
+                      client_configured=client_configured)
     http = install_http(config, auto_redirect=options.ui_redirect)
 
     otpd = otpdinstance.OtpdInstance()
@@ -706,18 +771,42 @@ def main():
 
     # Call client install script
     try:
-        args = [paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended", "--domain", config.domain_name, "--server", config.host_name, "--realm", config.realm_name]
-        if not options.create_sshfp:
-            args.append("--no-dns-sshfp")
-        if options.trust_sshfp:
-            args.append("--ssh-trust-dns")
-        if not options.conf_ssh:
-            args.append("--no-ssh")
-        if not options.conf_sshd:
-            args.append("--no-sshd")
-        if options.mkhomedir:
-            args.append("--mkhomedir")
-        ipautil.run(args)
+        if not client_configured:
+            args = [paths.IPA_CLIENT_INSTALL,
+                    "--on-master",
+                    "--unattended",
+                    "--domain", config.domain_name,
+                    "--server", config.host_name,
+                    "--realm", config.realm_name]
+            if not options.create_sshfp:
+                args.append("--no-dns-sshfp")
+            if options.trust_sshfp:
+                args.append("--ssh-trust-dns")
+            if not options.conf_ssh:
+                args.append("--no-ssh")
+            if not options.conf_sshd:
+                args.append("--no-sshd")
+            if options.mkhomedir:
+                args.append("--mkhomedir")
+            ipautil.run(args)
+        else:
+            sssdconfig = SSSDConfig.SSSDConfig()
+            sssdconfig.import_config()
+
+            domain = sssdconfig.get_domain(config.domain_name)
+            domain.remove_option('dns_discovery_domain')
+            domain.set_option('ipa_server_mode', True)
+            # the master should only use itself for Kerberos
+            domain.set_option('ipa_server', config.host_name)
+
+            sssdconfig.save_domain(domain)
+            sssdconfig.write(paths.SSSD_CONF)
+
+            sssd = services.service('sssd')
+            try:
+                sssd.restart()
+            except ipautil.CalledProcessError:
+                root_logger.warning("SSSD service restart was unsuccessful.")
     except Exception, e:
         print "Configuration of client side components failed!"
         print "ipa-client-install returned: " + str(e)
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index 648fc76..b942617 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -193,7 +193,7 @@ class KrbInstance(service.Service):
                        master_fqdn, host_name,
                        domain_name, admin_password,
                        setup_pkinit=False, pkcs12_info=None,
-                       subject_base=None):
+                       subject_base=None, client_configured=False):
         self.pkcs12_info = pkcs12_info
         self.subject_base = subject_base
         self.master_fqdn = master_fqdn
@@ -203,7 +203,9 @@ class KrbInstance(service.Service):
         self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
         self.step("configuring KDC", self.__configure_instance)
         self.step("creating a keytab for the directory", self.__create_ds_keytab)
-        self.step("creating a keytab for the machine", self.__create_host_keytab)
+        if not client_configured:
+            self.step("creating a keytab for the machine",
+                      self.__create_host_keytab)
         self.step("adding the password extension to the directory", self.__add_pwd_extop_module)
         if setup_pkinit:
             self.step("installing X509 Certificate for PKINIT", self.__setup_pkinit)
-- 
2.1.0

-- 
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