refactor CliUtils.kt

This commit is contained in:
az 2023-02-26 20:01:47 +01:00
parent df2a47bb6a
commit 804bfd0040

View file

@ -14,31 +14,32 @@ import kotlin.system.exitProcess
/** /**
* Returns a Prov instance according to the targetCommand. * 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. * 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 { fun createProvInstance(targetCommand: TargetCliCommand): Prov {
if (targetCommand.isValid()) { if (targetCommand.isValid()) {
val password: Secret? = targetCommand.remoteTarget()?.password val password: Secret? = targetCommand.remoteTarget()?.password
val remoteTarget = targetCommand.remoteTarget() val remoteTarget = targetCommand.remoteTarget()
if (targetCommand.isValidLocalhost()) {
return createLocalProvInstance() return if (targetCommand.isValidLocalhost()) {
createLocalProvInstance()
} else if (targetCommand.isValidRemote() && remoteTarget != null) { } else if (targetCommand.isValidRemote() && remoteTarget != null) {
return createRemoteProvInstance( createRemoteProvInstance(
remoteTarget.host, remoteTarget.host,
remoteTarget.user, remoteTarget.user,
remoteTarget.password == null, remoteTarget.password == null,
password password
) )
} else { } 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 { } 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) exitProcess(1)
} }
} }
@ -46,11 +47,13 @@ fun createProvInstance(targetCommand: TargetCliCommand): Prov {
private fun createLocalProvInstance(): Prov { private fun createLocalProvInstance(): Prov {
val prov = local() val prov = local()
if (!prov.currentUserCanSudoWithoutPassword()) { if (!prov.currentUserCanSudoWithoutPassword()) {
val password = PromptSecretSource( val passwordNonNull = getPasswordToConfigureSudoWithoutPassword()
"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." prov.makeCurrentUserSudoerWithoutPasswordRequired(passwordNonNull)
).secret()
prov.makeCurrentUserSudoerWithoutPasswordRequired(password) check(prov.currentUserCanSudoWithoutPassword()) {
"ERROR: User ${prov.whoami()} cannot sudo without enteringa password."
}
} }
return prov return prov
} }
@ -66,24 +69,36 @@ private fun createRemoteProvInstance(
if (sshWithKey) { if (sshWithKey) {
remote(host, remoteUser) remote(host, remoteUser)
} else { } else {
require( require(password != null) {
password != null, "No password available for provisioning without ssh keys. " +
{ "No password available for provisioning without ssh keys. Either specify provisioning by ssh-keys or provide password." }) "Either specify provisioning by ssh-keys or provide password."
}
remote(host, remoteUser, password) remote(host, remoteUser, password)
} }
if (!prov.currentUserCanSudoWithoutPassword()) { return if (prov.currentUserCanSudoWithoutPassword()) {
require( prov
password != null, } else {
{ "User ${prov.whoami()} not able to sudo on remote machine without password and no password available for the user." })
prov.makeCurrentUserSudoerWithoutPasswordRequired(password)
// a new session is required after making the user a sudoer without password val passwordNonNull = password
return remote(host, remoteUser, 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.)"
} }
return prov
}
// 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
}
}
internal fun getPasswordToConfigureSudoWithoutPassword(): Secret { internal fun getPasswordToConfigureSudoWithoutPassword(): Secret {
return PromptSecretSource("password to configure sudo without password.").secret() return PromptSecretSource("password to configure sudo without password.").secret()