major refactoring of workplace for ddd and common cli reuse, add tests and puml
This commit is contained in:
parent
268c421897
commit
7d26c4c98a
32 changed files with 416 additions and 445 deletions
|
@ -83,7 +83,7 @@ dependencies {
|
||||||
api "ch.qos.logback:logback-core:1.2.5"
|
api "ch.qos.logback:logback-core:1.2.5"
|
||||||
|
|
||||||
testFixturesApi group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.2'
|
testFixturesApi group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.2'
|
||||||
// testImplementation("io.mockk:mockk:1.12.0")
|
testImplementation("io.mockk:mockk:1.12.0")
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
docs/CliApplication.puml
Normal file
52
docs/CliApplication.puml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
@startuml
|
||||||
|
|
||||||
|
autonumber
|
||||||
|
|
||||||
|
skinparam sequenceBox {
|
||||||
|
borderColor White
|
||||||
|
}
|
||||||
|
|
||||||
|
participant User
|
||||||
|
|
||||||
|
box "application" #LightBlue
|
||||||
|
|
||||||
|
participant CliWorkplace
|
||||||
|
participant WorkplaceCliCommand
|
||||||
|
participant Application
|
||||||
|
|
||||||
|
end box
|
||||||
|
|
||||||
|
box "domain" #LightGreen
|
||||||
|
|
||||||
|
participant ProvisionWorkplace
|
||||||
|
participant WorkplaceConfig
|
||||||
|
|
||||||
|
end box
|
||||||
|
|
||||||
|
box "infrastructure" #CornSilk
|
||||||
|
|
||||||
|
participant ConfigRepository
|
||||||
|
participant InfrastructureModules
|
||||||
|
|
||||||
|
end box
|
||||||
|
|
||||||
|
|
||||||
|
User -> CliWorkplace ++ : main(args...)
|
||||||
|
|
||||||
|
CliWorkplace -> WorkplaceCliCommand : parseWorkplaceArguments
|
||||||
|
|
||||||
|
CliWorkplace -> WorkplaceCliCommand : isValid
|
||||||
|
|
||||||
|
CliWorkplace -> ConfigRepository : getConfig
|
||||||
|
WorkplaceConfig <- ConfigRepository : create
|
||||||
|
WorkplaceConfig --> ConfigRepository : config
|
||||||
|
CliWorkplace <-- ConfigRepository : config
|
||||||
|
|
||||||
|
CliWorkplace -> Application : provision
|
||||||
|
Application -> ProvisionWorkplace : provisionWorkplace
|
||||||
|
|
||||||
|
ProvisionWorkplace -> InfrastructureModules: Various calls like:
|
||||||
|
ProvisionWorkplace -> InfrastructureModules: installVirtualBoxGuestAdditions
|
||||||
|
ProvisionWorkplace -> InfrastructureModules: configureNoSwappiness, ...
|
||||||
|
|
||||||
|
@enduml
|
|
@ -31,7 +31,7 @@ fun parseTarget(
|
||||||
programName: String = "java -jar provs.jar",
|
programName: String = "java -jar provs.jar",
|
||||||
args: Array<String>
|
args: Array<String>
|
||||||
): TargetCliCommand {
|
): TargetCliCommand {
|
||||||
val parser = TargetParser(programName)
|
val parser = CliTargetParser(programName)
|
||||||
parser.parse(args)
|
parser.parse(args)
|
||||||
|
|
||||||
return TargetCliCommand(
|
return TargetCliCommand(
|
|
@ -4,7 +4,7 @@ import kotlinx.cli.ArgParser
|
||||||
import kotlinx.cli.ArgType
|
import kotlinx.cli.ArgType
|
||||||
import kotlinx.cli.default
|
import kotlinx.cli.default
|
||||||
|
|
||||||
open class TargetParser(name: String) : ArgParser(name) {
|
open class CliTargetParser(name: String) : ArgParser(name) {
|
||||||
val remoteHost by option(
|
val remoteHost by option(
|
||||||
ArgType.String, shortName =
|
ArgType.String, shortName =
|
||||||
"r", description = "provision to remote host - either localHost or remoteHost must be specified"
|
"r", description = "provision to remote host - either localHost or remoteHost must be specified"
|
|
@ -1,18 +0,0 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.server_compounds.monitoring
|
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.base.NginxConf
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.base.nginxHttpConf
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.provisionNginxStandAlone
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.prometheus.base.configurePrometheusDocker
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.prometheus.base.runPrometheusDocker
|
|
||||||
|
|
||||||
|
|
||||||
@Suppress("unused") // used externally
|
|
||||||
fun Prov.provisionMonitoring() = requireAll {
|
|
||||||
configurePrometheusDocker()
|
|
||||||
runPrometheusDocker()
|
|
||||||
provisionNginxStandAlone(NginxConf.nginxHttpConf())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.server_compounds.monitoring
|
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.base.NginxConf
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.base.nginxAddLocation
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.base.nginxCreateSelfSignedCertificate
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.base.nginxHttpsConfWithLocationFiles
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.nginx.provisionNginxStandAlone
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.prometheus.base.prometheusNginxConfig
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.server_software.standalone_server.prometheus.provisionPrometheusDocker
|
|
||||||
|
|
||||||
|
|
||||||
@Suppress("unused") // used externally
|
|
||||||
fun Prov.provisionNginxMonitoring(nginxHost: String = "localhost") = def {
|
|
||||||
provisionPrometheusDocker(nginxHost)
|
|
||||||
nginxCreateSelfSignedCertificate()
|
|
||||||
provisionNginxStandAlone(NginxConf.nginxHttpsConfWithLocationFiles())
|
|
||||||
nginxAddLocation("443", nginxHost, "/prometheus", prometheusNginxConfig)
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ package org.domaindrivenarchitecture.provs.extensions.server_software.k3s.applic
|
||||||
|
|
||||||
import kotlinx.cli.ArgType
|
import kotlinx.cli.ArgType
|
||||||
import kotlinx.cli.default
|
import kotlinx.cli.default
|
||||||
import org.domaindrivenarchitecture.provs.core.cli.TargetParser
|
import org.domaindrivenarchitecture.provs.core.cli.CliTargetParser
|
||||||
|
|
||||||
class CliK3sArgumentsParser(name: String) : TargetParser(name) {
|
class CliK3sArgumentsParser(name: String) : CliTargetParser(name) {
|
||||||
|
|
||||||
enum class K3sType {
|
enum class K3sType {
|
||||||
K3S, K3D
|
K3S, K3D
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace
|
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.*
|
|
||||||
import org.domaindrivenarchitecture.provs.core.processors.RemoteProcessor
|
|
||||||
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceType
|
|
||||||
import org.domaindrivenarchitecture.provs.extensions.workplace.base.*
|
|
||||||
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.git.provisionGit
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstallFromPpa
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptPurge
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.keys.base.gpgFingerprint
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.keys.provisionKeys
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.PromptSecretSource
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.user.base.currentUserCanSudo
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.user.base.makeUserSudoerWithNoSudoPasswordRequired
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.user.base.whoami
|
|
||||||
import org.domaindrivenarchitecture.provs.workplace.infrastructure.installDevOps
|
|
||||||
import java.net.InetAddress
|
|
||||||
import kotlin.system.exitProcess
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provisions software and configurations for a personal workplace.
|
|
||||||
* Offers the possibility to choose between different types.
|
|
||||||
* Type OFFICE installs office-related software like Thunderbird, LibreOffice, and much more.
|
|
||||||
* Type IDE provides additional software for a development environment, such as Visual Studio Code, IntelliJ, etc.
|
|
||||||
*
|
|
||||||
* Prerequisites: user must be sudoer. If password is required for user to execute sudo, then also parameter userPassword must be provided
|
|
||||||
*
|
|
||||||
* @param workplaceType
|
|
||||||
* @param userPassword only needs to be provided if user cannot sudo without password
|
|
||||||
*/
|
|
||||||
fun Prov.provisionWorkplace(
|
|
||||||
workplaceType: WorkplaceType = WorkplaceType.MINIMAL,
|
|
||||||
ssh: KeyPair? = null,
|
|
||||||
gpg: KeyPair? = null,
|
|
||||||
gitUserName: String? = null,
|
|
||||||
gitEmail: String? = null,
|
|
||||||
userPassword: Secret? = null
|
|
||||||
) = requireAll {
|
|
||||||
|
|
||||||
userPassword?.also { makeUserSudoerWithNoSudoPasswordRequired(it) }
|
|
||||||
|
|
||||||
if (!currentUserCanSudo()) {
|
|
||||||
throw Exception("Current user ${whoami()} cannot execute sudo without entering a password! This is necessary to execute provisionWorkplace")
|
|
||||||
}
|
|
||||||
|
|
||||||
aptInstall("ssh gnupg curl git")
|
|
||||||
|
|
||||||
provisionKeys(gpg, ssh)
|
|
||||||
provisionGit(gitUserName ?: whoami(), gitEmail, gpg?.let { gpgFingerprint(it.publicKey.plain()) })
|
|
||||||
|
|
||||||
installVirtualBoxGuestAdditions()
|
|
||||||
|
|
||||||
aptPurge("remove-power-management xfce4-power-manager " +
|
|
||||||
"xfce4-power-manager-plugins xfce4-power-manager-data")
|
|
||||||
aptPurge("abiword gnumeric")
|
|
||||||
aptPurge("popularity-contest")
|
|
||||||
|
|
||||||
configureNoSwappiness()
|
|
||||||
|
|
||||||
if (workplaceType == WorkplaceType.OFFICE || workplaceType == WorkplaceType.IDE) {
|
|
||||||
aptInstall("seahorse")
|
|
||||||
aptInstall(BASH_UTILS)
|
|
||||||
aptInstall(OS_ANALYSIS)
|
|
||||||
aptInstall(ZIP_UTILS)
|
|
||||||
|
|
||||||
aptInstall("firefox chromium-browser")
|
|
||||||
aptInstall("thunderbird libreoffice")
|
|
||||||
aptInstall("xclip")
|
|
||||||
|
|
||||||
installZimWiki()
|
|
||||||
installGopass()
|
|
||||||
aptInstallFromPpa("nextcloud-devs", "client", "nextcloud-client")
|
|
||||||
|
|
||||||
aptInstall("inkscape")
|
|
||||||
aptInstall("dia")
|
|
||||||
|
|
||||||
aptInstall(SPELLCHECKING_DE)
|
|
||||||
|
|
||||||
installRedshift()
|
|
||||||
configureRedshift()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (workplaceType == WorkplaceType.IDE) {
|
|
||||||
|
|
||||||
aptInstall(JAVA_JDK)
|
|
||||||
|
|
||||||
aptInstall(OPEN_VPM)
|
|
||||||
aptInstall(OPENCONNECT)
|
|
||||||
aptInstall(VPNC)
|
|
||||||
|
|
||||||
installDocker()
|
|
||||||
|
|
||||||
// IDEs
|
|
||||||
cmd("sudo snap install intellij-idea-community --classic")
|
|
||||||
installVSC("python", "clojure")
|
|
||||||
|
|
||||||
installDevOps()
|
|
||||||
}
|
|
||||||
|
|
||||||
ProvResult(true) // dummy
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provisions a workplace on a remote machine.
|
|
||||||
* Prerequisite: you have built the uberjar by ./gradlew uberJarLatest
|
|
||||||
* The remote host and remote user are specified by args parameters.
|
|
||||||
* The first argument specifies hostName or IP-Address of the remote machine,
|
|
||||||
* the second argument defines the user on the remote machine for whom the workplace is provisioned;
|
|
||||||
* You can invoke this method e.g. using the jar-file from the project root by:
|
|
||||||
* java -jar build/libs/provs-extensions-uber.jar org.domaindrivenarchitecture.provs.ubuntu.extensions.workplace.ProvisionWorkplaceKt provisionRemote <ip> <user>
|
|
||||||
* You will be prompted for the password of the remote user.
|
|
||||||
*
|
|
||||||
* @param args host and userName of the remote machine as the first resp. second argument
|
|
||||||
*/
|
|
||||||
fun provisionRemote(args: Array<String>) {
|
|
||||||
if (args.size != 2) {
|
|
||||||
println("Please specify host and user.")
|
|
||||||
exitProcess(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
val host = InetAddress.getByName(args[0])
|
|
||||||
val userName = args[1]
|
|
||||||
val pwSecret = PromptSecretSource("Password for user $userName on $host").secret()
|
|
||||||
val pwFromSecret = Password(pwSecret.plain())
|
|
||||||
|
|
||||||
val config = getConfig()
|
|
||||||
Prov.newInstance(RemoteProcessor(host, userName, pwFromSecret)).provisionWorkplace(
|
|
||||||
config.type,
|
|
||||||
config.ssh?.keyPair(),
|
|
||||||
config.gpg?.keyPair(),
|
|
||||||
config.gitUserName,
|
|
||||||
config.gitEmail,
|
|
||||||
pwFromSecret
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provisions a workplace on a remote machine by calling method provisionRemote.
|
|
||||||
*
|
|
||||||
* @ see #provisionRemote(args: Array<String>)
|
|
||||||
*
|
|
||||||
* You can invoke this method e.g. using the jar-file from the project root by:
|
|
||||||
* java -jar build/libs/provs-ext-latest.jar workplace.WorkplaceKt main
|
|
||||||
*
|
|
||||||
* @param args host and userName of the remote machine as first resp. second argument
|
|
||||||
*/
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
provisionRemote(args = args)
|
|
||||||
}
|
|
|
@ -1,15 +1,14 @@
|
||||||
package org.domaindrivenarchitecture.provs.workplace.application
|
package org.domaindrivenarchitecture.provs.workplace.application
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.Secret
|
import org.domaindrivenarchitecture.provs.workplace.domain.provisionWorkplace
|
||||||
import org.domaindrivenarchitecture.provs.extensions.workplace.provisionWorkplace
|
|
||||||
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceConfig
|
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceConfig
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use case for provisioning a workplace
|
* Use case for provisioning a workplace
|
||||||
*/
|
*/
|
||||||
fun Prov.provision(conf: WorkplaceConfig, password: Secret?) = def {
|
fun Prov.provision(conf: WorkplaceConfig) = def {
|
||||||
with (conf) {
|
with (conf) {
|
||||||
provisionWorkplace(type, ssh?.keyPair(), gpg?.keyPair(), gitUserName, gitEmail, password)
|
provisionWorkplace(type, ssh?.keyPair(), gpg?.keyPair(), gitUserName, gitEmail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
package org.domaindrivenarchitecture.provs.workplace.application
|
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Secret
|
|
||||||
import org.domaindrivenarchitecture.provs.core.local
|
|
||||||
import org.domaindrivenarchitecture.provs.core.remote
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.GopassSecretSource
|
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.PromptSecretSource
|
|
||||||
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provisions according to the options either a meissa workplace, reposOnly or gopassOnly.
|
|
||||||
* Locally or on a remote machine. If remotely, the remote host and remote user are specified by args parameters.
|
|
||||||
*/
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
val cliCommand = parseCli(args)
|
|
||||||
if (cliCommand.isValid()) {
|
|
||||||
provision(cliCommand)
|
|
||||||
} else {
|
|
||||||
println("Invalid command line options.\nPlease use option -h for help.")
|
|
||||||
System.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun provision(cliCommand: CliCommand) {
|
|
||||||
val filename = cliCommand.configFileName
|
|
||||||
|
|
||||||
// TODO: improve exceptions
|
|
||||||
try {
|
|
||||||
val conf = getConfig(filename)
|
|
||||||
val password: Secret? = retrievePassword(cliCommand)
|
|
||||||
val prov: Prov = createProvInstance(cliCommand, password)
|
|
||||||
|
|
||||||
prov.provision(conf, password)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
println(
|
|
||||||
"Error: File\u001b[31m $filename \u001b[0m was not found.\n" +
|
|
||||||
"Pls copy file \u001B[31m WorkplaceConfigExample.yaml \u001B[0m to file \u001B[31m $filename \u001B[0m " +
|
|
||||||
"and change the content according to your needs.\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
// provide example config
|
|
||||||
File("WorkplaceConfigExample.yaml").writeText("type: \"MINIMAL\"\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createProvInstance(
|
|
||||||
cliCommand: CliCommand,
|
|
||||||
password: Secret?
|
|
||||||
): Prov {
|
|
||||||
if (cliCommand.isValid()) {
|
|
||||||
if (cliCommand.isValidRemote()) {
|
|
||||||
val host = cliCommand.remoteHost!!
|
|
||||||
val remoteUser = cliCommand.userName!!
|
|
||||||
if (cliCommand.sshWithKey) {
|
|
||||||
return remote(host, remoteUser)
|
|
||||||
} else {
|
|
||||||
require(
|
|
||||||
password != null,
|
|
||||||
{ "No password available for provisioning without ssh keys. Either specify provisioning by ssh-keys or provide password." })
|
|
||||||
return remote(host, remoteUser, password)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return local()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw RuntimeException("Invalid cliCommand")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun retrievePassword(cliCommand: CliCommand): Secret? {
|
|
||||||
var password: Secret? = null
|
|
||||||
if (cliCommand.isValidRemote()) {
|
|
||||||
if (cliCommand.sshWithPasswordPrompt) {
|
|
||||||
password =
|
|
||||||
PromptSecretSource("Password for user ${cliCommand.userName!!} on ${cliCommand.remoteHost!!}").secret()
|
|
||||||
} else if (cliCommand.sshWithGopassPath != null) {
|
|
||||||
password = GopassSecretSource(cliCommand.sshWithGopassPath).secret()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return password
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
package org.domaindrivenarchitecture.provs.workplace.application
|
|
||||||
|
|
||||||
import kotlinx.cli.ArgParser
|
|
||||||
import kotlinx.cli.ArgType
|
|
||||||
import kotlinx.cli.default
|
|
||||||
import kotlinx.cli.optional
|
|
||||||
|
|
||||||
class CliCommand(
|
|
||||||
val remoteHost: String?,
|
|
||||||
val localHost: Boolean?,
|
|
||||||
val userName: String?,
|
|
||||||
val sshWithGopassPath: String?,
|
|
||||||
val sshWithPasswordPrompt: Boolean,
|
|
||||||
val sshWithKey: Boolean,
|
|
||||||
_configFileName: String?
|
|
||||||
) {
|
|
||||||
val configFileName: String
|
|
||||||
|
|
||||||
init {
|
|
||||||
configFileName = _configFileName ?: "WorkplaceConfig.yaml"
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isValidLocalhost(): Boolean {
|
|
||||||
return (localHost ?: false) && remoteHost == null && userName == null && sshWithGopassPath == null &&
|
|
||||||
!sshWithPasswordPrompt && !sshWithKey
|
|
||||||
}
|
|
||||||
|
|
||||||
fun hasValidPasswordOption(): Boolean {
|
|
||||||
return (sshWithGopassPath != null) xor sshWithPasswordPrompt xor sshWithKey
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isValidRemote(): Boolean {
|
|
||||||
return remoteHost != null && userName != null && hasValidPasswordOption()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isValid(): Boolean {
|
|
||||||
return (isValidLocalhost() || isValidRemote())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun parseCli(args: Array<String>): CliCommand {
|
|
||||||
val parser = ArgParser("java -jar provs.jar")
|
|
||||||
|
|
||||||
val remoteHost by parser.option(
|
|
||||||
ArgType.String, shortName =
|
|
||||||
"r", description = "provision to remote host - either localHost or remoteHost must be specified"
|
|
||||||
)
|
|
||||||
val localHost by parser.option(
|
|
||||||
ArgType.Boolean, shortName =
|
|
||||||
"l", description = "provision to local machine - either localHost or remoteHost must be specified"
|
|
||||||
)
|
|
||||||
val configFileName by parser.option(
|
|
||||||
ArgType.String,
|
|
||||||
shortName = "c",
|
|
||||||
description = "the config file name to apply"
|
|
||||||
).default("WorkplaceConfig.yaml")
|
|
||||||
val userName by parser.option(
|
|
||||||
ArgType.String,
|
|
||||||
shortName = "u",
|
|
||||||
description = "user for remote provisioning."
|
|
||||||
)
|
|
||||||
val sshWithGopassPath by parser.option(
|
|
||||||
ArgType.String,
|
|
||||||
shortName = "p",
|
|
||||||
description = "password stored at gopass path"
|
|
||||||
)
|
|
||||||
val sshWithPasswordPrompt by parser.option(
|
|
||||||
ArgType.Boolean,
|
|
||||||
shortName = "i",
|
|
||||||
description = "prompt for password interactive"
|
|
||||||
).default(false)
|
|
||||||
val sshWithKey by parser.option(
|
|
||||||
ArgType.Boolean,
|
|
||||||
shortName = "k",
|
|
||||||
description = "provision over ssh using user & ssh key"
|
|
||||||
).default(false)
|
|
||||||
parser.parse(args)
|
|
||||||
val cliCommand =
|
|
||||||
CliCommand(
|
|
||||||
remoteHost, localHost, userName, sshWithGopassPath, sshWithPasswordPrompt, sshWithKey, configFileName
|
|
||||||
)
|
|
||||||
return cliCommand
|
|
||||||
}
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.domaindrivenarchitecture.provs.workplace.application
|
||||||
|
|
||||||
|
import org.domaindrivenarchitecture.provs.core.cli.createProvInstance
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.application.WorkplaceCliCommand.Companion.parseWorkplaceArguments
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provisions according to the options either a meissa workplace, reposOnly or gopassOnly.
|
||||||
|
* Locally or on a remote machine. If remotely, the remote host and remote user are specified by args parameters.
|
||||||
|
*/
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
val cmd = parseWorkplaceArguments("java -jar provs.jar", args)
|
||||||
|
if (!cmd.isValid()) {
|
||||||
|
println("Arguments are not valid, pls try -h for help.")
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
provisionWorkplace(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun provisionWorkplace(cliCommand: WorkplaceCliCommand) {
|
||||||
|
val filename = cliCommand.configFile
|
||||||
|
|
||||||
|
try {
|
||||||
|
val conf = getConfig(filename)
|
||||||
|
|
||||||
|
val prov = createProvInstance(cliCommand.target)
|
||||||
|
prov.provision(conf)
|
||||||
|
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
println(
|
||||||
|
"Error: File\u001b[31m $filename \u001b[0m was not found.\n" +
|
||||||
|
"Pls copy file \u001B[31m WorkplaceConfigExample.yaml \u001B[0m to file \u001B[31m $filename \u001B[0m " +
|
||||||
|
"and change the content according to your needs.\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
// provide example config
|
||||||
|
File("WorkplaceConfigExample.yaml").writeText("type: \"MINIMAL\"\n")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.domaindrivenarchitecture.provs.workplace.application
|
||||||
|
|
||||||
|
import org.domaindrivenarchitecture.provs.core.cli.TargetCliCommand
|
||||||
|
|
||||||
|
|
||||||
|
class WorkplaceCliCommand(val configFile: String, val target: TargetCliCommand) {
|
||||||
|
companion object {
|
||||||
|
fun parseWorkplaceArguments(
|
||||||
|
programName: String = "java -jar provs.jar",
|
||||||
|
args: Array<String>
|
||||||
|
): WorkplaceCliCommand {
|
||||||
|
val parser = CliWorkplaceParser(programName)
|
||||||
|
parser.parse(args)
|
||||||
|
|
||||||
|
return WorkplaceCliCommand(
|
||||||
|
parser.configFileName ?: "WorkplaceConfig.yaml",
|
||||||
|
TargetCliCommand(
|
||||||
|
parser.localHost,
|
||||||
|
parser.remoteHost,
|
||||||
|
parser.userName,
|
||||||
|
parser.sshWithPasswordPrompt,
|
||||||
|
parser.sshWithGopassPath,
|
||||||
|
parser.sshWithKey
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isValid(): Boolean {
|
||||||
|
return target.isValid()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.domaindrivenarchitecture.provs.workplace.application
|
||||||
|
|
||||||
|
import kotlinx.cli.ArgType
|
||||||
|
import kotlinx.cli.optional
|
||||||
|
import org.domaindrivenarchitecture.provs.core.cli.CliTargetParser
|
||||||
|
|
||||||
|
class CliWorkplaceParser(name: String) : CliTargetParser(name) {
|
||||||
|
val configFileName by argument(
|
||||||
|
ArgType.String,
|
||||||
|
"configFilename",
|
||||||
|
"the filename containing the yaml config for the workplace"
|
||||||
|
).optional()
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package org.domaindrivenarchitecture.provs.workplace.domain
|
||||||
|
|
||||||
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.git.provisionGit
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstallFromPpa
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptPurge
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.keys.base.gpgFingerprint
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.keys.provisionKeys
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.user.base.currentUserCanSudo
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.user.base.whoami
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.*
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provisions software and configurations for a personal workplace.
|
||||||
|
* Offers the possibility to choose between different types.
|
||||||
|
* Type OFFICE installs office-related software like Thunderbird, LibreOffice, and much more.
|
||||||
|
* Type IDE provides additional software for a development environment, such as Visual Studio Code, IntelliJ, etc.
|
||||||
|
*
|
||||||
|
* Prerequisites: user must be able to sudo without entering the password
|
||||||
|
*/
|
||||||
|
fun Prov.provisionWorkplace(
|
||||||
|
workplaceType: WorkplaceType = WorkplaceType.MINIMAL,
|
||||||
|
ssh: KeyPair? = null,
|
||||||
|
gpg: KeyPair? = null,
|
||||||
|
gitUserName: String? = null,
|
||||||
|
gitEmail: String? = null
|
||||||
|
) = requireAll {
|
||||||
|
|
||||||
|
if (!currentUserCanSudo()) {
|
||||||
|
throw Exception("Current user ${whoami()} cannot execute sudo without entering a password! This is necessary to execute provisionWorkplace")
|
||||||
|
}
|
||||||
|
|
||||||
|
aptInstall("ssh gnupg curl git")
|
||||||
|
|
||||||
|
provisionKeys(gpg, ssh)
|
||||||
|
provisionGit(gitUserName ?: whoami(), gitEmail, gpg?.let { gpgFingerprint(it.publicKey.plain()) })
|
||||||
|
|
||||||
|
installVirtualBoxGuestAdditions()
|
||||||
|
|
||||||
|
aptPurge(
|
||||||
|
"remove-power-management xfce4-power-manager " +
|
||||||
|
"xfce4-power-manager-plugins xfce4-power-manager-data"
|
||||||
|
)
|
||||||
|
aptPurge("abiword gnumeric")
|
||||||
|
aptPurge("popularity-contest")
|
||||||
|
|
||||||
|
configureNoSwappiness()
|
||||||
|
|
||||||
|
if (workplaceType == WorkplaceType.OFFICE || workplaceType == WorkplaceType.IDE) {
|
||||||
|
aptInstall("seahorse")
|
||||||
|
aptInstall(BASH_UTILS)
|
||||||
|
aptInstall(OS_ANALYSIS)
|
||||||
|
aptInstall(ZIP_UTILS)
|
||||||
|
|
||||||
|
aptInstall("firefox chromium-browser")
|
||||||
|
aptInstall("thunderbird libreoffice")
|
||||||
|
aptInstall("xclip")
|
||||||
|
|
||||||
|
installZimWiki()
|
||||||
|
installGopass()
|
||||||
|
aptInstallFromPpa("nextcloud-devs", "client", "nextcloud-client")
|
||||||
|
|
||||||
|
aptInstall("inkscape")
|
||||||
|
aptInstall("dia")
|
||||||
|
|
||||||
|
aptInstall(SPELLCHECKING_DE)
|
||||||
|
|
||||||
|
installRedshift()
|
||||||
|
configureRedshift()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (workplaceType == WorkplaceType.IDE) {
|
||||||
|
|
||||||
|
aptInstall(JAVA_JDK)
|
||||||
|
|
||||||
|
aptInstall(OPEN_VPM)
|
||||||
|
aptInstall(OPENCONNECT)
|
||||||
|
aptInstall(VPNC)
|
||||||
|
|
||||||
|
installDocker()
|
||||||
|
|
||||||
|
// IDEs
|
||||||
|
cmd("sudo snap install intellij-idea-community --classic")
|
||||||
|
installVSC("python", "clojure")
|
||||||
|
|
||||||
|
installDevOps()
|
||||||
|
}
|
||||||
|
|
||||||
|
ProvResult(true) // dummy
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.ProvResult
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.ProvResult
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.addTextToFile
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.addTextToFile
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
val OS_ANALYSIS = "lsof strace ncdu iptraf htop iotop iftop"
|
val OS_ANALYSIS = "lsof strace ncdu iptraf htop iotop iftop"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
|
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.ProvResult
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.ProvResult
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
|
@ -1,4 +1,4 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Prov
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
import org.domaindrivenarchitecture.provs.core.ProvResult
|
import org.domaindrivenarchitecture.provs.core.ProvResult
|
|
@ -1,61 +1,75 @@
|
||||||
//package org.domaindrivenarchitecture.provs.core.cli
|
package org.domaindrivenarchitecture.provs.core.cli
|
||||||
//
|
|
||||||
//import io.mockk.every
|
import io.mockk.every
|
||||||
//import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
//import io.mockk.verify
|
import io.mockk.unmockkStatic
|
||||||
//import org.domaindrivenarchitecture.provs.core.Prov
|
import io.mockk.verify
|
||||||
//import org.domaindrivenarchitecture.provs.core.Secret
|
import org.domaindrivenarchitecture.provs.core.Prov
|
||||||
//import org.domaindrivenarchitecture.provs.core.local
|
import org.domaindrivenarchitecture.provs.core.Secret
|
||||||
//import org.domaindrivenarchitecture.provs.core.processors.PrintOnlyProcessor
|
import org.domaindrivenarchitecture.provs.core.local
|
||||||
//import org.domaindrivenarchitecture.provs.core.remote
|
import org.domaindrivenarchitecture.provs.core.processors.PrintOnlyProcessor
|
||||||
//import org.junit.jupiter.api.Test
|
import org.domaindrivenarchitecture.provs.core.remote
|
||||||
//
|
import org.junit.jupiter.api.AfterAll
|
||||||
//internal class CliCommandKtTest {
|
import org.junit.jupiter.api.BeforeAll
|
||||||
//
|
import org.junit.jupiter.api.Test
|
||||||
// @Test
|
|
||||||
// fun createProvInstance_local() {
|
internal class CliTargetCommandKtTest {
|
||||||
// mockkStatic(::local)
|
|
||||||
//
|
companion object {
|
||||||
// // given
|
@BeforeAll
|
||||||
// val cliCommand = CliCommand(true, null, null, false, null, false)
|
@JvmStatic
|
||||||
//
|
internal fun beforeAll() {
|
||||||
// // when
|
mockkStatic(::local)
|
||||||
// createProvInstance(cliCommand)
|
mockkStatic(::remote)
|
||||||
//
|
every { remote(any(), any(), any(), any()) } returns Prov.newInstance(PrintOnlyProcessor())
|
||||||
// // then
|
|
||||||
// verify { local() }
|
mockkStatic(::retrievePassword)
|
||||||
// }
|
every { retrievePassword(any()) } returns Secret("sec")
|
||||||
//
|
}
|
||||||
// @Test
|
|
||||||
// fun createProvInstance_remote_with_sshKey() {
|
@AfterAll
|
||||||
// mockkStatic(::remote)
|
@JvmStatic
|
||||||
// every { remote(any(), any(), any(), any()) } returns Prov.newInstance(PrintOnlyProcessor())
|
internal fun afterAll() {
|
||||||
//
|
unmockkStatic(::local)
|
||||||
// // given
|
unmockkStatic(::remote)
|
||||||
// val cliCommand = CliCommand(false, "host123", "user123", false, null, true)
|
unmockkStatic(::retrievePassword)
|
||||||
//
|
}
|
||||||
// // when
|
}
|
||||||
// createProvInstance(cliCommand)
|
|
||||||
//
|
|
||||||
// // then
|
@Test
|
||||||
// verify { remote("host123", "user123", null, any()) }
|
fun createProvInstance_local() {
|
||||||
// }
|
// given
|
||||||
//
|
val cliCommand = TargetCliCommand(true, null, null, false, null, false)
|
||||||
// @Test
|
|
||||||
// fun createProvInstance_remote_with_interactive_password_retrieval() {
|
// when
|
||||||
// mockkStatic(::remote)
|
createProvInstance(cliCommand)
|
||||||
// every { remote(any(), any(), any(), any()) } returns Prov.newInstance(PrintOnlyProcessor())
|
|
||||||
//
|
// then
|
||||||
// mockkStatic(::retrievePassword)
|
verify { local() }
|
||||||
// every { retrievePassword(any()) } returns Secret("sec")
|
}
|
||||||
//
|
|
||||||
// // given
|
@Test
|
||||||
// val cliCommand = CliCommand(false, "host123", "user123", true, null, false)
|
fun createProvInstance_remote_with_sshKey() {
|
||||||
//
|
// given
|
||||||
// // when
|
val cliCommand = TargetCliCommand(false, "host123", "user123", false, null, true)
|
||||||
// createProvInstance(cliCommand)
|
|
||||||
//
|
// when
|
||||||
// // then
|
createProvInstance(cliCommand)
|
||||||
// verify { remote("host123", "user123", Secret("sec"), any()) }
|
|
||||||
// }
|
// then
|
||||||
//}
|
verify { remote("host123", "user123", null, any()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createProvInstance_remote_with_interactive_password_retrieval() {
|
||||||
|
// given
|
||||||
|
val cliCommand = TargetCliCommand(false, "host123", "user123", true, null, false)
|
||||||
|
|
||||||
|
// when
|
||||||
|
createProvInstance(cliCommand)
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify { remote("host123", "user123", Secret("sec"), any()) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package org.domaindrivenarchitecture.provs.extensions.workplace
|
package org.domaindrivenarchitecture.provs.extensions.workplace
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.core.Password
|
|
||||||
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceType
|
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
||||||
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceType
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.domain.provisionWorkplace
|
||||||
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
||||||
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
internal class ProvisionWorkplaceKtTest {
|
internal class ProvisionWorkplaceKtTest {
|
||||||
|
|
||||||
|
@ -21,8 +21,7 @@ internal class ProvisionWorkplaceKtTest {
|
||||||
val res = a.provisionWorkplace(
|
val res = a.provisionWorkplace(
|
||||||
WorkplaceType.MINIMAL,
|
WorkplaceType.MINIMAL,
|
||||||
gitUserName = "testuser",
|
gitUserName = "testuser",
|
||||||
gitEmail = "testuser@test.org",
|
gitEmail = "testuser@test.org"
|
||||||
userPassword = Password("testuser")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.domaindrivenarchitecture.provs.extensions.workplace.base
|
||||||
|
|
||||||
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
||||||
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.installFakturama
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.domaindrivenarchitecture.provs.extensions.test_keys.privateGPGSnakeoilKey
|
import org.domaindrivenarchitecture.provs.extensions.test_keys.privateGPGSnakeoilKey
|
||||||
import org.domaindrivenarchitecture.provs.extensions.test_keys.publicGPGSnakeoilKey
|
import org.domaindrivenarchitecture.provs.extensions.test_keys.publicGPGSnakeoilKey
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.configureGopassBridgeJsonApi
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.downloadGopassBridge
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.installGopass
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.installGopassBridgeJsonApi
|
||||||
|
|
||||||
|
|
||||||
internal class GopassBridgeKtTest {
|
internal class GopassBridgeKtTest {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.domaindrivenarchitecture.provs.extensions.test_keys.privateGPGSnakeoilKey
|
import org.domaindrivenarchitecture.provs.extensions.test_keys.privateGPGSnakeoilKey
|
||||||
import org.domaindrivenarchitecture.provs.extensions.test_keys.publicGPGSnakeoilKey
|
import org.domaindrivenarchitecture.provs.extensions.test_keys.publicGPGSnakeoilKey
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.*
|
||||||
|
|
||||||
|
|
||||||
internal class GopassKtTest {
|
internal class GopassKtTest {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Disabled
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.installVSC
|
||||||
|
|
||||||
|
|
||||||
internal class VSCodeKtTest {
|
internal class VSCodeKtTest {
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package org.domaindrivenarchitecture.provs.workplace.application
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.unmockkStatic
|
||||||
|
import io.mockk.verify
|
||||||
|
import org.domaindrivenarchitecture.provs.core.*
|
||||||
|
import org.domaindrivenarchitecture.provs.core.cli.retrievePassword
|
||||||
|
import org.domaindrivenarchitecture.provs.core.processors.PrintOnlyProcessor
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceConfig
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceType
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.domain.provisionWorkplace
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
||||||
|
import org.junit.jupiter.api.AfterAll
|
||||||
|
import org.junit.jupiter.api.BeforeAll
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
internal class CliWorkplaceKtTest {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val printOnlyProv = Prov.newInstance(PrintOnlyProcessor())
|
||||||
|
val testConfig = WorkplaceConfig(WorkplaceType.MINIMAL, gitUserName = "gittestuser", gitEmail = "git@test.mail")
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
@JvmStatic
|
||||||
|
internal fun beforeAll() {
|
||||||
|
mockkStatic(::local)
|
||||||
|
every { local() } returns printOnlyProv
|
||||||
|
|
||||||
|
mockkStatic(::remote)
|
||||||
|
every { remote(any(), any(), any(), any()) } returns printOnlyProv
|
||||||
|
|
||||||
|
mockkStatic(::getConfig)
|
||||||
|
every { getConfig("testconfig.yaml") } returns testConfig
|
||||||
|
|
||||||
|
mockkStatic(Prov::provisionWorkplace)
|
||||||
|
every { any<Prov>().provisionWorkplace(any(), any(), any(), any(), any()) } returns ProvResult(true, cmd = "mocked command")
|
||||||
|
|
||||||
|
mockkStatic(::retrievePassword)
|
||||||
|
every { retrievePassword(any()) } returns Secret("sec")
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
@JvmStatic
|
||||||
|
internal fun afterAll() {
|
||||||
|
unmockkStatic(::local)
|
||||||
|
unmockkStatic(::remote)
|
||||||
|
unmockkStatic(::getConfig)
|
||||||
|
unmockkStatic(Prov::provisionWorkplace)
|
||||||
|
unmockkStatic(::retrievePassword)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun provision_workplace_locally() {
|
||||||
|
// when
|
||||||
|
main(arrayOf("-l", "testconfig.yaml"))
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify { any<Prov>().provisionWorkplace(WorkplaceType.MINIMAL, null, null, testConfig.gitUserName, testConfig.gitEmail) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun provision_workplace_remotely() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
main(arrayOf("-i", "-r", "host123", "-u", "user123", "testconfig.yaml"))
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify { remote("host123", "user123", Secret("sec"), any()) }
|
||||||
|
verify { any<Prov>().provisionWorkplace(WorkplaceType.MINIMAL, null, null, testConfig.gitUserName, testConfig.gitEmail) }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue