major refactoring of workplace for ddd and common cli reuse, add tests and puml

This commit is contained in:
gittestuser 2021-12-06 21:47:02 +01:00
parent 268c421897
commit 7d26c4c98a
32 changed files with 416 additions and 445 deletions

View file

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

View file

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

View file

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

View file

@ -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())
}

View file

@ -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)
}

View file

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

View file

@ -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)
}

View file

@ -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)
} }
} }

View file

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

View file

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

View file

@ -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")
}
}

View file

@ -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()
}
}

View file

@ -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()
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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()) }
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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) }
}
}