From 804bfd00400dbebebad4967d18021724933c2097 Mon Sep 17 00:00:00 2001 From: az Date: Sun, 26 Feb 2023 20:01:47 +0100 Subject: [PATCH] refactor CliUtils.kt --- .../provs/framework/core/cli/CliUtils.kt | 67 ++++++++++++------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/cli/CliUtils.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/cli/CliUtils.kt index 3cacf98..0107ea6 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/cli/CliUtils.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/cli/CliUtils.kt @@ -14,31 +14,32 @@ import kotlin.system.exitProcess /** * Returns a Prov instance according to the targetCommand. - * E.g. it returns a local Prov instance if targetCommand.isValidLocalhost() is true or + * Returns a local Prov instance if targetCommand.isValidLocalhost() is true resp. * returns a remote Prov instance if targetCommand.isValidRemote() is true. - * - * If the target is remote and if parameter remoteHostSetSudoWithoutPasswordRequired is set to true, - * it will enable sudo without password on the remote machine (in case this was not yet enabled). */ fun createProvInstance(targetCommand: TargetCliCommand): Prov { if (targetCommand.isValid()) { val password: Secret? = targetCommand.remoteTarget()?.password val remoteTarget = targetCommand.remoteTarget() - if (targetCommand.isValidLocalhost()) { - return createLocalProvInstance() + + return if (targetCommand.isValidLocalhost()) { + createLocalProvInstance() } else if (targetCommand.isValidRemote() && remoteTarget != null) { - return createRemoteProvInstance( + createRemoteProvInstance( remoteTarget.host, remoteTarget.user, remoteTarget.password == null, password ) } else { - throw IllegalArgumentException("Error: neither a valid localHost nor a valid remoteHost was specified! Use option -h for help.") + throw IllegalArgumentException( + "Error: neither a valid localHost nor a valid remoteHost was specified! Use option -h for help." + ) } } else { - println("Invalid command line options.\nPlease use option -h for help.") + println("ERROR: Invalid target (${targetCommand.target}). Please use option -h for help.") + System.out.flush() exitProcess(1) } } @@ -46,11 +47,13 @@ fun createProvInstance(targetCommand: TargetCliCommand): Prov { private fun createLocalProvInstance(): Prov { val prov = local() if (!prov.currentUserCanSudoWithoutPassword()) { - val password = PromptSecretSource( - "Please enter password to configure sudo without password in the future." + - "\nWarning: This will permanently allow your user to use sudo privileges without a password." - ).secret() - prov.makeCurrentUserSudoerWithoutPasswordRequired(password) + val passwordNonNull = getPasswordToConfigureSudoWithoutPassword() + + prov.makeCurrentUserSudoerWithoutPasswordRequired(passwordNonNull) + + check(prov.currentUserCanSudoWithoutPassword()) { + "ERROR: User ${prov.whoami()} cannot sudo without enteringa password." + } } return prov } @@ -66,25 +69,37 @@ private fun createRemoteProvInstance( if (sshWithKey) { remote(host, remoteUser) } else { - require( - password != null, - { "No password available for provisioning without ssh keys. Either specify provisioning by ssh-keys or provide password." }) + require(password != null) { + "No password available for provisioning without ssh keys. " + + "Either specify provisioning by ssh-keys or provide password." + } remote(host, remoteUser, password) } - if (!prov.currentUserCanSudoWithoutPassword()) { - require( - password != null, - { "User ${prov.whoami()} not able to sudo on remote machine without password and no password available for the user." }) - prov.makeCurrentUserSudoerWithoutPasswordRequired(password) + return if (prov.currentUserCanSudoWithoutPassword()) { + prov + } else { - // a new session is required after making the user a sudoer without password - return remote(host, remoteUser, password) + val passwordNonNull = password + ?: getPasswordToConfigureSudoWithoutPassword() + + val result = prov.makeCurrentUserSudoerWithoutPasswordRequired(passwordNonNull) + + check(result.success) { + "Could not make user a sudoer without password required. (Maybe the provided password is incorrect.)" + } + + // a new session is required after the user has become a sudoer without password + val provWithNewSshClient = remote(host, remoteUser, password) + + check(provWithNewSshClient.currentUserCanSudoWithoutPassword()) { + "ERROR: User ${provWithNewSshClient.whoami()} on $host cannot sudo without entering a password." + } + + provWithNewSshClient } - return prov } - internal fun getPasswordToConfigureSudoWithoutPassword(): Secret { return PromptSecretSource("password to configure sudo without password.").secret() } \ No newline at end of file