On 11/26/2015 01:33 PM, Jan Cholasta wrote: > On 25.11.2015 09:01, Jan Cholasta wrote: >> On 24.11.2015 15:56, Tomas Babej wrote: >>> >>> >>> On 11/23/2015 04:43 PM, Jan Cholasta wrote: >>>> Hi, >>>> >>>> On 23.11.2015 12:50, Tomas Babej wrote: >>>>> Hi, >>>>> >>>>> this patch implements the single command replica promotion&enrollment >>>>> for #5310. >>>>> >>>>> Tomas >>>>> >>>>> https://fedorahosted.org/freeipa/ticket/5310 >>>> >>>> 1) ensure_enrolled() should be called from promote_check() after the >>>> client check is done: >>>> >>>> client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) >>>> if not client_fstore.has_files(): >>>> ensure_enrolled(installer) >> >> Also it should no longer be decorated with @common_cleanup. >> >>>> >>>> >>>> 2) >>>> >>>> + server_name = Knob( >>>> + str, None, >>>> + description="fully qualified name of IPA server to enrooll >>>> to", >>>> + cli_name='server', >>>> + ) >>>> >>>> Please use the same identifier ipa-client-install uses, i.e. >>>> s/server_name/server/. >>>> >>>> Also there is typo in the description: "enrooll". >>> >>> Fixed. >> >> You don't need to set cli_name anymore, as it's the same as the default. >> >>> >>>> >>>> >>>> 3) >>>> >>>> + host_name = Knob( >>>> + str, None, >>>> + description="fully qualified name of this host", >>>> + cli_name='hostname', >>>> + ) >>>> >>>> This knob is already defined in BaseServer, there's no need to redefine >>>> it here (just remove the "host_name = None"). >>>> >>>> If you want to change the description, change it in BaseServer. >>> >>> Yep, that was the reasoning here. Changed in BaseServer. >>> >>>> >>>> >>>> 4) >>>> >>>> + keytab = Knob( >>>> + str, None, >>>> + description="path to backed up keytab from previous >>>> enrollment", >>>> + cli_name='keytab', >>>> + ) >>>> >>>> ipa-client-install uses the short name -k for the keytab option, it >>>> should be used here as well. >>>> >>> >>> Added. >> >> You don't need to set cli_name here as well. >> >>> >>>> >>>> 5) The replica file argument conflicts with the --realm, --domain, >>>> --server, --admin-password and --principal options. This should be >>>> checked in Replica.__init__(). >>>> >>>> The --hostname option should either be conflicting as well or be >>>> implemented properly for legacy replica install. >>>> >>> >>> All of them now conflict --replica-file. >> >> Replica file is not an option but rather an argument in >> ipa-replica-install. >> >> I think the error message should use the same wording which is used for >> --forwarder vs. --no-forwarder and --reverse-zone vs. --no-reverse: "You >> cannot specify a --something option together with replica file". >> >>> >>>> >>>> 6) I think --admin-password should be renamed to --password and the >>>> description changed, since it now also allows OTP enrollment. >>>> >>> >>> I changed the requirements to mandate --principal when --password is >>> used, as we discussed. >> >> I was wrong here, sorry. >> >> ipa-replica-install assumes "admin" for principal by default, so we just >> need to make sure ipa-client-install is called with --principal when >> password is used, whether it's the provided principal or the default >> "admin". >> >>> >>> The name of the option cannot really be changed, as it is already taken >>> by the dm_password. >> >> Right. >> > > One more thing I remembered: > > 7) When you try replica promotion on domain level 0, ipa-replica-install > will install the client, then do the domain level check and fail, > leaving the client installed. The check should be done as soon as > possible, i.e. in ipa-client-install, so that nothing is installed in > that case. > > This can be a separate patch though. >
Here's updated version of 385. I'll deal with (7) in a follow-up patch. Tomas
From 272617563575d2418d0f5556da6640b4b69d1ff4 Mon Sep 17 00:00:00 2001 From: Tomas Babej <tba...@redhat.com> Date: Mon, 23 Nov 2015 12:46:15 +0100 Subject: [PATCH] replicainstall: Add possiblity to install client in one command https://fedorahosted.org/freeipa/ticket/5310 --- ipaserver/install/server/common.py | 2 +- ipaserver/install/server/replicainstall.py | 110 ++++++++++++++++++++++++++--- 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/ipaserver/install/server/common.py b/ipaserver/install/server/common.py index 93c95dd8e8d2b24af193ee19368959188bcd6cb9..6116ebc25fc1d439a515d260feed82fc134f1d97 100644 --- a/ipaserver/install/server/common.py +++ b/ipaserver/install/server/common.py @@ -275,7 +275,7 @@ class BaseServer(common.Installable, common.Interactive, core.Composite): host_name = Knob( str, None, - description="fully qualified name of server", + description="fully qualified name of this host", cli_name='hostname', ) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 4b811105be3409e7c673fb55f96c8b3e58be63b5..27cad5455daededb2f46f540676bbcd684ada452 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -4,6 +4,7 @@ from __future__ import print_function +import collections import dns.exception as dnsexception import dns.name as dnsname import dns.resolver as dnsresolver @@ -751,6 +752,52 @@ def install(installer): remove_replica_info_dir(installer) +def ensure_enrolled(installer): + config = installer._config + + # Perform only if we have the necessary options + if not any([installer.principal and installer.admin_password, + installer.keytab]): + sys.exit("IPA client is not configured on this system.\n" + "You must use a replica file or join the system " + "either by using by running 'ipa-client-install'. " + "Alternatively, you may specify enrollment related options " + "directly, see man ipa-replica-install.") + + # Call client install script + service.print_msg("Configuring client side components") + try: + args = [paths.IPA_CLIENT_INSTALL, "--unattended"] + if installer.domain_name: + args.extend(["--domain", installer.domain_name]) + if installer.server: + args.extend(["--server", installer.server]) + if installer.realm_name: + args.extend(["--realm", installer.realm_name]) + if installer.host_name: + args.extend(["--hostname", installer.host_name]) + + if installer.admin_password: + args.extend(["--password", installer.admin_password]) + args.extend(["--principal", installer.principal]) + if installer.keytab: + args.extend(["--keytab", installer.keytab]) + + if installer.no_dns_sshfp: + args.append("--no-dns-sshfp") + if installer.ssh_trust_dns: + args.append("--ssh-trust-dns") + if installer.no_ssh: + args.append("--no-ssh") + if installer.no_sshd: + args.append("--no-sshd") + if installer.mkhomedir: + args.append("--mkhomedir") + ipautil.run(args) + except Exception as e: + sys.exit("Configuration of client side components failed!\n" + "ipa-client-install returned: " + str(e)) + @common_cleanup def promote_check(installer): options = installer @@ -761,9 +808,7 @@ def promote_check(installer): client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if not client_fstore.has_files(): - sys.exit("IPA client is not configured on this system.\n" - "You must use a replica file or join the system " - "using 'ipa-client-install'.") + ensure_enrolled(installer) sstore = sysrestore.StateFile(paths.SYSRESTORE) @@ -1103,9 +1148,6 @@ class Replica(BaseServer): description="a file generated by ipa-replica-prepare", ) - realm_name = None - domain_name = None - setup_ca = Knob(BaseServer.setup_ca) setup_kra = Knob(BaseServer.setup_kra) setup_dns = Knob(BaseServer.setup_dns) @@ -1125,12 +1167,22 @@ class Replica(BaseServer): admin_password = Knob( BaseServer.admin_password, - description="Admin user Kerberos password used for connection check", + description="Kerberos password for the specified admin principal", cli_short_name='w', ) + server = Knob( + str, None, + description="fully qualified name of IPA server to enroll to", + ) + + host_name = Knob( + str, None, + description="fully qualified name of this host", + cli_name='hostname', + ) + mkhomedir = Knob(BaseServer.mkhomedir) - host_name = None no_host_dns = Knob(BaseServer.no_host_dns) no_ntp = Knob(BaseServer.no_ntp) no_pkinit = Knob(BaseServer.no_pkinit) @@ -1148,10 +1200,17 @@ class Replica(BaseServer): principal = Knob( str, None, sensitive=True, - description="User Principal allowed to promote replicas", + description="User Principal allowed to promote replicas " + "and join IPA realm", cli_short_name='P', ) + keytab = Knob( + str, None, + description="path to backed up keytab from previous enrollment", + cli_short_name='k', + ) + promote = False # ca @@ -1187,11 +1246,44 @@ class Replica(BaseServer): if self.replica_file is None: self.promote = True + + # Make sure --password is not used without principal, + # that would mean OTP join for ipa-client-install + + password_and_principal = [self.admin_password, self.principal] + if any(password_and_principal) and not all(password_and_principal): + raise RuntimeError( + "The --password and --principal options must be used " + "together." + ) + else: if not ipautil.file_exists(self.replica_file): raise RuntimeError("Replica file %s does not exist" % self.replica_file) + CLIKnob = collections.namedtuple('CLIKnob', ('value', 'name')) + + conflicting_knobs = ( + CLIKnob(self.realm_name, '--realm'), + CLIKnob(self.domain_name, '--domain'), + CLIKnob(self.host_name, '--hostname'), + CLIKnob(self.server, '--server'), + CLIKnob(self.admin_password, '--admin-password'), + CLIKnob(self.principal, '--principal'), + ) + + if any([k.value is not None for k in conflicting_knobs]): + conflicting_knob_names = [ + knob.name for knob in conflicting_knobs + if knob.value is not None + ] + + raise RuntimeError( + "You cannot specify '{0}' option(s) with replica file." + .format(", ".join(conflicting_knob_names)) + ) + if self.setup_dns: #pylint: disable=no-member if not self.dns.forwarders and not self.dns.no_forwarders: -- 2.5.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