diff --git a/.classpath b/.classpath
deleted file mode 100644
index fc44fba..0000000
--- a/.classpath
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.project b/.project
deleted file mode 100644
index 2820e02..0000000
--- a/.project
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
- provs-core
- Project provs-core created by Buildship.
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.buildship.core.gradleprojectbuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
- org.eclipse.buildship.core.gradleprojectnature
-
-
-
- 1628357951205
-
- 30
-
- org.eclipse.core.resources.regexFilterMatcher
- node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
-
-
-
-
diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs
deleted file mode 100644
index 2b6d83b..0000000
--- a/.settings/org.eclipse.buildship.core.prefs
+++ /dev/null
@@ -1,13 +0,0 @@
-arguments=
-auto.sync=false
-build.scans.enabled=false
-connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
-connection.project.dir=
-eclipse.preferences.version=1
-gradle.user.home=
-java.home=/usr/lib/jvm/java-11-openjdk-amd64
-jvm.arguments=
-offline.mode=false
-override.workspace.settings=true
-show.console.view=true
-show.executions.view=true
diff --git a/bin/main/logback.xml b/bin/main/logback.xml
deleted file mode 100644
index 2dd0fdb..0000000
--- a/bin/main/logback.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
- System.err
-
- WARN
-
-
- %d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{35}) - %msg %n
-
-
-
-
- System.out
-
- DEBUG
-
-
- %d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{35}) - %msg %n
-
-
-
-
- ./logs/provs-${byTime}.log
-
- ./logs/provs-%d{yyyy-MM-dd}.%i.log
- 10MB
- 3
- 1GB
-
- true
-
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/Prov.kt b/bin/main/org/domaindrivenarchitecture/provs/core/Prov.kt
deleted file mode 100644
index ca7d06b..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/Prov.kt
+++ /dev/null
@@ -1,439 +0,0 @@
-package org.domaindrivenarchitecture.provs.core
-
-import org.domaindrivenarchitecture.provs.core.platforms.SHELL
-import org.domaindrivenarchitecture.provs.core.platforms.UbuntuProv
-import org.domaindrivenarchitecture.provs.core.platforms.WinProv
-import org.domaindrivenarchitecture.provs.core.processors.LocalProcessor
-import org.domaindrivenarchitecture.provs.core.processors.Processor
-import org.slf4j.LoggerFactory
-
-
-enum class ProgressType { NONE, DOTS, BASIC, FULL_LOG }
-enum class ResultMode { NONE, LAST, ALL, FAILEXIT }
-enum class OS { WINDOWS, LINUX }
-
-
-/**
- * This main class offers methods to execute shell commands.
- * The commands are executed locally, remotely (via ssh) or in a docker container
- * depending on the processor which is passed to the constructor.
- */
-open class Prov protected constructor(
- private val processor: Processor,
- val name: String? = null,
- private val progressType: ProgressType = ProgressType.BASIC
-) {
- init {
- if (progressType == ProgressType.FULL_LOG) {
- val log = LoggerFactory.getILoggerFactory()
- .getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME) as (ch.qos.logback.classic.Logger)
- log.level = ch.qos.logback.classic.Level.INFO
- }
- }
-
- companion object Factory {
-
- private lateinit var defaultProvInstance: Prov
-
- fun defaultInstance(platform: String? = null): Prov {
- return if (Factory::defaultProvInstance.isInitialized) {
- defaultProvInstance
- } else {
- defaultProvInstance = newInstance(platform = platform, name = "default instance")
- defaultProvInstance
- }
- }
-
- fun newInstance(
- processor: Processor = LocalProcessor(),
- platform: String? = null,
- name: String? = null,
- progressType: ProgressType = ProgressType.BASIC
- ): Prov {
-
- val os = platform ?: System.getProperty("os.name")
-
- return when {
- os.toUpperCase().contains(OS.LINUX.name) -> UbuntuProv(processor, name, progressType)
- os.toUpperCase().contains(OS.WINDOWS.name) -> WinProv(processor, name, progressType)
- else -> throw Exception("OS not supported")
- }
- }
- }
-
-
- private val internalResults = arrayListOf()
- private var level = 0
- private var previousLevel = 0
- private var exit = false
- private var runInContainerWithName: String? = null
-
-
- /**
- * defines a task with default success behavior, i.e. returns success if all subtasks finished with success.
- * Same as requireAll.
- */
- fun def(a: Prov.() -> ProvResult): ProvResult {
- return handle(ResultMode.ALL) { a() }
- }
-
- /**
- * defines a task, which returns success if the the last subtasks or last value returns success
- */
- fun requireLast(a: Prov.() -> ProvResult): ProvResult {
- return handle(ResultMode.LAST) { a() }
- }
-
- /**
- * defines a task, which always returns success
- */
- fun optional(a: Prov.() -> ProvResult): ProvResult {
- return handle(ResultMode.NONE) { a() }
- }
-
- /**
- * defines a task, which returns success if all subtasks finished with success
- */
- fun requireAll(a: Prov.() -> ProvResult): ProvResult {
- return handle(ResultMode.ALL) { a() }
- }
-
- /**
- * defines a task, which exits the overall execution on failure
- */
- fun exitOnFailure(a: Prov.() -> ProvResult): ProvResult {
- return handle(ResultMode.FAILEXIT) { a() }
- }
-
- // todo: add sudo and update test
- fun inContainer(containerName: String, a: Prov.() -> ProvResult): ProvResult {
- runInContainerWithName = containerName
- val res = handle(ResultMode.ALL) { a() }
- runInContainerWithName = null
- return res
- }
-
-
- /**
- * execute program with parameters
- */
- fun xec(vararg s: String): ProvResult {
- val cmd = runInContainerWithName?.let { cmdInContainer(it, *s) } ?: s
- val result = processor.x(*cmd)
- return ProvResult(
- success = (result.exitCode == 0),
- cmd = result.argsToString(),
- out = result.out,
- err = result.err
- )
- }
-
- /**
- * execute program with parameters without logging (to be used if secrets are involved)
- */
- fun xecNoLog(vararg s: String): ProvResult {
- val cmd = runInContainerWithName?.let { cmdInContainer(it, *s) } ?: s
- val result = processor.xNoLog(*cmd)
- return ProvResult(
- success = (result.exitCode == 0),
- cmd = "***",
- out = result.out,
- err = "***"
- )
- }
-
-
- /**
- * Executes a command by using the shell.
- * Be aware: Executing shell commands that incorporate unsanitized input from an untrusted source
- * makes a program vulnerable to shell injection, a serious security flaw which can result in arbitrary command execution.
- * Thus, the use of this method is strongly discouraged in cases where the command string is constructed from external input.
- */
- open fun cmd(cmd: String, dir: String? = null, sudo: Boolean = false): ProvResult {
- throw Exception("Not implemented")
- }
-
-
- /**
- * Same as method cmd but without logging of the result/output, should be used e.g. if secrets are involved.
- * Attention: only result is NOT logged the executed command still is.
- */
- open fun cmdNoLog(cmd: String, dir: String? = null, sudo: Boolean = false): ProvResult {
- throw Exception("Not implemented")
- }
-
-
- /**
- * Same as method cmd but without evaluating the result for the overall success.
- * Can be used e.g. for checks which might succeed or fail but where failure should not influence overall success
- */
- open fun cmdNoEval(cmd: String, dir: String? = null, sudo: Boolean = false): ProvResult {
- throw Exception("Not implemented")
- }
-
-
- /**
- * Executes command cmd and returns true in case of success else false.
- * The success resp. failure is not evaluated, i.e. it is not taken into account for the overall success.
- */
- fun chk(cmd: String, dir: String? = null): Boolean {
- return cmdNoEval(cmd, dir).success
- }
-
-
- /**
- * Retrieve a secret by executing the given command.
- * Returns the result of the command as secret.
- */
- fun getSecret(command: String): Secret? {
- val result = cmdNoLog(command)
- return if (result.success && result.out != null) {
- addResultToEval(ProvResult(true, getCallingMethodName()))
- Secret(result.out)
- } else {
- addResultToEval(ProvResult(false, getCallingMethodName(), err = result.err, exception = result.exception))
- null
- }
- }
-
-
- /**
- * Adds a ProvResult to the overall success evaluation.
- * Intended for use in methods which do not automatically add results.
- */
- fun addResultToEval(result: ProvResult) = requireAll {
- result
- }
-
- /**
- * Executes multiple shell commands. Each command must be in its own line.
- * Multi-line commands within the script are not supported.
- * Empty lines and comments (all text behind # in a line) are supported, i.e. they are ignored.
- */
- fun sh(script: String, dir: String? = null, sudo: Boolean = false) = def {
- val lines = script.trimIndent().replace("\r\n", "\n").split("\n")
- val linesWithoutComments = lines.stream().map { it.split("#")[0] }
- val linesNonEmpty = linesWithoutComments.filter { it.trim().isNotEmpty() }
-
- var success = true
-
- for (cmd in linesNonEmpty) {
- if (success) {
- success = success && cmd(cmd, dir, sudo).success
- }
- }
- ProvResult(success)
- }
-
-
- // todo: put logic in subclasses, such as UbuntuProv
- private fun cmdInContainer(containerName: String, vararg args: String): Array {
- return arrayOf(SHELL, "-c", "sudo docker exec $containerName " + buildCommand(*args))
- }
-
- private fun buildCommand(vararg args: String): String {
- return if (args.size == 1)
- args[0].escapeAndEncloseByDoubleQuoteForShell()
- else
- if (args.size == 3 && SHELL.equals(args[0]) && "-c".equals(args[1]))
- SHELL + " -c " + args[2].escapeAndEncloseByDoubleQuoteForShell()
- else
- args.joinToString(separator = " ")
- }
-
-
- /**
- * Provides result handling, e.g. gather results for result summary
- */
- private fun handle(mode: ResultMode, a: Prov.() -> ProvResult): ProvResult {
-
- // init
- if (level == 0) {
- internalResults.clear()
- previousLevel = -1
- exit = false
- initProgress()
- }
-
- // pre-handling
- val resultIndex = internalResults.size
- val method = getCallingMethodName()
- val internalResult = ResultLine(level, method, null)
- internalResults.add(internalResult)
-
- previousLevel = level
-
- level++
-
- // call the actual function
- val res = if (!exit) {
- progress(internalResult)
- @Suppress("UNUSED_EXPRESSION") // false positive
- a()
- } else {
- ProvResult(false, out = "Exiting due to failure and mode FAILEXIT")
- }
-
- level--
-
- // post-handling
- val returnValue =
- if (mode == ResultMode.LAST) {
- if (internalResultIsLeaf(resultIndex) || method == "cmd")
- res.copy() else ProvResult(res.success)
- } else if (mode == ResultMode.ALL) {
- // leaf
- if (internalResultIsLeaf(resultIndex)) res.copy()
- // evaluate subcalls' results
- else ProvResult(cumulativeSuccessSublevel(resultIndex) ?: false)
- } else if (mode == ResultMode.NONE) {
- ProvResult(true)
- } else if (mode == ResultMode.FAILEXIT) {
- return if (res.success) {
- ProvResult(true)
- } else {
- exit = true
- ProvResult(false)
- }
- } else {
- ProvResult(false, err = "mode unknown")
- }
-
- previousLevel = level
-
- internalResults[resultIndex].provResult = returnValue
-
- if (level == 0) {
- endProgress()
- processor.close()
- printResults()
- }
-
- return returnValue
- }
-
-
- private fun internalResultIsLeaf(resultIndex: Int): Boolean {
- return !(resultIndex < internalResults.size - 1 && internalResults[resultIndex + 1].level > internalResults[resultIndex].level)
- }
-
-
- private fun cumulativeSuccessSublevel(resultIndex: Int): Boolean? {
- val currentLevel = internalResults[resultIndex].level
- var res: Boolean? = null
- var i = resultIndex + 1
- while (i < internalResults.size && internalResults[i].level > currentLevel) {
- if (internalResults[i].level == currentLevel + 1) {
- res =
- if (res == null) internalResults[i].provResult?.success else res && (internalResults[i].provResult?.success
- ?: false)
- }
- i++
- }
- return res
- }
-
-
- private val ANSI_RESET = "\u001B[0m"
- private val ANSI_BRIGHT_RED = "\u001B[91m"
- private val ANSI_BRIGHT_GREEN = "\u001B[92m"
- // uncomment if needed
- // val ANSI_BLACK = "\u001B[30m"
- // val ANSI_RED = "\u001B[31m"
- // val ANSI_GREEN = "\u001B[32m"
- // val ANSI_YELLOW = "\u001B[33m"
- // val ANSI_BLUE = "\u001B[34m"
- // val ANSI_PURPLE = "\u001B[35m"
- // val ANSI_CYAN = "\u001B[36m"
- // val ANSI_WHITE = "\u001B[37m"
- val ANSI_GRAY = "\u001B[90m"
-
- private fun printResults() {
- println(
- "============================================== SUMMARY " + (if (name != null) "(" + name + ") " else "") +
- "============================================== "
- )
- for (result in internalResults) {
- println(
- result.toString().escapeNewline()
- .replace("Success --", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET + " --")
- .replace("FAILED --", ANSI_BRIGHT_RED + "FAILED" + ANSI_RESET + " --")
- )
- }
- if (internalResults.size > 1) {
- println("----------------------------------------------------------------------------------------------------- ")
- println(
- "Overall " + internalResults[0].toString().take(10)
- .replace("Success", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET)
- .replace("FAILED", ANSI_BRIGHT_RED + "FAILED" + ANSI_RESET)
- )
- }
- println("============================================ SUMMARY END ============================================ " + newline())
- }
-
- private fun String.formattedAsResultLine(): String = this
- .replace("Success", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET)
- .replace("FAILED", ANSI_BRIGHT_RED + "FAILED" + ANSI_RESET)
- .replace("executing...", ANSI_GRAY + "executing..." + ANSI_RESET)
-
-
- private fun initProgress() {
- if ((progressType == ProgressType.DOTS) || (progressType == ProgressType.BASIC)) {
- println("---------- Processing started ----------")
- System.out.flush()
- }
- }
-
- private fun progress(line: ResultLine) {
- if (progressType == ProgressType.DOTS) {
- print(".")
- System.out.flush()
- } else if (progressType == ProgressType.BASIC) {
- val shortLine = line.inProgress()
- if (!shortLine.endsWith("cmd") && !shortLine.endsWith("sh")) {
- println(shortLine.formattedAsResultLine())
- System.out.flush()
- }
- }
- }
-
- private fun endProgress() {
- if ((progressType == ProgressType.DOTS) || (progressType == ProgressType.BASIC)) {
- println("---------- Processing completed ----------")
- }
- }
-
-}
-
-
-internal data class ResultLine(val level: Int, val method: String?, var provResult: ProvResult?) {
- override fun toString(): String {
- val provResult = provResult
- return if (provResult != null) {
- prefix(level) + (if (provResult.success) "Success -- " else "FAILED -- ") +
- method + " " + (provResult.cmd ?: "") +
- (if (!provResult.success && provResult.err != null) " -- Error: " + provResult.err.escapeNewline() else "")
- } else
- prefix(level) + method + " " + "... in progress ... "
-
- }
-
- fun inProgress(): String {
- return prefix(level) + "executing... -- " + method
- }
-
- private fun prefix(level: Int): String {
- return "---".repeat(level) + "> "
- }
-}
-
-fun Prov.myfu() = def {
- cmd("echo asdf222")
-}
-fun main() {
-
- local().def {
- cmd("echo asdfasdf")
- myfu()
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/ProvResult.kt b/bin/main/org/domaindrivenarchitecture/provs/core/ProvResult.kt
deleted file mode 100644
index e625d68..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/ProvResult.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.domaindrivenarchitecture.provs.core
-
-
-data class ProvResult(val success: Boolean,
- val cmd: String? = null,
- val out: String? = null,
- val err: String? = null,
- val exception: Exception? = null,
- val exit: String? = null) {
-
- constructor(returnCode : Int) : this(returnCode == 0)
-
- override fun toString(): String {
- return "ProvResult:: ${if (success) "Succeeded" else "FAILED"} -- ${if (!cmd.isNullOrEmpty()) "Name: " +
- cmd.escapeNewline() + ", " else ""}${if (!out.isNullOrEmpty()) "Details: $out" else ""}" +
- (exception?.run { " Exception: " + toString() } ?: "")
- }
-
- @Suppress("unused")
- fun toShortString() : String {
- return "ProvResult:: ${if (success) "Succeeded" else "FAILED"} -- " +
- if (!success)
- (if (out != null) "Details: $out " else "" +
- if (err != null) " Error: " + err else "") else ""
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/Secret.kt b/bin/main/org/domaindrivenarchitecture/provs/core/Secret.kt
deleted file mode 100644
index 5772373..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/Secret.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.domaindrivenarchitecture.provs.core
-
-
-open class Secret(private val value: String) {
- override fun toString(): String {
- return "********"
- }
- fun plain() : String {
- return value
- }
-}
-
-
-class Password(plainPassword: String) : Secret(plainPassword)
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/Utils.kt b/bin/main/org/domaindrivenarchitecture/provs/core/Utils.kt
deleted file mode 100644
index 878ea9e..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/Utils.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.domaindrivenarchitecture.provs.core
-
-import org.domaindrivenarchitecture.provs.core.docker.provideContainer
-import org.domaindrivenarchitecture.provs.core.processors.ContainerStartMode
-import org.domaindrivenarchitecture.provs.core.processors.ContainerUbuntuHostProcessor
-import org.domaindrivenarchitecture.provs.core.processors.RemoteProcessor
-import org.domaindrivenarchitecture.provs.core.tags.Api
-import java.io.File
-import java.net.InetAddress
-
-/**
- * Returns the name of the calling function but excluding some functions of the prov framework
- * in order to return the "real" calling function.
- * Note: names of inner functions (i.e. which are defined inside other functions) are not
- * supported in the sense that always the name of the outer function is returned instead.
- */
-fun getCallingMethodName(): String? {
- val offsetVal = 1
- val exclude = arrayOf("def", "record", "invoke", "invoke0", "handle", "def\$default", "addResultToEval")
- // suffixes are also ignored as method names but will be added as suffix in the evaluation results
- val suffixes = arrayOf("optional", "requireAll", "requireLast", "inContainer")
-
- var suffix = ""
- val callingFrame = Thread.currentThread().stackTrace
- for (i in 0 until (callingFrame.size - 1)) {
- if (callingFrame[i].methodName == "getCallingMethodName") {
- var method = callingFrame[i + offsetVal].methodName
- var inc = 0
- while ((method in exclude) or (method in suffixes)) {
- if (method in suffixes && suffix == "") {
- suffix = method
- }
- inc++
- method = callingFrame[i + offsetVal + inc].methodName
- }
- return method + if (suffix.isBlank()) "" else " ($suffix)"
- }
- }
- return null
-}
-
-
-fun String.escapeNewline(): String = this.replace("\r\n", "\\n").replace("\n", "\\n")
-fun String.escapeBackslash(): String = this.replace("\\", "\\\\")
-fun String.escapeDoubleQuote(): String = this.replace("\"", "\\\"")
-fun String.escapeSingleQuote(): String = this.replace("'", "\'")
-fun String.escapeSingleQuoteForShell(): String = this.replace("'", "'\"'\"'")
-fun String.escapeProcentForPrintf(): String = this.replace("%", "%%")
-
-// see https://www.shellscript.sh/escape.html
-fun String.escapeAndEncloseByDoubleQuoteForShell(): String {
- return "\"" + this.escapeBackslash().replace("`", "\\`").escapeDoubleQuote().replace("$", "\\$") + "\""
-}
-
-fun hostUserHome(): String = System.getProperty("user.home") + fileSeparator()
-fun newline(): String = System.getProperty("line.separator")
-fun fileSeparator(): String = File.separator
-
-
-/**
- * Returns default local Prov instance.
- */
-@Suppress("unused") // used by other libraries resp. KotlinScript
-fun local(): Prov {
- return Prov.defaultInstance()
-}
-
-
-/**
- * Returns Prov instance for remote host with remote user with provided password.
- * If password is null, connection is done by ssh-key.
- * Platform (Linux, Windows) must be provided if different from local platform.
- */
-@Api // used by other libraries resp. KotlinScript
-fun remote(host: String, remoteUser: String, password: Secret? = null, platform: String? = null): Prov {
- require(host.isNotEmpty(), { "Host must not be empty." })
- require(remoteUser.isNotEmpty(), { "Remote user must not be empty." })
-
- return Prov.newInstance(RemoteProcessor(InetAddress.getByName(host), remoteUser, password), platform)
-}
-
-
-/**
- * Returns Prov instance running in a local docker container with name containerName.
- * A potentially existing container with the same name is reused by default resp. if
- * parameter useExistingContainer is set to true.
- * If a new container needs to be created, on Linux systems the image _ubuntu_ is used.
- */
-@Api // used by other libraries resp. KotlinScript
-fun docker(containerName: String = "provs_default", useExistingContainer: Boolean = true): Prov {
-
- val os = System.getProperty("os.name")
-
- if ("Linux".equals(os)) {
- val defaultDockerImage = "ubuntu"
-
- local().provideContainer(containerName, defaultDockerImage)
-
- return Prov.newInstance(
- ContainerUbuntuHostProcessor(
- containerName,
- defaultDockerImage,
- if (useExistingContainer)
- ContainerStartMode.USE_RUNNING_ELSE_CREATE
- else
- ContainerStartMode.CREATE_NEW_KILL_EXISTING
- )
- )
- } else {
- throw RuntimeException("ERROR: method docker() is currently not supported for " + os)
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/docker/HostDocker.kt b/bin/main/org/domaindrivenarchitecture/provs/core/docker/HostDocker.kt
deleted file mode 100644
index 550234a..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/docker/HostDocker.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.docker
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.docker.dockerimages.DockerImage
-import org.domaindrivenarchitecture.provs.core.docker.platforms.*
-import org.domaindrivenarchitecture.provs.core.platforms.UbuntuProv
-import org.domaindrivenarchitecture.provs.core.processors.ContainerStartMode
-
-/**
- * Builds a docker image if not yet existing.
- */
-fun Prov.dockerProvideImage(image: DockerImage, skipIfExisting: Boolean = true, sudo: Boolean = true) : ProvResult {
- if (this is UbuntuProv) {
- return this.dockerProvideImagePlatform(image, skipIfExisting, sudo)
- } else {
- throw RuntimeException("docker not yet supported for " + (this as UbuntuProv).javaClass)
- }
-}
-
-/**
- * Returns true if the specified docker image exists.
- */
-fun Prov.dockerImageExists(imageName: String, sudo: Boolean = true) : Boolean {
- if (this is UbuntuProv) {
- return this.dockerImageExistsPlatform(imageName, sudo)
- } else {
- throw RuntimeException("docker not yet supported for " + (this as UbuntuProv).javaClass)
- }
-}
-
-/**
- * Creates and runs a new container with name _containerName_ for image _imageName_ if not yet existing.
- * In case the container already exists, the parameter _startMode_ determines
- * if the running container is just kept (default behavior)
- * or if the running container is stopped and removed and a new container is created
- * or if the method results in a failure result.
- */
-fun Prov.provideContainer(
- containerName: String,
- imageName: String = "ubuntu",
- startMode: ContainerStartMode = ContainerStartMode.USE_RUNNING_ELSE_CREATE,
- sudo: Boolean = true
-) : ProvResult {
- if (this is UbuntuProv) {
- return this.provideContainerPlatform(containerName, imageName, startMode, sudo)
- } else {
- throw RuntimeException("docker not yet supported for " + (this as UbuntuProv).javaClass)
- }
-}
-
-
-fun Prov.containerRuns(containerName: String, sudo: Boolean = true) : Boolean {
- if (this is UbuntuProv) {
- return this.containerRunsPlatform(containerName, sudo)
- } else {
- throw RuntimeException("docker not yet supported for " + (this as UbuntuProv).javaClass)
- }
-}
-
-
-fun Prov.runContainer(
- containerName: String = "provs_default",
- imageName: String = "ubuntu",
- sudo: Boolean = true
-) : ProvResult {
- if (this is UbuntuProv) {
- return this.runContainerPlatform(containerName, imageName, sudo)
- } else {
- throw RuntimeException("docker not yet supported for " + (this as UbuntuProv).javaClass)
- }
-}
-
-
-fun Prov.exitAndRmContainer(
- containerName: String,
- sudo: Boolean = true
-) : ProvResult {
- if (this is UbuntuProv) {
- return this.exitAndRmContainerPlatform(containerName, sudo)
- } else {
- throw RuntimeException("docker not yet supported for " + (this as UbuntuProv).javaClass)
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/docker/dockerimages/DockerImages.kt b/bin/main/org/domaindrivenarchitecture/provs/core/docker/dockerimages/DockerImages.kt
deleted file mode 100644
index 1efbc40..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/docker/dockerimages/DockerImages.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.docker.dockerimages
-
-
-interface DockerImage {
- fun imageName() : String
- fun imageText() : String
-}
-
-/**
- * Provides a docker image based on ubuntu additionally with a non-root default user and sudo isntalled
- */
-class UbuntuPlusUser(private val userName: String = "testuser") : DockerImage {
-
- override fun imageName(): String {
- return "ubuntu_plus_user"
- }
-
- override fun imageText(): String {
- return """
-FROM ubuntu:18.04
-
-ARG DEBIAN_FRONTEND=noninteractive
-
-RUN apt-get update && apt-get -y install sudo
-RUN useradd -m $userName && echo "$userName:$userName" | chpasswd && adduser $userName sudo
-RUN echo "$userName ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/$userName
-
-USER $userName
-CMD /bin/bash
-WORKDIR /home/$userName
-"""
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/docker/platforms/UbuntuHostDocker.kt b/bin/main/org/domaindrivenarchitecture/provs/core/docker/platforms/UbuntuHostDocker.kt
deleted file mode 100644
index db33835..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/docker/platforms/UbuntuHostDocker.kt
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.docker.platforms
-
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.docker.containerRuns
-import org.domaindrivenarchitecture.provs.core.docker.dockerImageExists
-import org.domaindrivenarchitecture.provs.core.docker.exitAndRmContainer
-import org.domaindrivenarchitecture.provs.core.docker.dockerimages.DockerImage
-import org.domaindrivenarchitecture.provs.core.escapeSingleQuote
-import org.domaindrivenarchitecture.provs.core.fileSeparator
-import org.domaindrivenarchitecture.provs.core.hostUserHome
-import org.domaindrivenarchitecture.provs.core.platforms.UbuntuProv
-import org.domaindrivenarchitecture.provs.core.processors.ContainerStartMode
-
-
-fun UbuntuProv.provideContainerPlatform(
- containerName: String,
- imageName: String = "ubuntu",
- startMode: ContainerStartMode = ContainerStartMode.USE_RUNNING_ELSE_CREATE,
- sudo: Boolean = true
-): ProvResult = requireLast {
- val dockerCmd = if (sudo) "sudo docker " else "docker "
-
- if (startMode == ContainerStartMode.CREATE_NEW_KILL_EXISTING) {
- exitAndRmContainer(containerName)
- }
- if ((startMode == ContainerStartMode.CREATE_NEW_KILL_EXISTING) || (startMode == ContainerStartMode.CREATE_NEW_FAIL_IF_EXISTING)) {
- if (!cmd(dockerCmd + "run -dit --name=$containerName $imageName").success) {
- throw RuntimeException("could not start docker")
- }
- } else if (startMode == ContainerStartMode.USE_RUNNING_ELSE_CREATE) {
- val runCheckResult = cmdNoEval(dockerCmd + "inspect -f '{{.State.Running}}' $containerName")
-
- // if either container not found or container found but not running
- if (!runCheckResult.success || "false\n" == runCheckResult.out) {
- cmdNoEval(dockerCmd + "rm -f $containerName")
- cmd(dockerCmd + "run -dit --name=$containerName $imageName")
- }
- }
- ProvResult(containerRuns(containerName, sudo))
-}
-
-
-fun UbuntuProv.containerRunsPlatform(containerName: String, sudo: Boolean = true): Boolean {
- val dockerCmd = if (sudo) "sudo docker " else "docker "
- return cmdNoEval(dockerCmd + "inspect -f '{{.State.Running}}' $containerName").out?.equals("true\n") ?: false
-}
-
-
-fun UbuntuProv.runContainerPlatform(
- containerName: String = "defaultProvContainer",
- imageName: String = "ubuntu",
- sudo: Boolean = true
-) = def {
- val dockerCmd = if (sudo) "sudo docker " else "docker "
- cmd(dockerCmd + "run -dit --name=$containerName $imageName")
-}
-
-
-fun UbuntuProv.containerExecPlatform(containerName: String, cmd: String, sudo: Boolean = true) = def {
- val dockerCmd = if (sudo) "sudo docker " else "docker "
- cmd(dockerCmd + "exec $containerName $cmd")
-}
-
-
-fun UbuntuProv.dockerProvideImagePlatform(image: DockerImage, skipIfExisting: Boolean, sudo: Boolean): ProvResult {
- val dockerCmd = if (sudo) "sudo docker " else "docker "
-
- if (skipIfExisting && dockerImageExists(image.imageName())) {
- return ProvResult(true)
- }
-
- val path = hostUserHome() + "tmp_docker_img" + fileSeparator()
-
- if (!xec("test", "-d", path).success) {
- cmd("cd ${hostUserHome()} && mkdir tmp_docker_img")
- }
-
- cmd("cd $path && printf '${image.imageText().escapeSingleQuote()}' > Dockerfile")
-
- return cmd("cd $path && "+dockerCmd+"build --tag ${image.imageName()} .")
-}
-
-
-fun UbuntuProv.dockerImageExistsPlatform(imageName: String, sudo: Boolean): Boolean {
- val dockerCmd = if (sudo) "sudo docker " else "docker "
-
- return (cmdNoEval(dockerCmd + "images $imageName -q").out != "")
-}
-
-
-fun UbuntuProv.exitAndRmContainerPlatform(
- containerName: String,
- sudo: Boolean
-) = requireAll {
- val dockerCmd = if (sudo) "sudo docker " else "docker "
-
- if (containerRuns(containerName)) {
- cmd(dockerCmd + "stop $containerName")
- }
- cmd(dockerCmd + "rm $containerName")
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/entry/Entry.kt b/bin/main/org/domaindrivenarchitecture/provs/core/entry/Entry.kt
deleted file mode 100644
index c329021..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/entry/Entry.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.entry
-
-/**
- * Calls a static method of a class.
- * Only methods are supported with either no parameters or with one vararg parameter of type String.
- * Methods with a vararg parameter must be called with at least one argument.
- *
- * @param args specify class and (optionally) method and parameters, in detail:
- * @param args[0] fully-qualified class name of the class to be called
- * @param args[1] (optional) static method of the class with a vararg parameter of type String; if not specified, the "main" method is used
- * @param args[2...] (optional) String parameters that are passed to the method; can be only used if method name (args[1]) is provided
- */
-fun main(vararg args: String) {
-
- if (args.isNotEmpty()) {
- val className = args[0]
-
- val jClass = Class.forName(className)
-
- val parameterTypeStringArray = arrayOf>(
- Array::class.java
- )
- val method = if (args.size == 1) {
- jClass.getMethod("main", *parameterTypeStringArray)
- } else {
- jClass.getMethod(args[1], *parameterTypeStringArray)
- }
-
- if (args.size <= 2) {
- method.invoke(null, emptyArray())
- } else {
- method.invoke(null, args.drop(2).toTypedArray())
- }
- } else {
- println("Usage: ")
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/platforms/UbuntuProv.kt b/bin/main/org/domaindrivenarchitecture/provs/core/platforms/UbuntuProv.kt
deleted file mode 100644
index 67fae5b..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/platforms/UbuntuProv.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.platforms
-
-import org.domaindrivenarchitecture.provs.core.ProgressType
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.escapeAndEncloseByDoubleQuoteForShell
-import org.domaindrivenarchitecture.provs.core.processors.LocalProcessor
-import org.domaindrivenarchitecture.provs.core.processors.Processor
-
-const val SHELL = "/bin/bash"
-
-
-class UbuntuProv internal constructor(processor : Processor = LocalProcessor(), name: String? = null, progressType: ProgressType)
- : Prov(processor, name, progressType) {
-
- override fun cmd(cmd: String, dir: String?, sudo: Boolean) : ProvResult = def {
- xec(SHELL, "-c", commandWithDirAndSudo(cmd, dir, sudo))
- }
-
- override fun cmdNoLog(cmd: String, dir: String?, sudo: Boolean) : ProvResult {
- return xecNoLog(SHELL, "-c", commandWithDirAndSudo(cmd, dir, sudo))
- }
-
- override fun cmdNoEval(cmd: String, dir: String?, sudo: Boolean) : ProvResult {
- return xec(SHELL, "-c", commandWithDirAndSudo(cmd, dir, sudo))
- }
-}
-
-private fun commandWithDirAndSudo(cmd: String, dir: String?, sudo: Boolean): String {
- val cmdWithDir= if (dir == null) cmd else "cd $dir && $cmd"
- return if (sudo) cmdWithDir.sudoize() else cmdWithDir
-}
-
-private fun String.sudoize(): String {
- return "sudo " + SHELL + " -c " + this.escapeAndEncloseByDoubleQuoteForShell()
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/platforms/WinProv.kt b/bin/main/org/domaindrivenarchitecture/provs/core/platforms/WinProv.kt
deleted file mode 100644
index 66b787e..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/platforms/WinProv.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.platforms
-
-import org.domaindrivenarchitecture.provs.core.ProgressType
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.processors.LocalProcessor
-import org.domaindrivenarchitecture.provs.core.processors.Processor
-
-
-class WinProv internal constructor(processor : Processor = LocalProcessor(), name: String? = null, progressType: ProgressType)
- : Prov(processor, name, progressType) {
-
- private val SHELL = "cmd.exe"
-
- override fun cmd(cmd: String, dir: String?, sudo: Boolean) : ProvResult = def {
- require(!sudo, {"sudo not supported"})
- xec(SHELL, "/c", if (dir == null) cmd else "cd $dir && $cmd")
- }
-
- override fun cmdNoLog(cmd: String, dir: String?, sudo: Boolean) : ProvResult = def {
- require(!sudo, {"sudo not supported"})
- xecNoLog(SHELL, "/c", if (dir == null) cmd else "cd $dir && $cmd")
- }
-
-
- override fun cmdNoEval(cmd: String, dir: String?, sudo: Boolean) : ProvResult {
- require(!sudo, {"sudo not supported"})
- return xec(SHELL, "/c", if (dir == null) cmd else "cd $dir && $cmd")
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/processors/ContainerUbuntuHostProcessor.kt b/bin/main/org/domaindrivenarchitecture/provs/core/processors/ContainerUbuntuHostProcessor.kt
deleted file mode 100644
index d1e219c..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/processors/ContainerUbuntuHostProcessor.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-import org.domaindrivenarchitecture.provs.core.ProgressType
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.docker.provideContainer
-import org.domaindrivenarchitecture.provs.core.escapeAndEncloseByDoubleQuoteForShell
-import org.domaindrivenarchitecture.provs.core.platforms.SHELL
-import org.domaindrivenarchitecture.provs.core.tags.Api
-
-enum class ContainerStartMode {
- USE_RUNNING_ELSE_CREATE,
- CREATE_NEW_KILL_EXISTING,
- CREATE_NEW_FAIL_IF_EXISTING
-}
-
-enum class ContainerEndMode {
- EXIT_AND_REMOVE,
- KEEP_RUNNING
-}
-
-open class ContainerUbuntuHostProcessor(
- private val containerName: String = "default_provs_container",
- @Api // suppress false positive warning
- private val dockerImage: String = "ubuntu",
- @Api // suppress false positive warning
- private val startMode: ContainerStartMode = ContainerStartMode.USE_RUNNING_ELSE_CREATE,
- private val endMode: ContainerEndMode = ContainerEndMode.KEEP_RUNNING,
- @Api // suppress false positive warning
- private val sudo: Boolean = true
-) : Processor {
- private val dockerCmd = if (sudo) "sudo docker " else "docker "
- private var localExecution = LocalProcessor()
- private var a = Prov.newInstance(name = "LocalProcessor for Docker operations", progressType = ProgressType.NONE)
-
- init {
- val r = a.provideContainer(containerName, dockerImage, startMode, sudo)
- if (!r.success)
- throw RuntimeException("Could not start docker image: " + r.toString(), r.exception)
- }
-
- override fun x(vararg args: String): ProcessResult {
- return localExecution.x("sh", "-c", dockerCmd + "exec $containerName " + buildCommand(*args))
- }
-
- override fun xNoLog(vararg args: String): ProcessResult {
- return localExecution.xNoLog("sh", "-c", dockerCmd + "exec $containerName " + buildCommand(*args))
- }
-
- private fun exitAndRm() {
- localExecution.x(SHELL, "-c", dockerCmd + "stop $containerName")
- localExecution.x(SHELL, "-c", dockerCmd + "rm $containerName")
- }
-
- private fun quoteString(s: String): String {
- return s.escapeAndEncloseByDoubleQuoteForShell()
- }
-
- private fun buildCommand(vararg args: String) : String {
- return if (args.size == 1) quoteString(args[0]) else
- if (args.size == 3 && SHELL == args[0] && "-c" == args[1]) SHELL + " -c " + quoteString(args[2])
- else args.joinToString(separator = " ")
- }
-
- protected fun finalize() {
- if (endMode == ContainerEndMode.EXIT_AND_REMOVE) {
- exitAndRm()
- }
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/processors/LocalProcessor.kt b/bin/main/org/domaindrivenarchitecture/provs/core/processors/LocalProcessor.kt
deleted file mode 100644
index 06e245d..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/processors/LocalProcessor.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-import org.domaindrivenarchitecture.provs.core.escapeNewline
-import org.slf4j.LoggerFactory
-import java.io.File
-import java.io.IOException
-import java.nio.charset.Charset
-
-
-private fun getOsName(): String {
- return System.getProperty("os.name")
-}
-
-open class LocalProcessor : Processor {
-
- companion object {
- @Suppress("JAVA_CLASS_ON_COMPANION")
- private val log = LoggerFactory.getLogger(javaClass.enclosingClass)
-
- var charset: Charset = if (getOsName().contains("Windows")) Charset.forName("Windows-1252") else Charset.defaultCharset()
- init {
- log.info("os.name: " + getOsName())
- log.info("user.home: " + System.getProperty("user.home"))
- }
- }
-
- private fun workingDir() : String
- {
- return System.getProperty("user.home") ?: File.separator
- }
-
- override fun x(vararg args: String): ProcessResult {
- return execute(true, *args)
- }
-
-
- override fun xNoLog(vararg args: String): ProcessResult {
- return execute(false, *args)
- }
-
- private fun execute(logging: Boolean, vararg args: String): ProcessResult {
- try {
- var prefix = "******************** Prov: "
- if (logging) {
- for (arg in args) {
- prefix += " \"${arg.escapeNewline()}\""
- }
- } else {
- prefix += "\"xxxxxxxx\""
- }
- log.info(prefix)
-
- val proc = ProcessBuilder(args.toList())
- .directory(File(workingDir()))
- .redirectOutput(ProcessBuilder.Redirect.PIPE)
- .redirectError(ProcessBuilder.Redirect.PIPE)
- .start()
-
- val c = proc.waitFor()
-
- val r = ProcessResult(
- c,
- proc.inputStream.bufferedReader(charset).readText(),
- proc.errorStream.bufferedReader(charset).readText(),
- args = args
- )
- if (logging) {
- log.info(r.toString())
- }
- return r
-
- } catch (e: IOException) {
- e.printStackTrace()
- return ProcessResult(-1, ex = e)
- }
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/processors/PrintOnlyProcessor.kt b/bin/main/org/domaindrivenarchitecture/provs/core/processors/PrintOnlyProcessor.kt
deleted file mode 100644
index 868d0ef..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/processors/PrintOnlyProcessor.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-
-@Suppress("unused") // used externally
-class PrintOnlyProcessor : Processor {
-
- override fun x(vararg args: String): ProcessResult
- {
- print("PrintOnlyProcessor >>> ")
- for (n in args) print("\"$n\" ")
- println()
- return ProcessResult(0, args = args)
- }
-
- override fun xNoLog(vararg args: String): ProcessResult
- {
- print("PrintOnlyProcessor >>> ********")
- return ProcessResult(0, args = args)
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/processors/Processor.kt b/bin/main/org/domaindrivenarchitecture/provs/core/processors/Processor.kt
deleted file mode 100644
index c868066..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/processors/Processor.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-
-interface Processor {
- fun x(vararg args: String): ProcessResult
- fun xNoLog(vararg args: String): ProcessResult
- fun close() {
- // no action needed for most processors; if action is needed when closing, this method must be overwritten in the subclass
- }
-}
-
-
-data class ProcessResult(val exitCode: Int, val out: String? = null, val err: String? = null, val ex: Exception? = null, val args: Array = emptyArray()) {
-
- private fun success(): Boolean {
- return (exitCode == 0)
- }
-
- fun argsToString() : String {
- return args.joinToString(
- separator = ", ",
- prefix = "[",
- postfix = "]",
- limit = 4,
- truncated = " ..."
- )
- }
-
- override fun toString(): String {
- return "--->>> ProcessResult: ${if (success()) "Succeeded" else "FAILED"} -- Code: $exitCode, ${if (!out.isNullOrEmpty()) "Out: $out, " else ""}${if (!err.isNullOrEmpty()) "Err: $err" else ""}" + argsToString()
- }
-
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (javaClass != other?.javaClass) return false
-
- other as ProcessResult
-
- if (exitCode != other.exitCode) return false
- if (out != other.out) return false
- if (err != other.err) return false
- if (ex != other.ex) return false
- if (!args.contentEquals(other.args)) return false
-
- return true
- }
-
- override fun hashCode(): Int {
- var result = exitCode
- result = 31 * result + (out?.hashCode() ?: 0)
- result = 31 * result + (err?.hashCode() ?: 0)
- result = 31 * result + ex.hashCode()
- result = 31 * result + args.contentHashCode()
- return result
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/processors/RemoteUbuntuProcessor.kt b/bin/main/org/domaindrivenarchitecture/provs/core/processors/RemoteUbuntuProcessor.kt
deleted file mode 100644
index eae5792..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/processors/RemoteUbuntuProcessor.kt
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.core.escapeAndEncloseByDoubleQuoteForShell
-import org.domaindrivenarchitecture.provs.core.escapeNewline
-import org.domaindrivenarchitecture.provs.core.platforms.SHELL
-import net.schmizz.sshj.SSHClient
-import net.schmizz.sshj.connection.channel.direct.Session
-import net.schmizz.sshj.connection.channel.direct.Session.Command
-import net.schmizz.sshj.transport.verification.PromiscuousVerifier
-import org.slf4j.LoggerFactory
-import java.io.BufferedReader
-import java.io.File
-import java.io.IOException
-import java.io.InputStreamReader
-import java.net.InetAddress
-import java.util.concurrent.TimeUnit
-
-
-class RemoteProcessor(ip: InetAddress, user: String, password: Secret? = null) : Processor {
-
- companion object {
- @Suppress("JAVA_CLASS_ON_COMPANION")
- private val log = LoggerFactory.getLogger(javaClass.enclosingClass)
- }
-
- private val ssh = SSHClient()
-
- init {
- try {
- log.info("Connecting to $ip with user: $user with " + if (password != null) "password" else "ssh-key")
-
- ssh.loadKnownHosts()
-
- // todo: replace PromiscuousVerifier by more secure solution
- ssh.addHostKeyVerifier(PromiscuousVerifier())
- ssh.connect(ip)
-
- if (password != null) {
- ssh.authPassword(user, password.plain())
- } else {
- val base = System.getProperty("user.home") + File.separator + ".ssh" + File.separator
- ssh.authPublickey(user, base + "id_rsa", base + "id_dsa", base + "id_ed25519", base + "id_ecdsa")
- }
- } catch (e: Exception) {
- try {
- ssh.disconnect()
- } finally {
- log.error("Got exception when initializing ssh: " + e.message)
- throw RuntimeException("Error when initializing ssh", e)
- }
- }
- }
-
- override fun x(vararg args: String): ProcessResult {
- return execute(true, *args)
- }
-
- override fun xNoLog(vararg args: String): ProcessResult {
- return execute(false, *args)
- }
-
- private fun execute(logging: Boolean, vararg args: String): ProcessResult {
- var prefix = "******************** Prov: "
- if (logging) {
- for (arg in args) {
- prefix += " \"${arg.escapeNewline()}\""
- }
- } else {
- prefix += "\"xxxxxxxx\""
- }
- log.info(prefix)
-
- val cmdString: String =
- if (args.size == 1)
- args[0].escapeAndEncloseByDoubleQuoteForShell()
- else
- if (args.size == 3 && SHELL == args[0] && "-c" == args[1])
- SHELL + " -c " + args[2].escapeAndEncloseByDoubleQuoteForShell()
- else
- args.joinToString(separator = " ")
-
- var session: Session? = null
-
- try {
- session = ssh.startSession()
-
- val cmd: Command = session!!.exec(cmdString)
- val out = BufferedReader(InputStreamReader(cmd.inputStream)).use { it.readText() }
- val err = BufferedReader(InputStreamReader(cmd.errorStream)).use { it.readText() }
- cmd.join(100, TimeUnit.SECONDS)
-
- val cmdRes = ProcessResult(cmd.exitStatus, out, err, args = args)
- if (logging) {
- log.info(cmdRes.toString())
- }
- session.close()
-
- return cmdRes
-
- } catch (e: Exception) {
- try {
- session?.close()
- } finally {
- // nothing to do
- }
- return ProcessResult(
- -1,
- err = "Error when opening or executing remote ssh session (Pls check host, user, password resp. ssh key) - ",
- ex = e
- )
- }
- }
-
- override fun close() {
- try {
- log.info("Disconnecting ssh.")
- ssh.disconnect()
- } catch (e: IOException) {
- // No prov required
- }
- }
-
- protected fun finalize() {
- close()
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/core/tags/Api.kt b/bin/main/org/domaindrivenarchitecture/provs/core/tags/Api.kt
deleted file mode 100644
index 9d9bd08..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/core/tags/Api.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.tags
-
-@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
-@Retention(AnnotationRetention.SOURCE)
-@Suppress("unused") // element is offered to be used externally
-annotation class Api
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/demos/HelloWorld.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/demos/HelloWorld.kt
deleted file mode 100644
index 8b3b7d8..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/demos/HelloWorld.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.demos
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.local
-
-
-fun Prov.helloWorld() = def {
- cmd("echo Hello world!")
-}
-
-
-fun main() {
- local().helloWorld()
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/demos/SystemInfos.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/demos/SystemInfos.kt
deleted file mode 100644
index 2488d52..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/demos/SystemInfos.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.demos
-
-import org.domaindrivenarchitecture.provs.core.*
-
-
-/**
- * Prints some information and settings of the operating system and environment.
- *
- * For running locally no arguments are required.
- * For running remotely either 2 or 3 arguments must be provided:
- * either host and user for connection by ssh key ()
- * or host, user and password for password-authenticated connection.
- * E.g. 172.0.0.123 username or 172.0.0.123 username password
- */
-fun main(vararg args: String) {
- if (args.isEmpty()) {
- local().printInfos()
- } else {
- if (args.size !in 2..3) {
- println("Wrong number of arguments. Please specify either host and user if connection is done by ssh key or otherwise host, user and password. E.g. 172.0.0.123 username password")
- } else {
- val password = if (args.size == 2) null else Secret(args[3])
- remote(args[0], args[1], password = password).printInfos()
- }
- }
-}
-
-
-fun Prov.printInfos() = def {
- println("\nUbuntu Version:\n${ubuntuVersion()}")
- println("\nCurrent directory:\n${currentDir()}")
- println("\nTime zone:\n${timeZone()}")
-
- val dir = cmd("pwd").out
- println("\nCurrent directory: $dir")
-
- ProvResult(true)
-}
-
-
-fun Prov.ubuntuVersion(): String? {
- return cmd("lsb_release -a").out
-}
-
-
-fun Prov.currentDir(): String? {
- return cmd("pwd").out
-}
-
-
-fun Prov.timeZone(): String? {
- return cmd("cat /etc/timezone").out
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_compounds/monitoring/ProvisionMonitoring.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_compounds/monitoring/ProvisionMonitoring.kt
deleted file mode 100644
index 8c85888..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_compounds/monitoring/ProvisionMonitoring.kt
+++ /dev/null
@@ -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.nginx.base.NginxConf
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.nginxHttpConf
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.provisionNginxStandAlone
-import org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.base.configurePrometheusDocker
-import org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.base.runPrometheusDocker
-
-
-@Suppress("unused") // used externally
-fun Prov.provisionMonitoring() = requireAll {
- configurePrometheusDocker()
- runPrometheusDocker()
- provisionNginxStandAlone(NginxConf.nginxHttpConf())
-}
-
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_compounds/monitoring/ProvisionNginxAndMonitoring.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_compounds/monitoring/ProvisionNginxAndMonitoring.kt
deleted file mode 100644
index 9320da8..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_compounds/monitoring/ProvisionNginxAndMonitoring.kt
+++ /dev/null
@@ -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.nginx.base.NginxConf
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.nginxAddLocation
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.nginxCreateSelfSignedCertificate
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.nginxHttpsConfWithLocationFiles
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.provisionNginxStandAlone
-import org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.base.prometheusNginxConfig
-import org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.provisionPrometheusDocker
-
-
-@Suppress("unused") // used externally
-fun Prov.provisionNginxMonitoring(nginxHost: String = "localhost") = def {
- provisionPrometheusDocker(nginxHost)
- nginxCreateSelfSignedCertificate()
- provisionNginxStandAlone(NginxConf.nginxHttpsConfWithLocationFiles())
- nginxAddLocation("443", nginxHost, "/prometheus", prometheusNginxConfig)
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/certbot/ProvisionCertbot.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/certbot/ProvisionCertbot.kt
deleted file mode 100644
index ad66362..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/certbot/ProvisionCertbot.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.certbot
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileExists
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-
-/**
- * Provisions a certbot for the specified serverName and email to obtain and renew letsencrypt certificates
- * Parameter can be used to specify certbot options e.g. "--nginx" to configure nginx, see https://certbot.eff.org/docs/using.html#certbot-command-line-options
- */
-fun Prov.provisionCertbot(serverName: String, email: String?, additionalOptions: String? = "") = requireAll {
- aptInstall("snapd")
- sh("""
- sudo snap install core; sudo snap refresh core
- sudo snap install --classic certbot
- """.trimIndent())
-
- if (!fileExists("/usr/bin/certbot")) {
- cmd("sudo ln -s /snap/bin/certbot /usr/bin/certbot")
- val emailOption = email?.let { " -m $it" } ?: "--register-unsafely-without-email"
- cmd("sudo certbot $additionalOptions -n --agree-tos $emailOption -d $serverName")
- } else {
- ProvResult(true)
- }
-
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/ProvisionFirewall.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/ProvisionFirewall.kt
deleted file mode 100644
index 1cc8ed2..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/ProvisionFirewall.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.firewall
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-
-fun Prov.saveIpTables() = requireAll {
- sh("""
- iptables-save > /etc/iptables/rules.v4
- ip6tables-save > /etc/iptables/rules.v6
-
- netfilter-persistent save""",
- sudo = true)
-}
-
-
-fun Prov.makeIpTablesPersistent() = requireAll {
- // inspired by https://gist.github.com/alonisser/a2c19f5362c2091ac1e7
- // enables iptables-persistent to be installed without manual input
- sh("""
- echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
- echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
- """.trimIndent())
-
- aptInstall("iptables-persistent netfilter-persistent")
- saveIpTables()
-}
-
-
-fun Prov.resetFirewall() = requireAll {
- sh("""
- #!/bin/bash
- sudo iptables -F
- sudo iptables -X
- sudo iptables -t nat -F
- sudo iptables -t nat -X
- sudo iptables -t mangle -F
- sudo iptables -t mangle -X
-
- # the rules allow us to reconnect by opening up all traffic.
- sudo iptables -P INPUT ACCEPT
- sudo iptables -P FORWARD ACCEPT
- sudo iptables -P OUTPUT ACCEPT
-
- # print out all rules to the console after running this file.
- sudo iptables -nL
- """, sudo = true
- )
-}
-
-
-fun Prov.provisionFirewall(addNetworkProtections: Boolean = false) = requireAll {
- if (addNetworkProtections) {
- networkProtections()
- }
-
- // inspired by: https://github.com/ChrisTitusTech/firewallsetup/blob/master/firewall
- sh("""
- # Firewall
-
- # Accept all traffic first to avoid ssh lockdown via iptables firewall rules #
- iptables -P INPUT ACCEPT
- iptables -P FORWARD ACCEPT
- iptables -P OUTPUT ACCEPT
-
- # Flush all chains
- iptables --flush
-
- # Allow unlimited traffic on the loopback interface
- iptables -A INPUT -i lo -j ACCEPT
- iptables -A OUTPUT -o lo -j ACCEPT
-
- # Previously initiated and accepted exchanges bypass rule checking
- # Allow unlimited outbound traffic
- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
-
- #Ratelimit SSH for attack protection
- iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
- iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
- iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
-
- # Allow http/https ports to be accessible from the outside
- iptables -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT # http
- iptables -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT # https
-
- # UDP packet rule. This is just a random udp packet rule as an example only
- # iptables -A INPUT -p udp --dport 5021 -m state --state NEW -j ACCEPT
-
- # Allow pinging of your server
- iptables -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
-
-
- # Drop all other traffic
- iptables -A INPUT -j DROP
-
- # print the activated rules to the console when script is completed
- iptables -nL
-
- # Set default policies
- iptables --policy INPUT DROP
- iptables --policy OUTPUT DROP
- iptables --policy FORWARD DROP
- """, sudo = true)
- if (chk("docker -v")) {
- ipTablesRecreateDockerRules()
- } else {
- ProvResult(true, "No need to create iptables docker rules as no docker installed.")
- }
-}
-
-
-fun Prov.networkProtections() = def {
- sh("""
- # Drop ICMP echo-request messages sent to broadcast or multicast addresses
- echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
-
- # Drop source routed packets
- echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
-
- # Enable TCP SYN cookie protection from SYN floods
- echo 1 > /proc/sys/net/ipv4/tcp_syncookies
-
- # Don't accept ICMP redirect messages
- echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
-
- # Don't send ICMP redirect messages
- echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
-
- # Enable source address spoofing protection
- echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
-
- # Log packets with impossible source addresses
- echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
- """.trimIndent())
-}
-
-
-fun Prov.ipTablesRecreateDockerRules() = requireAll {
- // see https://stackoverflow.com/questions/25917941/docker-how-to-re-create-dockers-additional-iptables-rules
- cmd("sudo service docker restart")
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/base/FirewallBackup.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/base/FirewallBackup.kt
deleted file mode 100644
index f4b6068..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/base/FirewallBackup.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.firewall.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import java.time.LocalDateTime
-import java.time.format.DateTimeFormatter
-
-
-fun Prov.saveIpTablesToFile() = def {
- val dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("-yyyy-MM-dd--HH:mm:ss"))
- val file = "savedrules$dateTime.txt"
- sh("""
- sudo iptables-save > $file
- cat $file""")
-}
-
-fun Prov.restoreIpTablesFromFile(file: String? = null) = def {
- val fileName = file ?: cmd("ls -r a* | head -1\n").out
- fileName?.let { cmd("sudo iptables-restore < $file") }
- ?: ProvResult(false, err = "File to restore not found.")
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexus.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexus.kt
deleted file mode 100644
index 5a2f65f..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexus.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nexus
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.docker.containerRuns
-import org.domaindrivenarchitecture.provs.core.remote
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileExists
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.user.base.createUser
-import org.domaindrivenarchitecture.provs.extensions.server_software.certbot.provisionCertbot
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.NginxConf
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.nginxReverseProxyHttpConfig
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.provisionNginxStandAlone
-
-
-/**
- * Provisions sonatype nexus in a docker container.
- * If you would want nexus to be accessible directly from the internet (e.g. for test or demo reasons)
- * set parameter portAccessibleFromNetwork to true.
- */
-fun Prov.provisionNexusWithDocker(portAccessibleFromNetwork: Boolean = false) = requireAll {
- // https://blog.sonatype.com/sonatype-nexus-installation-using-docker
- // https://medium.com/@AhGh/how-to-setup-sonatype-nexus-3-repository-manager-using-docker-7ff89bc311ce
- aptInstall("docker.io")
-
- if (!containerRuns("nexus")) {
- val volume = "nexus-data"
- if (!cmdNoEval("docker volume inspect $volume").success) {
- cmd("docker volume create --name $volume")
- }
- cmd("sudo docker run -d --restart unless-stopped -p 8081:8081 --name nexus -v nexus-data:/nexus-data sonatype/nexus3")
-
- for (n in 0..3) {
- if (fileExists("/var/lib/docker/volumes/$volume/_data/admin.password", sudo = true)) {
- val res = cmd("sudo cat /var/lib/docker/volumes/$volume/_data/admin.password")
- println("Admin Password:" + res.out)
- break
- }
- Thread.sleep(20000)
- }
- }
- if (!portAccessibleFromNetwork) {
- val netIf = getDefaultNetworkingInterface()
- netIf?.also {
- val iptablesParameters = "DOCKER-USER -i $it ! -s 127.0.0.1 -j DROP"
- if (!cmdNoEval("sudo iptables -C $iptablesParameters").success) {
- cmd("sudo iptables -I $iptablesParameters")
- }
- }
- }
- ProvResult(true) // dummy
-}
-
-private fun Prov.getDefaultNetworkingInterface(): String? {
- return cmd("route | grep \"^default\" | grep -o \"[^ ]*\$\"\n").out?.trim()
-}
-
-
-/**
- * Provisions sonatype nexus on the specified host.
- * Creates user "nexus" on the remote system.
- * Installs nexus in a docker container behind an nginx reverse proxy with ssl using letsencrypt certificates.
- *
- * To run this method it is required to have ssl root access to the host.
- */
-@Suppress("unused") // to be used externally
-fun provisionNexusServer(serverName: String, certbotEmail: String) {
- val userName = "nexus" + 7
- remote(serverName, "root").def {
- createUser(userName, copyAuthorizedKeysFromCurrentUser = true, sudo = true)
- }
- remote(serverName, userName).requireAll {
- provisionNexusWithDocker()
-
- if (provisionNginxStandAlone(NginxConf.nginxReverseProxyHttpConfig(serverName)).success) {
-
- cmd("sudo cat /etc/nginx/nginx.conf")
-
- provisionCertbot(serverName, certbotEmail, "--nginx")
-
- optional {
- cmd("sudo cat /etc/nginx/nginx.conf")
- cmd("sudo sed -i 's/X-Forwarded-Proto \"http\"/X-Forwarded-Proto \"https\"/g' /etc/nginx/nginx.conf")
- cmd("sudo systemctl reload nginx")
- }
- } else {
- ProvResult(true)
- }
- }
-}
-
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/base/NginxConf.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/base/NginxConf.kt
deleted file mode 100644
index 25e3b58..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/base/NginxConf.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nexus.base
-
-fun reverseProxyConfigHttpPort80(serverName: String): String {
- // see https://help.sonatype.com/repomanager3/installation/run-behind-a-reverse-proxy
- return """
- events {} # event context have to be defined to consider config valid
-
- http {
-
- proxy_send_timeout 120;
- proxy_read_timeout 300;
- proxy_buffering off;
- keepalive_timeout 5 5;
- tcp_nodelay on;
-
- server {
- listen 80;
- server_name $serverName;
-
- # allow large uploads of files
- client_max_body_size 1G;
-
- # optimize downloading files larger than 1G
- #proxy_max_temp_file_size 2G;
-
- location / {
- # Use IPv4 upstream address instead of DNS name to avoid attempts by nginx to use IPv6 DNS lookup
- proxy_pass http://127.0.0.1:8081/;
- proxy_set_header Host ${'$'}host;
- proxy_set_header X-Real-IP ${'$'}remote_addr;
- proxy_set_header X-Forwarded-For ${'$'}proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto "http";
- }
- }
- }
- """.trimIndent()
-}
-
-
-fun reverseProxyConfigSsl(serverName: String, ssl_certificate: String? = null, ssl_certificate_key: String? = null): String {
- // see https://help.sonatype.com/repomanager3/installation/run-behind-a-reverse-proxy
-
- val sslCertificateEntry = ssl_certificate?.let { "ssl_certificate $ssl_certificate;" } ?: "ssl_certificate /etc/letsencrypt/live/$serverName/fullchain.pem;"
- val sslCertificateKeyEntry = ssl_certificate?.let { "ssl_certificate_key $ssl_certificate_key;" } ?: "ssl_certificate_key /etc/letsencrypt/live/$serverName/privkey.pem"
-
- return """
-events {} # event context have to be defined to consider config valid
-
-http {
-
- proxy_send_timeout 120;
- proxy_read_timeout 300;
- proxy_buffering off;
- keepalive_timeout 5 5;
- tcp_nodelay on;
-
- server {
- listen *:443 ssl;
- server_name $serverName;
-
- # allow large uploads of files
- client_max_body_size 1G;
-
- # optimize downloading files larger than 1G
- # proxy_max_temp_file_size 2G;
-
- $sslCertificateEntry
- $sslCertificateKeyEntry
-
- location / {
- # Use IPv4 upstream address instead of DNS name to avoid attempts by nginx to use IPv6 DNS lookup
- proxy_pass http://127.0.0.1:8081/;
- proxy_set_header Host ${'$'}host;
- proxy_set_header X-Real-IP ${'$'}remote_addr;
- proxy_set_header X-Forwarded-For ${'$'}proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto "https";
- }
- }
-}
- """
-}
-
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/ProvisionNginx.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/ProvisionNginx.kt
deleted file mode 100644
index 51714ad..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/ProvisionNginx.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nginx
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.remote
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileExists
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.NginxConf
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.createNginxLocationFolders
-import kotlin.system.exitProcess
-
-
-internal const val configFile = "/etc/nginx/nginx.conf"
-
-
-fun Prov.provisionNginxStandAlone(config: NginxConf? = null) = requireAll {
-
- aptInstall("nginx")
-
- createNginxLocationFolders()
-
- if (config != null) {
- if (fileExists(configFile)) {
- cmd("sudo mv $configFile $configFile-orig")
- }
- createFile(configFile, config.conf, sudo = true)
- val configCheck = cmd("sudo nginx -t")
- if (configCheck.success) {
- cmd("sudo service nginx restart")
- } else {
- ProvResult(false, err = "Nginx config is incorrect:\n" + configCheck.err)
- }
- } else {
- ProvResult(true) // dummy
- }
-}
-
-
-fun provisionRemote(vararg args: String) {
- if (args.size != 2) {
- println("Pls specify host and user for remote installation of nginx.")
- exitProcess(1)
- }
- remote(args[0], args[1]).provisionNginxStandAlone()
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/BasicAuth.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/BasicAuth.kt
deleted file mode 100644
index d9d48d2..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/BasicAuth.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-fun Prov.nginxAddBasicAuth(user: String, password: Secret) = requireAll {
- aptInstall("apache2-utils")
- val passwordFile = "/etc/nginx/.htpasswd"
- cmdNoLog("sudo htpasswd -b -c $passwordFile $user ${password.plain()}")
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/Configs.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/Configs.kt
deleted file mode 100644
index 40be12d..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/Configs.kt
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base
-
-class NginxConf(val conf: String = NGINX_MINIMAL_CONF) {
- companion object {}
-}
-
-
-const val NGINX_MINIMAL_CONF = """
-events {}
-
-http {
- server {
- listen 80;
-
- location / {
- return 200 'Hi from nginx!';
- }
- }
-}
-"""
-
-
-@Suppress("unused") // use later
-fun NginxConf.Companion.nginxHttpConf(
- serverName: String = "localhost"
-): NginxConf {
- return NginxConf(
- """
-events {}
-
-http {
- server {
- listen 80;
- server_name $serverName;
-
- include /etc/nginx/locations-enabled/port80*$locationsFileExtension;
- }
-}
-"""
- )
-}
-
-
-fun NginxConf.Companion.nginxHttpsConfWithLocationFiles(
- sslCertificate: String = "/etc/nginx/ssl/cert/selfsigned.crt",
- sslCertificateKey: String = "/etc/nginx/ssl/private/selfsigned.key"
-): NginxConf {
- return NginxConf(
- """
-events {}
-
-http {
- server {
- listen 443 ssl;
- server_name localhost;
-
- ssl_certificate $sslCertificate;
- ssl_certificate_key $sslCertificateKey;
-
- include /etc/nginx/locations-enabled/port443*$locationsFileExtension;
- }
-}
-"""
- )
-}
-
-
-@Suppress("unused") // use later
-fun NginxConf.Companion.nginxReverseProxySslConfig(
- serverName: String,
- ssl_certificate: String? = null,
- ssl_certificate_key: String? = null
-): NginxConf {
- // see https://help.sonatype.com/repomanager3/installation/run-behind-a-reverse-proxy
-
- val sslCertificateEntry = ssl_certificate?.let { "ssl_certificate $ssl_certificate;" }
- ?: "ssl_certificate /etc/letsencrypt/live/$serverName/fullchain.pem;"
- val sslCertificateKeyEntry = ssl_certificate?.let { "ssl_certificate_key $ssl_certificate_key;" }
- ?: "ssl_certificate_key /etc/letsencrypt/live/$serverName/privkey.pem"
-
- return NginxConf(
- """
-events {} # event context have to be defined to consider config valid
-
-http {
-
- proxy_send_timeout 120;
- proxy_read_timeout 300;
- proxy_buffering off;
- keepalive_timeout 5 5;
- tcp_nodelay on;
-
- server {
- listen *:443 ssl;
- server_name $serverName;
-
- # allow large uploads of files
- client_max_body_size 1G;
-
- # optimize downloading files larger than 1G
- #proxy_max_temp_file_size 2G;
-
- $sslCertificateEntry
- $sslCertificateKeyEntry
-
- location / {
- # Use IPv4 upstream address instead of DNS name to avoid attempts by nginx to use IPv6 DNS lookup
- proxy_pass http://127.0.0.1:8081/;
- proxy_set_header Host ${'$'}host;
- proxy_set_header X-Real-IP ${'$'}remote_addr;
- proxy_set_header X-Forwarded-For ${'$'}proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto "https";
- }
- }
-}
- """
- )
-}
-
-
-@Suppress("unused") // use later
-fun NginxConf.Companion.nginxReverseProxyHttpConfig(
- serverName: String
-): NginxConf {
- // see https://help.sonatype.com/repomanager3/installation/run-behind-a-reverse-proxy
-
- return NginxConf(
- """
-events {} # event context have to be defined to consider config valid
-
-http {
-
- proxy_send_timeout 120;
- proxy_read_timeout 300;
- proxy_buffering off;
- keepalive_timeout 5 5;
- tcp_nodelay on;
-
- server {
- listen *:80;
- server_name $serverName;
-
- # allow large uploads of files
- client_max_body_size 1G;
-
- # optimize downloading files larger than 1G
- #proxy_max_temp_file_size 2G;
-
- location / {
- # Use IPv4 upstream address instead of DNS name to avoid attempts by nginx to use IPv6 DNS lookup
- proxy_pass http://127.0.0.1:8081/;
- proxy_set_header Host ${'$'}host;
- proxy_set_header X-Real-IP ${'$'}remote_addr;
- proxy_set_header X-Forwarded-For ${'$'}proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto "https";
- }
- }
-}
- """
- )
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/Locations.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/Locations.kt
deleted file mode 100644
index cf14cc7..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/Locations.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.*
-
-
-internal const val locationsAvailableDir = "/etc/nginx/locations-available/"
-internal const val locationsEnabledDir = "/etc/nginx/locations-enabled/"
-internal const val locationsFileExtension = ".locations"
-
-
-fun Prov.createNginxLocationFolders() = requireAll {
- createDirs(locationsEnabledDir, sudo = true)
- createDirs(locationsAvailableDir, sudo = true)
-}
-
-
-fun Prov.nginxIncludeLocationFolders() = requireAll {
- replaceTextInFile("/etc/nginx/nginx.conf", "listen 80;\n",
- """listen 80;
- include ${locationsAvailableDir}port80*$locationsFileExtension;
- include ${locationsEnabledDir}port443*$locationsFileExtension;
- """)
-}
-
-
-fun Prov.nginxAddLocation(port: String, locationFileName: String, urlPath: String, content: String) = requireAll {
-
- val locationConf = """location $urlPath {""" +
- content +
- "\n}"
-
- if (!dirExists(locationsAvailableDir, sudo = true)) {
- createNginxLocationFolders()
- }
-
- createFile("${locationsAvailableDir}port${port}_$locationFileName$locationsFileExtension", locationConf, sudo = true)
- if (!fileExists("${locationsEnabledDir}port${port}_$locationFileName$locationsFileExtension", sudo = true)) {
- cmd("sudo ln -s ${locationsAvailableDir}port${port}_$locationFileName$locationsFileExtension ${locationsEnabledDir}port${port}_$locationFileName$locationsFileExtension ")
- } else {
- ProvResult(true)
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/SelfSignedCertificate.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/SelfSignedCertificate.kt
deleted file mode 100644
index 196aad7..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/SelfSignedCertificate.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.provisionNginxStandAlone
-
-
-internal val certificateName = "selfsigned"
-internal val sslDays = 365
-val dirSslCert="/etc/nginx/ssl/cert"
-val dirSslKey="/etc/nginx/ssl/private"
-
-
-fun Prov.nginxCreateSelfSignedCertificate(
- country: String = "DE",
- state: String = "test",
- locality: String = "test",
- organization: String = "test",
- organizationalUnit: String = "test",
- commonName: String = "test",
- email : String = "test@test.net"
-) = def {
- // inspired by https://gist.github.com/adrianorsouza/2bbfe5e197ce1c0b97c8
- createDirs(dirSslCert, sudo = true)
- createDirs(dirSslKey, sudo = true)
- cmd("cd $dirSslKey && sudo openssl req -x509 -nodes -newkey rsa:2048 -keyout $certificateName.key -out $certificateName.crt -days $sslDays -subj \"/C=$country/ST=$state/L=$locality/O=$organization/OU=$organizationalUnit/CN=$commonName/emailAddress=$email\"")
- cmd("sudo mv $dirSslKey/$certificateName.crt $dirSslCert/")
-}
-
-
-fun Prov.configureNginxWithSelfSignedCertificate() = def {
- // todo: should not call provisionNginxStandAlone, which is defined in the package above
- provisionNginxStandAlone(NginxConf.nginxReverseProxySslConfig("localhost",
- dirSslCert+"/"+ certificateName + ".crt",
- dirSslKey + "/" + certificateName + ".key"))
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/ProvisionPrometheus.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/ProvisionPrometheus.kt
deleted file mode 100644
index d138fb0..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/ProvisionPrometheus.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.prometheus
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.base.*
-
-/**
- * Provisions prometheus monitoring.
- * If running behind an nginx, pls specify the hostname in parameter nginxHost (e.g. mydomain.com).
- * To run it without nodeExporter (which provides system data to prometheus), set withNodeExporter to false.
- */
-fun Prov.provisionPrometheusDocker(nginxHost: String? = null, withNodeExporter: Boolean = true) = def {
- configurePrometheusDocker()
- if (withNodeExporter) {
- installNodeExporter()
- runNodeExporter()
- addNodeExporterToPrometheusConf()
- }
- runPrometheusDocker(nginxHost)
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/NodeExporter.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/NodeExporter.kt
deleted file mode 100644
index be205d4..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/NodeExporter.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileContainsText
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.replaceTextInFile
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.user.base.whoami
-
-
-internal val defaultInstallationDir = "/usr/local/bin/"
-
-
-fun Prov.installNodeExporter() = requireAll {
- // inspired by https://devopscube.com/monitor-linux-servers-prometheus-node-exporter/ and
- // https://www.howtoforge.com/tutorial/how-to-install-prometheus-and-node-exporter-on-centos-8/#step-install-and-configure-nodeexporter
- val downloadFileBasename = "node_exporter-1.0.1.linux-amd64"
- val downloadFile = "$downloadFileBasename.tar.gz"
- val downloadPath = "~/tmp/"
- val fqFile = downloadPath + downloadFile
-
- aptInstall("curl")
- createDir("tmp")
- sh(
- """
- cd tmp && curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.0.1/$downloadFile --output $downloadFile
- cd tmp && tar -xvf $fqFile -C $downloadPath
-
- sudo mv $downloadPath$downloadFileBasename/node_exporter $defaultInstallationDir"""
- )
-
-}
-
-
-fun Prov.runNodeExporter() = def {
- createFile("/etc/systemd/system/node_exporter.service", nodeExporterServiceConf(whoami()?:"nouserfound"), sudo = true)
-
- sh("""
- sudo systemctl daemon-reload
-
- # start the node_exporter service and enable it to launch everytime at system startup.
- sudo systemctl start node_exporter
- sudo systemctl enable node_exporter
-
- # check if running
- sudo systemctl status node_exporter --no-pager -l
- """)
-}
-
-
-fun Prov.addNodeExporterToPrometheusConf (
- prometheusConf: String = "/etc/prometheus/prometheus.yml",
- sudo: Boolean = true
-) = requireAll {
- val prometheusConfNodeExporter = """
-scrape_configs:
- - job_name: 'node_exporter'
- static_configs:
- - targets: ['172.17.0.1:9100']
-"""
- if (!fileContainsText(prometheusConf, "- job_name: 'node_exporter'", sudo)) {
- replaceTextInFile(prometheusConf, "\nscrape_configs:\n", prometheusConfNodeExporter)
- }
- // cmd("sudo systemctl restart prometheus") for standalone
- cmd("sudo docker restart prometheus")
-}
-
-
-fun nodeExporterServiceConf(user: String, installationDir: String = defaultInstallationDir): String {
- return """
-[Unit]
-Description=Node Exporter
-Wants=network-online.target
-After=network-online.target
-
-[Service]
-User=$user
-ExecStart=${installationDir}node_exporter
-
-[Install]
-WantedBy=default.target
-"""
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/Prometheus.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/Prometheus.kt
deleted file mode 100644
index 5b3fea4..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/Prometheus.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.docker.containerRuns
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-
-internal val configDir = "/etc/prometheus/"
-internal val configFile = "prometheus.yml"
-
-
-fun Prov.configurePrometheusDocker(config: String = prometheusDefaultConfig) = requireAll {
- createDirs(configDir, sudo = true)
- createFile(configDir + configFile, config, sudo = true)
-}
-
-
-fun Prov.runPrometheusDocker(nginxHost: String? = null) = requireAll {
- aptInstall("docker.io")
-
- val containerName = "prometheus"
-
- if (containerRuns(containerName)) {
- cmd("sudo docker restart $containerName")
- } else {
- if (nginxHost == null) {
- cmd(
- "sudo docker run -d -p 9090:9090 " +
- " --name $containerName " +
- " --restart on-failure:1" +
- " -v prometheus-data:/prometheus" +
- " -v $configDir$configFile:/etc/prometheus/prometheus.yml " +
- " prom/prometheus"
- )
- } else {
- cmd(
- "sudo docker run -d -p 9090:9090 " +
- " --name $containerName " +
- " --restart on-failure:1" +
- " -v prometheus-data:/prometheus" +
- " -v $configDir$configFile:/etc/prometheus/prometheus.yml " +
- " prom/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus " +
- "--web.console.libraries=/usr/share/prometheus/console_libraries " +
- "--web.console.templates=/usr/share/prometheus/consoles " +
- "--web.external-url=http://$nginxHost/prometheus"
- )
- }
- }
-}
-
-
-private const val prometheusDefaultConfig =
- """
-global:
- scrape_interval: 15s # By default, scrape targets every 15 seconds.
-
- # Attach these labels to any time series or alerts when communicating with
- # external systems (federation, remote storage, Alertmanager).
- external_labels:
- monitor: 'codelab-monitor'
-
-# A scrape configuration containing exactly one endpoint to scrape:
-# Here it's Prometheus itself.
-scrape_configs:
- # The job name is added as a label `job=` to any timeseries scraped from this config.
- - job_name: 'prometheus'
-
- # Override the global default and scrape targets from this job every 5 seconds.
- scrape_interval: 5s
-
- static_configs:
- - targets: ['localhost:9090']
-"""
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/PrometheusNginxConfig.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/PrometheusNginxConfig.kt
deleted file mode 100644
index 39fdb22..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/server_software/prometheus/base/PrometheusNginxConfig.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.prometheus.base
-
-val prometheusNginxConfig = """
- proxy_pass http://localhost:9090/prometheus;
-"""
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/ProvisionWorkplace.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/ProvisionWorkplace.kt
deleted file mode 100644
index c5146c4..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/ProvisionWorkplace.kt
+++ /dev/null
@@ -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.extensions.workplace.base.*
-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.provisionKeysCurrentUser
-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 java.net.InetAddress
-import kotlin.system.exitProcess
-
-
-enum class WorkplaceType {
- MINIMAL, OFFICE, IDE
-}
-
-
-/**
- * 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 a password, but he must be able to in order to provisionWorkplace")
- }
-
- aptInstall("ssh gnupg curl git")
-
- provisionKeysCurrentUser(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")
- }
-
- 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
- * 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) {
- 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 = readWorkplaceConfigFromFile() ?: WorkplaceConfig()
- Prov.newInstance(RemoteProcessor(host, userName, pwFromSecret), OS.LINUX.name).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)
- *
- * 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) {
- provisionRemote(args = args)
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/WorkplaceConfig.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/WorkplaceConfig.kt
deleted file mode 100644
index de75195..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/WorkplaceConfig.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace
-
-import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPairSource
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.json.Json
-import java.io.*
-
-
-@Serializable
-class WorkplaceConfig(
- val type: WorkplaceType = WorkplaceType.MINIMAL,
- val ssh: KeyPairSource? = null,
- val gpg: KeyPairSource? = null,
- val gitUserName: String? = null,
- val gitEmail: String? = null,
-)
-
-
-// -------------------------------------------- file methods ------------------------------------
-fun readWorkplaceConfigFromFile(filename: String = "WorkplaceConfig.json"): WorkplaceConfig? {
- val file = File(filename)
- return if (file.exists())
- try {
- // read from file
- val inputAsString = BufferedReader(FileReader(filename)).use { it.readText() }
-
- return Json.decodeFromString(WorkplaceConfig.serializer(), inputAsString)
- } catch (e: FileNotFoundException) {
- null
- } else null
-}
-
-
-fun writeWorkplaceConfigToFile(config: WorkplaceConfig) {
- val fileName = "WorkplaceConfig.json"
-
- FileWriter(fileName).use { it.write(Json.encodeToString(WorkplaceConfig.serializer(), config)) }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Docker.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Docker.kt
deleted file mode 100644
index 1892f4f..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Docker.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-fun Prov.installDocker() = def {
- aptInstall("containerd docker.io")
- if (!chk("getent group docker")) {
- cmd("sudo groupadd docker")
- }
- cmd("sudo gpasswd -a \$USER docker")
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Fakturama.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Fakturama.kt
deleted file mode 100644
index 06a9440..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Fakturama.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.web.base.downloadFromURL
-
-
-fun Prov.installFakturama() = def {
- createDir("/tmp", sudo = true)
- downloadFromURL( "https://files.fakturama.info/release/v2.1.1/Installer_Fakturama_linux_x64_2.1.1b.deb", "fakturama.deb", "/tmp")
- cmd("sudo dpkg -i fakturama.deb", "/tmp")
-
- createDir("/opt/fakturama", sudo = true)
- val filename = "Handbuch-Fakturama_2.1.1.pdf"
- downloadFromURL( "https://files.fakturama.info/release/v2.1.1/Handbuch-Fakturama_2.1.1.pdf", filename, "/tmp")
- cmd("sudo mv /tmp/$filename /opt/fakturama")
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Gopass.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Gopass.kt
deleted file mode 100644
index c5050fd..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Gopass.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.userHome
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
-
-
-fun Prov.installGopass(version: String = "1.12.7", enforceVersion: Boolean = false) = def {
- if (isPackageInstalled("gopass") && !enforceVersion) {
- ProvResult(true)
- } else {
- // install required dependencies
- aptInstall("rng-tools gnupg2 git")
- aptInstall("curl")
-
- sh(
- """
- curl -L https://github.com/gopasspw/gopass/releases/download/v${version}/gopass_${version}_linux_amd64.deb -o gopass_${version}_linux_amd64.deb
- sudo dpkg -i gopass_${version}_linux_amd64.deb
- """
- )
- gopassEnsureVersion(version)
- }
-}
-
-
-fun Prov.configureGopass(gopassRootFolder: String? = null) = def {
- val defaultRootFolder = userHome() + ".password-store"
- val rootFolder = gopassRootFolder ?: defaultRootFolder
- // use default
- createDir(rootFolder)
- createDirs(".config/gopass")
- createFile("~/.config/gopass/config.yml", gopassConfig(rootFolder))
-}
-
-
-fun Prov.gopassMountStore(storeName: String, path: String, indexOfRecepientKey: Int = 0) = def {
- cmd("printf \"$indexOfRecepientKey\\n\" | gopass mounts add $storeName $path")
-}
-
-
-internal fun gopassConfig(gopassRoot: String): String {
- return """
-root:
- askformore: false
- autoclip: true
- autoprint: false
- autoimport: true
- autosync: false
- check_recipient_hash: false
- cliptimeout: 45
- concurrency: 1
- editrecipients: false
- exportkeys: true
- nocolor: false
- noconfirm: true
- nopager: false
- notifications: true
- path: gpgcli-gitcli-fs+file://$gopassRoot
- recipient_hash:
- .gpg-id: 3078303637343130344341383141343930350aa69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26
- safecontent: false
- usesymbols: false
-mounts: {}
- """.trim() + "\n"
-}
-
-
-/**
- * Returns true if gopass is installed and has the given version.
- *
- * @param version that is checked; specifies left part of text of installed version, e.g. both "1" and "1.12" will return true if installed version is "1.12.6+8d7a311b9273846bbb618e4bd9ddbae51b1db7b8"
- */
-internal fun Prov.gopassEnsureVersion(version: String) = def {
- val installedGopassVersion = gopassVersion()
- if (installedGopassVersion != null && installedGopassVersion.startsWith("gopass " + version)) {
- ProvResult(true, out = "Required gopass version ($version) matches installed version ($installedGopassVersion)")
- } else {
- ProvResult(false, err = "Wrong gopass version. Expected $version but found $installedGopassVersion")
- }
-}
-
-internal fun Prov.gopassVersion(): String? {
- val result = cmdNoEval("gopass -v")
- return if (!result.success) null else result.out
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassBridge.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassBridge.kt
deleted file mode 100644
index 92f1531..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassBridge.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.userHome
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
-import org.domaindrivenarchitecture.provs.ubuntu.web.base.downloadFromURL
-
-
-fun Prov.downloadGopassBridge() = def {
- val version = "0.8.0"
- val filename = "gopass_bridge-${version}-fx.xpi"
- val downloadDir = "${userHome()}Downloads/"
-
- createDirs(downloadDir)
- downloadFromURL(
- "-L https://addons.mozilla.org/firefox/downloads/file/3630534/" + filename,
- downloadDir + filename
- )
- // needs manual install with: firefox Downloads/gopass_bridge-0.8.0-fx.xpi
-}
-
-fun Prov.installGopassBridgeJsonApi() = def {
- // see https://github.com/gopasspw/gopass-jsonapi
- val gopassBridgeVersion = "1.11.1"
- val requiredGopassVersion = "1.12"
- val filename = "gopass-jsonapi_${gopassBridgeVersion}_linux_amd64.deb"
- val downloadUrl = "-L https://github.com/gopasspw/gopass-jsonapi/releases/download/v$gopassBridgeVersion/$filename"
- val downloadDir = "${userHome()}Downloads"
- val installedJsonApiVersion = gopassJsonApiVersion()?.trim()
-
- if (installedJsonApiVersion == null) {
- if (chk("gopass ls")) {
- if (gopassEnsureVersion(requiredGopassVersion).success) {
- aptInstall("git gnupg2") // required dependencies
- createDir(downloadDir)
- downloadFromURL(downloadUrl, filename, downloadDir)
- cmd("dpkg -i " + downloadDir + "/" + filename, sudo = true)
- } else {
- ProvResult(
- false,
- "Version of currently installed gopass (" + gopassVersion() + ") is incompatible with gopass-jsonapi version to be installed. " +
- "Please upgrade gopass to version: " + requiredGopassVersion
- )
- }
- } else {
- addResultToEval(
- ProvResult(
- false,
- "gopass not initialized correctly. You can initialize gopass with: \"gopass init\""
- )
- )
- }
- } else {
- if (installedJsonApiVersion.startsWith("gopass-jsonapi version " + gopassBridgeVersion)) {
- addResultToEval(ProvResult(true, out = "Version $gopassBridgeVersion of gopass-jsonapi is already installed"))
- } else {
- addResultToEval(
- ProvResult(
- false,
- err = "gopass-jsonapi (version $gopassBridgeVersion) cannot be installed as version $installedJsonApiVersion is already installed." +
- " Upgrading gopass-jsonapi is currently not supported by provs."
- )
- )
- }
- }
-}
-
-fun Prov.configureGopassBridgeJsonApi() = def {
- if (isPackageInstalled("gopass-jsonapi")) {
- // configure for firefox and choose default for each:
- // "Install for all users? [y/N/q]",
- // "In which path should gopass_wrapper.sh be installed? [/home/testuser/.config/gopass]"
- // "Wrapper Script for gopass_wrapper.sh ..."
- cmd("printf \"\\n\\n\\n\" | gopass-jsonapi configure --browser firefox")
- } else {
- ProvResult(
- false,
- err = "gopass-jsonapi is missing. Gopass-jsonapi must be installed to be able to configure it."
- )
- }
-}
-
-internal fun Prov.gopassJsonApiVersion(): String? {
- val result = cmdNoEval("gopass-jsonapi -v")
- return if (!result.success) null else result.out
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/NoSwappiness.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/NoSwappiness.kt
deleted file mode 100644
index ba63836..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/NoSwappiness.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.addTextToFile
-import java.io.File
-
-fun Prov.configureNoSwappiness() = def {
- // set swappiness to 0
- addTextToFile("vm.swappiness=0", File("/etc/sysctl.conf"), sudo = true)
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/PackageBundles.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/PackageBundles.kt
deleted file mode 100644
index 2d9e984..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/PackageBundles.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-val OS_ANALYSIS = "lsof strace ncdu iptraf htop iotop iftop"
-
-val ZIP_UTILS = "p7zip-rar p7zip-full rar unrar zip unzip"
-
-val BASH_UTILS = "bash-completion"
-
-val SPELLCHECKING_DE = "hyphen-de hunspell hunspell-de-de"
-
-val OPEN_VPM = "openvpn network-manager-openvpn network-manager-openvpn-gnome"
-
-val OPENCONNECT = "openconnect network-manager-openconnect network-manager-openconnect-gnome"
-
-val VPNC = "vpnc network-manager-vpnc network-manager-vpnc-gnome vpnc-scripts"
-
-val JAVA_JDK = "openjdk-8-jdk openjdk-11-jdk openjdk-14-jdk"
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Redshift.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Redshift.kt
deleted file mode 100644
index 8541da4..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Redshift.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-
-fun Prov.installRedshift() = def {
- aptInstall("redshift redshift-gtk")
-}
-
-
-fun Prov.configureRedshift() = def {
- aptInstall("redshift redshift-gtk")
-
- createDir(".config")
- createFile("~/.config/redshift.conf", config)
-}
-
-
-val config = """
- [redshift]
- temp-day=5500
- temp-night=2700
- brightness-day=1
- brightness-night=0.6
- fade=1
-
- location-provider=manual
-
- [manual]
- lat=48.783333
- lon=9.1833334
-""".trimIndent()
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/VSCode.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/VSCode.kt
deleted file mode 100644
index fc70a3d..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/VSCode.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-
-fun Prov.installVSC(vararg options: String) = requireAll {
- val clojureExtensions =
- arrayListOf("betterthantomorrow.calva", "martinklepsch.clojure-joker-linter", "DavidAnson.vscode-markdownlint")
- val pythonExtensions = arrayListOf("ms-python.python")
-
- prerequisitesVSCinstall()
-
- installVSCPackage()
-
- if (options.contains("clojure")) {
- installExtensions(clojureExtensions)
- }
- if (options.contains("python")) {
- installExtensions(pythonExtensions)
- }
-
- provisionAdditionalTools()
-}
-
-
-private fun Prov.prerequisitesVSCinstall() = def {
- aptInstall("curl gpg unzip apt-transport-https")
-}
-
-
-@Suppress("unused") // only required for installation of vscode via apt
-private fun Prov.configurePackageManagerForVsc() = requireAll {
- // see https://code.visualstudio.com/docs/setup/linux
- // alternatively install with snapd (but this cannot be tested within docker as snapd within docker is not working/supported)
-
- sh(
- """
- curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
- sudo install -o root -g root -m 644 packages.microsoft.gpg /etc/apt/trusted.gpg.d/
- sudo sh -c 'echo \"deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/packages.microsoft.gpg] https://packages.microsoft.com/repos/vscode stable main\" > /etc/apt/sources.list.d/vscode.list'
- """
- )
- aptInstall("apt-transport-https")
- aptInstall("code")
-}
-
-
-private fun Prov.installVSCPackage() = def {
- cmd("sudo snap install code --classic")
-
- // to install via apt use:
- // configurePackageManagerForVsc()
- // aptInstall("code")
-
-}
-
-
-private fun Prov.installExtensions(extensions: List) = optional {
- var res = ProvResult(true)
- for (ext in extensions) {
- res = cmd("code --install-extension $ext")
- }
- res
- // Settings can be found at $HOME/.config/Code/User/settings.json
-}
-
-
-private fun Prov.provisionAdditionalTools() = requireAll {
- // Joker
- cmd("curl -Lo joker-0.12.2-linux-amd64.zip https://github.com/candid82/joker/releases/download/v0.12.2/joker-0.12.2-linux-amd64.zip")
- cmd("unzip joker-0.12.2-linux-amd64.zip")
- cmd("sudo mv joker /usr/local/bin/")
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/VirtualBoxGuest.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/VirtualBoxGuest.kt
deleted file mode 100644
index 45763d6..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/VirtualBoxGuest.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.user.base.whoami
-
-fun Prov.installVirtualBoxGuestAdditions() = def {
- // if running in a VirtualBox vm
- if (!chk("lspci | grep VirtualBox")) {
- return@def ProvResult(true, "Not running in a VirtualBox")
- }
-
- if (chk("VBoxService --version")) {
- return@def ProvResult(true, "VBoxService already installed")
- }
-
- // install guest additions
- cmd("sudo add-apt-repository multiverse")
- aptInstall("virtualbox-guest-x11") // virtualbox-guest-dkms")
- // and add user to group vboxsf e.g. to be able to use shared folders
- whoami()?.let { cmd("sudo usermod -G vboxsf -a " + it) }
- ?: ProvResult(true)
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Zim.kt b/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Zim.kt
deleted file mode 100644
index 1c4295a..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/extensions/workplace/base/Zim.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstallFromPpa
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
-
-
-fun Prov.installZimWiki() = def {
- if (isPackageInstalled("zim")) {
- ProvResult(true, out = "zim already installed.")
- } else {
- aptInstallFromPpa("jaap.karssenberg", "zim", "zim")
- aptInstall("python3-gtkspellcheck")
- }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/filesystem/base/Filesystem.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/filesystem/base/Filesystem.kt
deleted file mode 100644
index d97e4bd..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/filesystem/base/Filesystem.kt
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.filesystem.base
-
-import org.domaindrivenarchitecture.provs.core.*
-import org.domaindrivenarchitecture.provs.core.platforms.SHELL
-import java.io.File
-
-
-fun Prov.fileExists(file: String, sudo: Boolean = false): Boolean {
- return cmdNoEval((if (sudo) "sudo " else "") + "test -e " + file).success
-}
-
-
-fun Prov.createFile(
- fullyQualifiedFilename: String,
- text: String?,
- posixFilePermission: String? = null,
- sudo: Boolean = false
-): ProvResult =
- def {
- val withSudo = if (sudo) "sudo " else ""
- posixFilePermission?.let {
- ensureValidPosixFilePermission(posixFilePermission)
- cmd(withSudo + "install -m $posixFilePermission /dev/null $fullyQualifiedFilename")
- }
- if (text != null) {
- if (sudo) {
- cmd(
- "printf " + text.escapeProcentForPrintf()
- .escapeAndEncloseByDoubleQuoteForShell() + " | sudo tee $fullyQualifiedFilename > /dev/null"
- )
- } else {
- cmd(
- "printf " + text.escapeProcentForPrintf()
- .escapeAndEncloseByDoubleQuoteForShell() + " > $fullyQualifiedFilename"
- )
- }
- } else {
- cmd(withSudo + "touch $fullyQualifiedFilename")
- }
- }
-
-
-fun Prov.createSecretFile(
- fullyQualifiedFilename: String,
- secret: Secret,
- posixFilePermission: String? = null
-): ProvResult =
- def {
- posixFilePermission?.let {
- ensureValidPosixFilePermission(posixFilePermission)
- cmd("install -m $posixFilePermission /dev/null $fullyQualifiedFilename")
- }
- cmdNoLog("echo '" + secret.plain().escapeSingleQuote() + "' > $fullyQualifiedFilename")
- }
-
-
-fun Prov.deleteFile(file: String, sudo: Boolean = false): ProvResult = def {
- cmd((if (sudo) "sudo " else "") + "rm $file")
-}
-
-
-fun Prov.fileContainsText(file: String, content: String, sudo: Boolean = false): Boolean {
- return cmdNoEval((if (sudo) "sudo " else "") + "grep '${content.escapeSingleQuote()}' $file").success
-}
-
-
-fun Prov.fileContent(file: String, sudo: Boolean = false): String? {
- return cmd((if (sudo) "sudo " else "") + "cat $file").out
-}
-
-
-fun Prov.addTextToFile(
- text: String,
- file: File,
- doNotAddIfExisting: Boolean = true,
- sudo: Boolean = false
-): ProvResult =
- def {
- // TODO find solution without trim handling spaces, newlines, etc correctly
- val findCmd = "grep '${text.trim().escapeSingleQuote()}' ${file}"
- val findResult = cmdNoEval(if (sudo) findCmd.sudoizeCommand() else findCmd)
- if (!findResult.success || !doNotAddIfExisting) {
- val addCmd = "printf \"" + text.escapeDoubleQuote() + "\" >> " + file
- cmd(if (sudo) addCmd.sudoizeCommand() else addCmd)
- } else {
- ProvResult(true)
- }
- }
-
-
-fun Prov.replaceTextInFile(file: String, oldText: String, replacement: String) = def {
- replaceTextInFile(file, Regex.fromLiteral(oldText), Regex.escapeReplacement(replacement))
-}
-
-
-fun Prov.replaceTextInFile(file: String, oldText: Regex, replacement: String) = def {
- // todo: only use sudo for root or if owner different from current
- val content = fileContent(file, true)
- if (content != null) {
- cmd("sudo truncate -s 0 $file")
- addTextToFile(content.replace(oldText, Regex.escapeReplacement(replacement)), File(file), sudo = true)
- } else {
- ProvResult(false)
- }
-}
-
-
-fun Prov.insertTextInFile(file: String, textBehindWhichToInsert: Regex, textToInsert: String) = def {
- // todo: only use sudo for root or if owner different from current
- val content = fileContent(file, true)
- if (content != null) {
- val match = textBehindWhichToInsert.find(content)
- if (match != null) {
- cmd("sudo truncate -s 0 $file")
- addTextToFile(
- content.replace(textBehindWhichToInsert, match.value + Regex.escapeReplacement(textToInsert)),
- File(file),
- sudo = true
- )
- } else {
- ProvResult(false, err = "Text not found")
- }
- } else {
- ProvResult(false)
- }
-}
-
-
-fun Prov.dirExists(dir: String, path: String? = null, sudo: Boolean = false): Boolean {
- val effectivePath = if (path != null) path else
- (if (dir.startsWith(File.separator)) File.separator else "~" + File.separator)
- val cmd = "cd $effectivePath && test -d $dir"
- return cmdNoEval(if (sudo) cmd.sudoizeCommand() else cmd).success
-}
-
-
-fun Prov.createDir(
- dir: String,
- path: String = "~/",
- failIfExisting: Boolean = false,
- sudo: Boolean = false
-): ProvResult = def {
- if (!failIfExisting && dirExists(dir, path, sudo)) {
- ProvResult(true)
- } else {
- val cmd = "cd $path && mkdir $dir"
- cmd(if (sudo) cmd.sudoizeCommand() else cmd)
- }
-}
-
-
-fun Prov.createDirs(
- dirs: String,
- path: String = "~/",
- failIfExisting: Boolean = false,
- sudo: Boolean = false
-): ProvResult = def {
- if (!failIfExisting && dirExists(dirs, path, sudo)) {
- ProvResult(true)
- } else {
- val cmd = "cd $path && mkdir -p $dirs"
- cmd(if (sudo) cmd.sudoizeCommand() else cmd)
- }
-}
-
-
-fun Prov.deleteDir(dir: String, path: String, sudo: Boolean = false): ProvResult {
- if ("" == path)
- throw RuntimeException("In deleteDir: path must not be empty.")
- val cmd = "cd $path && rmdir $dir"
- return if (!sudo) {
- cmd(cmd)
- } else {
- cmd(cmd.sudoizeCommand())
- }
-}
-
-
-fun Prov.userHome(): String {
- val user = cmd("whoami").out
- if (user == null) {
- throw RuntimeException("Could not determine user with whoami")
- } else {
- // assume default home folder
- return "/home/" + user.trim() + "/"
- }
-}
-
-
-private fun ensureValidPosixFilePermission(posixFilePermission: String) {
- if (!Regex("^[0-7]{3}$").matches(posixFilePermission)) throw RuntimeException("Wrong file permission ($posixFilePermission), permission must consist of 3 digits as e.g. 664 ")
-}
-
-
-private fun String.sudoizeCommand(): String {
- return "sudo " + SHELL + " -c " + this.escapeAndEncloseByDoubleQuoteForShell()
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/git/ProvisionGit.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/git/ProvisionGit.kt
deleted file mode 100644
index f96b57a..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/git/ProvisionGit.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.git
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-
-
-fun Prov.provisionGit(
- userName: String? = null,
- email: String? = null,
- signingKey: String? = null,
- diffTool: String? = null
-): ProvResult = def {
-
- aptInstall("git")
-
- cmd("git config --global push.default simple")
- userName?.let { cmd("git config --global user.name $it") }
- email?.let { cmd("git config --global user.email $it") }
- signingKey?.let { cmd("git config --global user.signingkey $it") }
- diffTool?.let { cmd("git config --global --add diff.tool $it") } ?: ProvResult(true)
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/git/base/Git.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/git/base/Git.kt
deleted file mode 100644
index ab127b7..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/git/base/Git.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.git.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.addTextToFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.dirExists
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.isHostKnown
-import org.domaindrivenarchitecture.provs.ubuntu.utils.printToShell
-import java.io.File
-
-
-/**
- * @param host name or ip
- * @param rsaFingerprints
- */
-private fun Prov.trustHost(host: String, rsaFingerprints: Set) = def {
- if (!isHostKnown(host)) {
- // logic based on https://serverfault.com/questions/447028/non-interactive-git-clone-ssh-fingerprint-prompt
- val key = cmd("ssh-keyscan $host").out
- if (key == null) {
- ProvResult(false, "No key retrieved for $host")
- } else {
- val c = printToShell(key).trim()
- val fpr = cmd(c + " | ssh-keygen -lf -").out
- if (rsaFingerprints.contains(fpr)
- ) {
- createDir(".ssh", "~/")
- cmd(printToShell(key) + " >> ~/.ssh/known_hosts")
- } else {
- ProvResult(false, "Fingerprint $fpr not valid for $host")
- }
- }
- } else {
- ProvResult(true)
- }
-}
-
-
-fun Prov.gitClone(repo: String, path: String, pullIfExisting: Boolean = true): ProvResult = def {
- val dir = cmdNoEval("basename $repo .git").out?.trim()
- if (dir == null) {
- ProvResult(false, err = "$repo is not a valid git repository")
- } else {
- val pathToDir = if (path.endsWith("/")) path + dir else path + "/" + dir
- if (dirExists(pathToDir + "/.git/")) {
- if (pullIfExisting) {
- cmd("cd $pathToDir && git pull")
- } else {
- ProvResult(true, out = "Repo $repo is already existing")
- }
- } else {
- cmd("cd $path && git clone $repo")
- }
- }
-}
-
-
-fun Prov.trustGithub() = def {
- // current see https://docs.github.com/en/github/authenticating-to-github/githubs-ssh-key-fingerprints
- val fingerprints = setOf(
- "2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)\n",
- "2048 SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ github.com (RSA)\n"
- )
-
- trustHost("github.com", fingerprints)
-}
-
-
-fun Prov.trustGitlab() = def {
- // from https://docs.gitlab.com/ee/user/gitlab_com/
- val gitlabFingerprints = """
- gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
- gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
- gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
- """.trimIndent()
- addTextToFile("\n" + gitlabFingerprints+ "\n", File("~/.ssh/known_hosts"))
-}
-
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/install/base/Install.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/install/base/Install.kt
deleted file mode 100644
index 83c09af..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/install/base/Install.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.install.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-
-
-private var aptInit = false
-
-/**
- * Installs package(s) by using package manager "apt".
- *
- * @param packages the packages to be installed, packages separated by space if there are more than one
- */
-fun Prov.aptInstall(packages: String): ProvResult = def {
- if (!aptInit) {
- cmd("sudo apt-get update")
- cmd("sudo apt-get install -qy apt-utils")
- aptInit = true
- }
-
- val packageList = packages.split(" ")
- for (packg in packageList) {
- // see https://superuser.com/questions/164553/automatically-answer-yes-when-using-apt-get-install
- cmd("sudo DEBIAN_FRONTEND=noninteractive apt-get install -qy $packg")
- }
- ProvResult(true) // dummy
-}
-
-
-/**
- * Installs a package from a ppa (personal package archive) by using package manager "apt".
- *
- * @param packageName the package to install
- */
-fun Prov.aptInstallFromPpa(launchPadUser: String, ppaName: String, packageName: String): ProvResult = def {
- aptInstall("software-properties-common") // for being able to use add-apt-repository
- cmd("sudo add-apt-repository -y ppa:$launchPadUser/$ppaName")
- aptInstall(packageName)
-}
-
-
-/**
- * Checks if a program is installed
- *
- * @param packageName to check
- * @return true if program is installed
- */
-@Suppress("unused") // used externally
-fun Prov.isPackageInstalled(packageName: String): Boolean {
- return chk("timeout 2 dpkg -l $packageName")
-}
-
-
-/**
- * Removes a package including its configuration and data files
- */
-@Suppress("unused") // used externally
-fun Prov.aptPurge(packageName: String): Boolean {
- return chk("sudo apt-get purge -qy $packageName")
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/ProvisionKeys.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/ProvisionKeys.kt
deleted file mode 100644
index 7b4bf0d..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/ProvisionKeys.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.keys
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.configureGpgKeys
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.configureSshKeys
-import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSourceType
-import kotlinx.serialization.Serializable
-
-
-open class KeyPair(val publicKey: Secret, val privateKey: Secret)
-
-
-@Serializable
-class KeyPairSource(val sourceType: SecretSourceType, val publicKey: String, val privateKey: String) {
- fun keyPair() : KeyPair {
- val pub = sourceType.secret(publicKey)
- val priv = sourceType.secret(privateKey)
- return KeyPair(pub, priv)
- }
-}
-
-
-/**
- * provisions gpg and/or ssh keys for the current user
- */
-fun Prov.provisionKeysCurrentUser(gpgKeys: KeyPair? = null, sshKeys: KeyPair? = null) = requireAll {
- gpgKeys?.let { configureGpgKeys(it, true) }
- sshKeys?.let { configureSshKeys(it) }
- ProvResult(true) // dummy
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/base/Gpg.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/base/Gpg.kt
deleted file mode 100644
index 701ffd8..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/base/Gpg.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.keys.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createSecretFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.dirExists
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
-import org.domaindrivenarchitecture.provs.ubuntu.utils.printToShell
-
-
-/**
- * Installs a gpg key pair for the current user.
- *
- * @param gpgKeys
- * @param trust whether to trust keys with trust-level 5 (ultimate)
- */
-fun Prov.configureGpgKeys(gpgKeys: KeyPair, trust: Boolean = false, skipIfExistin: Boolean = true) = requireAll {
- aptInstall("gnupg")
- val fingerprint = gpgFingerprint(gpgKeys.publicKey.plain())
- if (fingerprint == null) {
- ProvResult(false, err = "Fingerprint of key could not be determined")
- } else {
- if (gpgKeysInstalled(fingerprint) && skipIfExistin) {
- ProvResult(true, out = "Keys were already installed")
- } else {
- val pubkeyFile = "~/pub-key.asc"
- val privkeyFile = "~/priv-key.asc"
-
- createSecretFile(pubkeyFile, gpgKeys.publicKey)
- createSecretFile(privkeyFile, gpgKeys.privateKey)
-
- cmd("gpg --import $pubkeyFile")
-
- // using option --batch for older keys; see https://superuser.com/questions/1135812/gpg2-asking-for-passphrase-when-importing-secret-keys
- cmd("gpg --batch --import $privkeyFile")
-
- if (trust) {
- cmd("printf \"5\\ny\\n\" | gpg --no-tty --command-fd 0 --expert --edit-key $fingerprint trust")
- }
-
- cmd("shred $pubkeyFile")
- cmd("shred $privkeyFile")
-
- configureGPGAgent()
- }
- }
-}
-
-
-private fun Prov.configureGPGAgent() = def {
- if (dirExists(".gnupg")) {
- createDir(".gnupg", "~/")
- }
- val content = """
- allow-preset-passphrase
- allow-loopback-pinentry
- """.trimIndent()
- createFile("~/.gnupg/gpg-agent.conf", content)
-}
-
-
-private fun Prov.gpgKeysInstalled(fingerprint: String): Boolean {
- return cmdNoLog("gpg --list-keys $fingerprint").success
-}
-
-
-fun Prov.gpgFingerprint(pubKey: String): String? {
- val result =
- cmdNoLog(" " + printToShell(pubKey) + " | gpg --with-colons --import-options show-only --import --fingerprint")
- return result.out?.let { """^fpr:*([A-Z0-9]*):$""".toRegex(RegexOption.MULTILINE).find(it)?.groupValues?.get(1) }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/base/Ssh.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/base/Ssh.kt
deleted file mode 100644
index ac84160..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/keys/base/Ssh.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.keys.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDir
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createSecretFile
-import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
-
-
-/**
- * installs ssh keys for active user
- */
-fun Prov.configureSshKeys(sshKeys: KeyPair) = def {
- createDir(".ssh", "~/")
- createSecretFile("~/.ssh/id_rsa.pub", sshKeys.publicKey, "644")
- createSecretFile("~/.ssh/id_rsa", sshKeys.privateKey, "600")
- configureSSHClient()
-}
-
-fun Prov.configureSSHClient() = def {
- // TODO("Not yet implemented")
- ProvResult(true)
-}
-
-
-/**
- * Specifies a host or Ip to be trusted
- *
- * ATTENTION:
- * This method is NOT secure as a man-in-the-middle could compromise the connection.
- * Don't use this for critical systems resp. environments
- */
-fun Prov.trustServer(hostOrIp: String) = def {
- cmd("ssh-keyscan $hostOrIp >> ~/.ssh/known_hosts")
-}
-
-
-/**
- * Checks if the specified hostname or Ip is in a known_hosts file
- *
- * @return whether if was found
- */
-fun Prov.isHostKnown(hostOrIp: String) : Boolean {
- return cmdNoEval("ssh-keygen -F $hostOrIp").out?.isNotEmpty() ?: false
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/SecretSource.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/SecretSource.kt
deleted file mode 100644
index 438cf4e..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/SecretSource.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.secret
-
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.*
-import kotlinx.serialization.Serializable
-
-
-@Serializable
-abstract class SecretSource(protected val input: String) {
- abstract fun secret() : Secret
- abstract fun secretNullable() : Secret?
-}
-
-
-@Serializable
-enum class SecretSourceType() {
-
- PLAIN, FILE, PROMPT, PASS, GOPASS;
-
- fun secret(input: String) : Secret {
- return when (this) {
- PLAIN -> PlainSecretSource(input).secret()
- FILE -> FileSecretSource(input).secret()
- PROMPT -> PromptSecretSource().secret()
- PASS -> PassSecretSource(input).secret()
- GOPASS -> GopassSecretSource(input).secret()
- }
- }
-}
-
-
-@Serializable
-@Suppress("unused") // for use in other projects
-class SecretSupplier(private val source: SecretSourceType, val parameter: String) {
- fun secret(): Secret {
- return source.secret(parameter)
- }
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/FileSecretSource.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/FileSecretSource.kt
deleted file mode 100644
index be188d6..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/FileSecretSource.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSource
-
-
-/**
- * Retrieve secret from a file
- */
-class FileSecretSource(fqFileName: String) : SecretSource(fqFileName) {
-
- override fun secret(): Secret {
- val p = Prov.newInstance(name = "FileSecretSource")
- return p.getSecret("cat " + input) ?: throw Exception("Failed to get secret.")
- }
-
- override fun secretNullable(): Secret? {
- val p = Prov.newInstance(name = "FileSecretSource")
- return p.getSecret("cat " + input)
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/GopassSecretSource.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/GopassSecretSource.kt
deleted file mode 100644
index e05fb52..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/GopassSecretSource.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSource
-
-
-/**
- * Retrieve secret from gopass
- */
-class GopassSecretSource(path: String) : SecretSource(path) {
- override fun secret(): Secret {
- return secretNullable() ?: throw Exception("Failed to get \"$input\" secret from gopass.")
- }
- override fun secretNullable(): Secret? {
- val p = Prov.newInstance(name = "GopassSecretSource for $input")
- return p.getSecret("gopass show -f " + input)
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PassSecretSource.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PassSecretSource.kt
deleted file mode 100644
index ac537de..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PassSecretSource.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSource
-
-
-/**
- * Retrieve secret from passwordstore on Unix
- */
-class PassSecretSource(path: String) : SecretSource(path) {
- override fun secret(): Secret {
- val p = Prov.newInstance(name = "PassSecretSource")
- return p.getSecret("pass " + input) ?: throw Exception("Failed to get secret.")
- }
- override fun secretNullable(): Secret? {
- val p = Prov.newInstance(name = "PassSecretSource")
- return p.getSecret("pass " + input)
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PlainSecretSource.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PlainSecretSource.kt
deleted file mode 100644
index cf6f795..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PlainSecretSource.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources
-
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSource
-
-
-class PlainSecretSource(plainSecret: String) : SecretSource(plainSecret) {
- override fun secret(): Secret {
- return Secret(input)
- }
- override fun secretNullable(): Secret {
- return Secret(input)
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PromptSecretSource.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PromptSecretSource.kt
deleted file mode 100644
index a2ab4cd..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PromptSecretSource.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources
-
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSource
-import java.awt.FlowLayout
-import javax.swing.*
-
-
-class PasswordPanel : JPanel(FlowLayout()) {
-
- private val passwordField = JPasswordField(20)
- private var entered = false
-
- val enteredPassword
- get() = if (entered) String(passwordField.password) else null
-
- init {
- add(JLabel("Password: "))
- add(passwordField)
- passwordField.setActionCommand("OK")
- passwordField.addActionListener {
- if (it.actionCommand == "OK") {
- entered = true
-
- SwingUtilities.getWindowAncestor(it.source as JComponent)
- .dispose()
- }
- }
- }
-
- private fun request(passwordIdentifier: String) = apply {
- JOptionPane.showOptionDialog(null, this@PasswordPanel,
- "Enter $passwordIdentifier",
- JOptionPane.DEFAULT_OPTION,
- JOptionPane.INFORMATION_MESSAGE,
- null, emptyArray(), null)
- }
-
- companion object {
-
- fun requestPassword(passwordIdentifier: String) = PasswordPanel()
- .request(passwordIdentifier)
- .enteredPassword
- }
-}
-
-class PromptSecretSource(text: String = "Secret/Password") : SecretSource(text) {
-
- override fun secret(): Secret {
- val password = PasswordPanel.requestPassword(input)
- if (password == null) {
- throw IllegalArgumentException("Failed to retrieve secret from prompting.")
- } else {
- return Secret(password)
- }
- }
-
- override fun secretNullable(): Secret? {
- val password = PasswordPanel.requestPassword(input)
-
- return if(password == null) {
- null
- }else {
- Secret(password)
- }
- }
-}
\ No newline at end of file
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/user/UserConfig.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/user/UserConfig.kt
deleted file mode 100644
index 746dc46..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/user/UserConfig.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.user
-
-import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPairSource
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.json.Json
-import java.io.BufferedReader
-import java.io.FileReader
-import java.io.FileWriter
-
-
-@Serializable
-class UserConfig(val userName: String, val gitEmail: String? = null, val gpg: KeyPairSource? = null, val ssh: KeyPairSource? = null)
-
-
-// -------------------------------------------- file methods ------------------------------------
-@Suppress("unused")
-fun readUserConfigFromFile(filename: String = "UserConfig.json") : UserConfig {
- // read from file
- val inputAsString = BufferedReader(FileReader(filename)).use { it.readText() }
-
- // serializing objects
- return Json.decodeFromString(UserConfig.serializer(), inputAsString)
-}
-
-fun writeUserConfigToFile(config: UserConfig) {
- val fileName = "UserConfig.json"
-
- FileWriter(fileName).use { it.write(Json.encodeToString(UserConfig.serializer(), config)) }
-}
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/user/base/User.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/user/base/User.kt
deleted file mode 100644
index 4d80dc3..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/user/base/User.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.user.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.core.processors.RemoteProcessor
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileExists
-import org.domaindrivenarchitecture.provs.ubuntu.git.provisionGit
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.gpgFingerprint
-import org.domaindrivenarchitecture.provs.ubuntu.keys.provisionKeysCurrentUser
-import org.domaindrivenarchitecture.provs.ubuntu.user.UserConfig
-import java.net.InetAddress
-
-
-fun Prov.userExists(userName: String): Boolean {
- return cmdNoEval("grep -c '^$userName:' /etc/passwd").success
-}
-
-
-/**
- * Creates a new user.
- */
-fun Prov.createUser(
- userName: String,
- password: Secret? = null,
- sudo: Boolean = false,
- copyAuthorizedKeysFromCurrentUser: Boolean = false
-): ProvResult = requireAll {
- if (!userExists(userName)) {
- cmd("sudo adduser --gecos \"First Last,RoomNumber,WorkPhone,HomePhone\" --disabled-password --home /home/$userName $userName")
- }
- password?.let { cmdNoLog("sudo echo \"$userName:${password.plain()}\" | sudo chpasswd") } ?: ProvResult(true)
- if (sudo) {
- makeUserSudoerWithNoSudoPasswordRequired(userName)
- }
- val authorizedKeysFile = "~/.ssh/authorized_keys"
- if (copyAuthorizedKeysFromCurrentUser && fileExists(authorizedKeysFile)) {
- createDirs("/home/$userName/.ssh")
- val newAuthorizedKeysFile = "/home/$userName/.ssh/authorized_keys"
- cmd("sudo cp $authorizedKeysFile $newAuthorizedKeysFile")
- cmd("chown $userName $newAuthorizedKeysFile")
-
- }
- ProvResult(true) // dummy
-}
-
-
-/**
- * Configures gpg and ssh keys for the current if keys are provided in the config.
- * Installs and configures git for the user if gitEmail is provided in the config.
- * Does NOT CREATE the user.
- */
-fun Prov.configureUser(config: UserConfig) = requireAll {
- provisionKeysCurrentUser(
- config.gpg?.keyPair(),
- config.ssh?.keyPair()
- )
-
- config.gitEmail?.run {
- provisionGit(
- config.userName,
- config.gitEmail,
- config.gpg?.keyPair()?.let { gpgFingerprint(it.publicKey.plain()) })
- } ?: ProvResult(true)
-}
-
-
-@Suppress("unused")
-// todo create test
-fun Prov.deleteUser(userName: String, deleteHomeDir: Boolean = false): ProvResult = requireAll {
- val flagToDeleteHomeDir = if (deleteHomeDir) " -r " else ""
- if (userExists(userName)) {
- cmd("sudo userdel $flagToDeleteHomeDir $userName")
- } else {
- ProvResult(false, err = "User $userName cannot be deleted as it does not exist.")
- }
-}
-
-
-/**
- * Makes userName a sudoer who does not need a password to sudo.
- * The current (executing) user must already be a sudoer. If he is a sudoer with password required then
- * his password must be provided.
- */
-fun Prov.makeUserSudoerWithNoSudoPasswordRequired(
- userName: String,
- password: Secret? = null,
- overwriteFile: Boolean = false
-): ProvResult = def {
- val userSudoFile = "/etc/sudoers.d/$userName"
- if (!fileExists(userSudoFile) || overwriteFile) {
- val sudoPrefix = if (password == null) "sudo" else "echo ${password.plain()} | sudo -S"
- // see https://stackoverflow.com/questions/323957/how-do-i-edit-etc-sudoers-from-a-script
- val result = cmdNoLog(sudoPrefix + " sh -c \"echo '$userName ALL=(ALL) NOPASSWD:ALL' | (sudo su -c 'EDITOR=\"tee\" visudo -f " + userSudoFile + "')\"")
- // don't log the command (containing the password) resp. don't include it in the ProvResult, just include success and err
- ProvResult(result.success, err = result.err)
- } else {
- ProvResult(true, out = "File already exists")
- }
-}
-
-
-/**
- * Makes the current (executing) user be able to sudo without password.
- * IMPORTANT: Current user must already by sudoer when calling this function.
- */
-@Suppress("unused") // used externally
-fun Prov.makeUserSudoerWithNoSudoPasswordRequired(password: Secret) = def {
- val currentUser = whoami()
- if (currentUser != null) {
- makeUserSudoerWithNoSudoPasswordRequired(currentUser, password, overwriteFile = true)
- } else {
- ProvResult(false, "Current user could not be determined.")
- }
-}
-
-
-/**
- * Checks if user is in group sudo.
- */
-@Suppress("unused")
-fun Prov.userIsInGroupSudo(userName: String): Boolean {
- return cmd("getent group sudo | grep -c '$userName'").success
-}
-
-
-/**
- * Checks if current user can execute sudo commands.
- */
-@Suppress("unused")
-fun Prov.currentUserCanSudo(): Boolean {
- return cmd("timeout 1 sudo id").success
-}
-
-
-/**
- * Returns username of current user if it can be determined
- */
-fun Prov.whoami(): String? {
- return cmd("whoami").run { if (success) out?.trim() else null }
-}
-
-
-/**
- * Creates a new user on the specified host.
- *
- * @host hostname or ip-address
- * @hostUser user on the remote system, which is used to create the new user,
- * hostUser must be sudoer
- * @hostPassword pw of hostUser on the remote system;
- * ssh-key authentication will be used if hostPassword is null
- */
-@Suppress("api") // use externally
-fun createRemoteUser(
- host: InetAddress,
- hostUser: String,
- hostPassword: Secret?,
- newUserName: String,
- newUserPW: Secret,
- makeNewUserSudoer: Boolean = false
-) {
- Prov.newInstance(RemoteProcessor(host, hostUser, hostPassword), name = "createRemoteUser")
- .createUser(newUserName, newUserPW, makeNewUserSudoer)
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/utils/Utils.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/utils/Utils.kt
deleted file mode 100644
index bad65f7..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/utils/Utils.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.utils
-
-import org.domaindrivenarchitecture.provs.core.escapeBackslash
-import org.domaindrivenarchitecture.provs.core.escapeDoubleQuote
-
-
-// todo: investigate to use .escapeAndEncloseByDoubleQuoteForShell() or similar instead (?)
-internal fun printToShell(text: String): String {
- return "echo -n \"${text.escapeBackslash().escapeDoubleQuote()}\""
-}
-
diff --git a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/web/base/Web.kt b/bin/main/org/domaindrivenarchitecture/provs/ubuntu/web/base/Web.kt
deleted file mode 100644
index 5336d9d..0000000
--- a/bin/main/org/domaindrivenarchitecture/provs/ubuntu/web/base/Web.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.web.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.isPackageInstalled
-
-
-/**
- * Downloads a file from the given URL using curl
- *
- * @param path where to download to
- * @param url file to download
- * @param filename filename after download
- */
-@Suppress("unused") // used externally
-fun Prov.downloadFromURL(url: String, filename: String? = null, path: String? = null, sudo: Boolean = false) : ProvResult = def {
-
- if (!isPackageInstalled("curl")) aptInstall("curl")
-
- if (filename == null) {
- cmd("curl $url", path, sudo)
- } else {
- cmd("curl $url -o $filename", path, sudo)
- }
-}
\ No newline at end of file
diff --git a/bin/test/WorkplaceConfigExample.json b/bin/test/WorkplaceConfigExample.json
deleted file mode 100644
index 5ea87e4..0000000
--- a/bin/test/WorkplaceConfigExample.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "type": "MINIMAL",
- "ssh": null,
- "gpg": null,
- "gitUserName": "mygitusername",
- "gitEmail": "my@git.email"
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/ProvTest.kt b/bin/test/org/domaindrivenarchitecture/provs/core/ProvTest.kt
deleted file mode 100644
index 365cf31..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/ProvTest.kt
+++ /dev/null
@@ -1,478 +0,0 @@
-package org.domaindrivenarchitecture.provs.core
-
-import org.domaindrivenarchitecture.provs.core.docker.provideContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.domaindrivenarchitecture.provs.test.tags.NonCi
-import org.domaindrivenarchitecture.provs.test.testLocal
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-import java.io.ByteArrayOutputStream
-import java.io.PrintStream
-
-
-internal class ProvTest {
-
- private fun Prov.def_returnungFalse() = def {
- ProvResult(false)
- }
-
- private fun Prov.def_returningTrue() = def {
- ProvResult(true)
- }
-
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun cmd_onLinux() {
- // when
- val res = Prov.newInstance(name = "testing").cmd("echo --testing--").success
-
- // then
- assert(res)
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- @ContainerTest
- fun sh_onLinux() {
- // given
- val script = """
- # test some script commands
-
- ping -c1 nu.nl
- echo something
- ping -c1 github.com
- """
-
- // when
- val res = Prov.newInstance(name = "testing").sh(script).success
-
- // then
- assert(res)
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- @ContainerTest
- @NonCi
- fun sh_onLinux_with_dir_and_sudo() {
- // given
- val script = """
- # test some script commands
-
- ping -c1 google.com
- echo something
- ping -c1 github.com
- echo 1 # comment behind command
- """
-
- // when
- val res = Prov.newInstance(name = "provs_test").sh(script, "/root", true).success
-
- // then
- assert(res)
- }
-
-
- @Test
- @EnabledOnOs(OS.WINDOWS)
- fun cmd_onWindows() {
- // when
- val res = Prov.newInstance(name = "testing").cmd("echo --testing--").success
-
- // then
- assert(res)
- }
-
- @Test
- @EnabledOnOs(OS.WINDOWS)
- fun sh_onWindows() {
- // given
- val script = """
- # test some script commands
-
- ping -n 1 nu.nl
- echo something
- ping -n 1 github.com
- """
-
- // when
- val res = Prov.newInstance(name = "testing").sh(script).success
-
- // then
- assert(res)
- }
-
- @Test
- fun def_modeOptional_result_true() {
- // given
- fun Prov.tst_def() = optional {
- def_returnungFalse()
- def_returningTrue()
- def_returnungFalse()
- }
-
- // when
- val res = testLocal().tst_def().success
-
- // then
- assert(res)
- }
-
- @Test
- fun def_modeLast_result_true() {
- // given
- fun Prov.tst_def() = requireLast {
- def_returnungFalse()
- def_returningTrue()
- }
-
- // when
- val res = testLocal().tst_def().success
-
- // then
- assert(res)
- }
-
- @Test
- fun def_modeLast_result_false() {
- // given
- fun Prov.tst_def() = requireLast {
- def_returningTrue()
- def_returnungFalse()
- }
-
- // when
- val res = testLocal().tst_def().success
-
- // then
- assert(!res)
- }
-
- @Test
- fun def_mode_ALL_result_true() {
- // given
- fun Prov.tst_def_all_true_mode_ALL() = requireAll {
- def_returningTrue()
- def_returningTrue()
- }
-
- // when
- val res = testLocal().tst_def_all_true_mode_ALL().success
-
- // then
- assert(res)
- }
-
- // given
- fun Prov.tst_def_one_false_mode_ALL() = requireAll {
- def_returningTrue()
- def_returnungFalse()
- def_returningTrue()
- }
-
- @Test
- fun def_modeALL_resultFalse() {
- // when
- val res = testLocal().tst_def_one_false_mode_ALL().success
-
- // then
- assert(!res)
- }
-
- // given
- fun Prov.tst_def_one_false_mode_ALL_nested() = requireAll {
- def_returningTrue()
- tst_def_one_false_mode_ALL()
- def_returningTrue()
- tst_ALL_returningTrue()
- }
-
- // given
- fun Prov.tst_ALL_returningTrue() = requireAll {
- ProvResult(true)
- }
-
- @Test
- fun def_modeALLnested_resultFalse() {
- // when
- val res = testLocal().tst_def_one_false_mode_ALL_nested().success
-
- // then
- assert(!res)
- }
-
- @Test
- fun def_mode_ALL_LAST_NONE_nested() {
- // given
- fun Prov.tst_def_last() = def {
- def_returningTrue()
- def_returnungFalse()
- }
-
- fun Prov.tst_def_one_false_mode_ALL() = requireAll {
- tst_def_last()
- def_returningTrue()
- }
-
- // when
- val res = testLocal().tst_def_one_false_mode_ALL().success
-
- // then
- assert(!res)
- }
-
- @Test
- fun def_mode_FAILEXIT_nested_false() {
- // given
- fun Prov.tst_def_failexit_inner() = exitOnFailure {
- def_returningTrue()
- def_returnungFalse()
- }
-
- fun Prov.tst_def_failexit_outer() = exitOnFailure {
- tst_def_failexit_inner()
- def_returningTrue()
- }
-
- // when
- val res = testLocal().tst_def_failexit_outer().success
-
- // then
- assert(!res)
- }
-
- @Test
- fun def_mode_FAILEXIT_nested_true() {
- // given
- fun Prov.tst_def_failexit_inner() = exitOnFailure {
- def_returningTrue()
- def_returningTrue()
- }
-
- fun Prov.tst_def_failexit_outer() = exitOnFailure {
- tst_def_failexit_inner()
- def_returningTrue()
- }
-
- // when
- val res = testLocal().tst_def_failexit_outer().success
-
- // then
- assert(res)
- }
-
- @Test
- fun def_mode_multiple_nested() {
- // given
- fun Prov.tst_nested() = def {
- requireAll {
- def_returningTrue()
- def {
- def_returnungFalse()
- def_returningTrue()
- }
- def_returnungFalse()
- def_returningTrue()
- optional {
- def_returnungFalse()
- }
- }
- }
-
- // when
- val res = testLocal().tst_nested().success
-
- // then
- assert(!res)
- }
-
-
- // given
- fun Prov.checkPrereq_evaluateToFailure() = requireLast {
- ProvResult(false, err = "This is a test error.")
- }
-
- fun Prov.methodThatProvidesSomeOutput() = requireLast {
-
- if (!checkPrereq_evaluateToFailure().success) {
- sh(
- """
- echo -Start test-
- echo Some output
- """
- )
- }
-
- sh("echo -End test-")
- }
-
- @Test
- fun runProv_printsCorrectOutput() {
-
- // given
- val outContent = ByteArrayOutputStream()
- val errContent = ByteArrayOutputStream()
- val originalOut = System.out
- val originalErr = System.err
-
- System.setOut(PrintStream(outContent))
- System.setErr(PrintStream(errContent))
-
- // when
- Prov.newInstance(name = "test instance", progressType = ProgressType.NONE).methodThatProvidesSomeOutput()
-
- // then
- System.setOut(originalOut)
- System.setErr(originalErr)
-
- println(outContent.toString())
-
- val expectedOutput = if (OS.WINDOWS.isCurrentOs) "\n" +
- "============================================== SUMMARY (test Instance) ============================================== \n" +
- "> Success -- methodThatProvidesSomeOutput (requireLast) \n" +
- "---> FAILED -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" +
- "---> Success -- sh \n" +
- "------> Success -- cmd [cmd.exe, /c, echo -Start test-]\n" +
- "------> Success -- cmd [cmd.exe, /c, echo Some output]\n" +
- "---> Success -- sh \n" +
- "------> Success -- cmd [cmd.exe, /c, echo -End test-]\n" +
- "============================================ SUMMARY END ============================================ \n"
- else if (OS.LINUX.isCurrentOs()) {
- "============================================== SUMMARY (test instance) ============================================== \n" +
- "> \u001B[92mSuccess\u001B[0m -- methodThatProvidesSomeOutput (requireLast) \n" +
- "---> \u001B[91mFAILED\u001B[0m -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" +
- "---> \u001B[92mSuccess\u001B[0m -- sh \n" +
- "------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -Start test-]\n" +
- "------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo Some output]\n" +
- "---> \u001B[92mSuccess\u001B[0m -- sh \n" +
- "------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -End test-]\n" +
- "----------------------------------------------------------------------------------------------------- \n" +
- "Overall > \u001B[92mSuccess\u001B[0m\n" +
- "============================================ SUMMARY END ============================================ \n" +
- "\n"
- } else {
- "OS " + System.getProperty("os.name") + " not yet supported"
- }
-
- assertEquals(expectedOutput, outContent.toString().replace("\r", ""))
- }
-
- @Test
- fun check_returnsTrue() {
- // when
- val res = testLocal().chk("echo 123")
-
- // then
- assertTrue(res)
- }
-
- @Test
- fun check_returnsFalse() {
- // when
- val res = testLocal().chk("cmddoesnotexist")
-
- // then
- assertFalse(res)
- }
-
- @Test
- fun getSecret_returnsSecret() {
- // when
- val res = testLocal().getSecret("echo 123")
-
- // then
- assertEquals("123", res?.plain()?.trim())
- }
-
- @Test
- fun addResultToEval_success() {
- // given
- fun Prov.inner() {
- addResultToEval(ProvResult(true))
- }
-
- fun Prov.outer() = requireAll {
- inner()
- ProvResult(true)
- }
-
- // when
- val res = testLocal().outer()
-
- //then
- assertEquals(ProvResult(true), res)
- }
-
- @Test
- fun addResultToEval_failure() {
- // given
- fun Prov.inner() {
- addResultToEval(ProvResult(false))
- }
-
- fun Prov.outer() = requireAll {
- inner()
- ProvResult(true)
- }
-
- // when
- val res = testLocal().outer()
-
- //then
- assertEquals(ProvResult(false), res)
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- @NonCi
- fun inContainer_locally() {
- // given
- val containerName = "provs_test"
- testLocal().provideContainer(containerName, "ubuntu")
-
- fun Prov.inner() = def {
- cmd("echo in container")
- }
-
- // then
- fun Prov.outer() = def {
- inContainer(containerName) {
- inner()
- cmd("echo testfile > testfile.txt")
- }
- }
-
- val res = testLocal().def { outer() }
-
- // then
- assertEquals(true, res.success)
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- @Disabled // run manually after updating host and remoteUser
- fun inContainer_remotely() {
- // given
- val host = "192.168.56.135"
- val remoteUser = "az"
-
- fun Prov.inner() = def {
- cmd("echo 'in testfile' > testfile.txt")
- }
-
- // then
- val res = remote(host, remoteUser).def {
- inner() // executed on the remote host
- inContainer("prov_default") {
- inner() // executed in the container on the remote host
- }
- }
-
- // then
- assertEquals(true, res.success)
- }
-}
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/UtilsKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/core/UtilsKtTest.kt
deleted file mode 100644
index a0f7865..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/UtilsKtTest.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.domaindrivenarchitecture.provs.core
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-import java.net.UnknownHostException
-
-internal class UtilsKtTest {
-
- @Test
- fun test_getCallingMethodName() {
- // when
- val s = getCallingMethodName()
-
- // then
- assertEquals("test_getCallingMethodName", s)
- }
-
- @Test
- @ContainerTest
- fun runCmdInContainer() {
- // when
- val res = defaultTestContainer().cmd("echo something")
-
- // then
- assertTrue(res.success)
- }
-
- @Test
- fun remote_emptyHost() {
- assertThrows(IllegalArgumentException::class.java,
- { remote("", "user") })
- }
-
- @Test
- fun remote_invalidHost() {
- assertThrows(
- UnknownHostException::class.java,
- { remote("invalid_host", "user") })
- }
-
- @Test
- @Disabled // run manually after having updated user
- fun test_remote() {
- assertTrue(remote("127.0.0.1", "user").cmd("echo sth").success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/docker/platforms/UbuntuHostDockerKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/core/docker/platforms/UbuntuHostDockerKtTest.kt
deleted file mode 100644
index c5bb42b..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/docker/platforms/UbuntuHostDockerKtTest.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.docker.platforms
-
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.docker.containerRuns
-import org.domaindrivenarchitecture.provs.core.docker.exitAndRmContainer
-import org.domaindrivenarchitecture.provs.core.docker.runContainer
-import org.domaindrivenarchitecture.provs.test.tags.NonCi
-import org.domaindrivenarchitecture.provs.test.testLocal
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-
-internal class UbuntuHostDockerKtTest {
-
- @Test
- @EnabledOnOs(OS.LINUX)
- @NonCi
- fun runAndCheckAndExitContainer() {
- // when
- val containerName = "testContainer"
- val result = testLocal().requireAll {
- runContainer(containerName)
- addResultToEval(ProvResult(containerRuns(containerName)))
-
- exitAndRmContainer(containerName)
- }
-
- // then
- assertEquals(ProvResult(true), result)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/entry/EntryTest.kt b/bin/test/org/domaindrivenarchitecture/provs/core/entry/EntryTest.kt
deleted file mode 100644
index fca7e30..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/entry/EntryTest.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.entry
-
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import java.io.ByteArrayOutputStream
-import java.io.PrintStream
-
-
-@Suppress("unused")
-fun testfun(args: Array) {
- println("test is fun " + args.joinToString(" "))
-}
-
-@Suppress("unused")
-fun main(args: Array) {
- println("main is fun " + args.joinToString(" "))
-}
-
-
-internal class EntryKtTest {
-
- private var outContent = ByteArrayOutputStream()
- private var originalOut = System.out
-
- @BeforeEach
- fun redirectSystemOutStream() {
- originalOut = System.out
-
- // given
- outContent = ByteArrayOutputStream()
- System.setOut(PrintStream(outContent))
- }
-
- @AfterEach
- fun restoreSystemOutStream() {
- System.setOut(originalOut)
- }
-
- @Test
- fun test_without_method_argument() {
- // when
- main("org.domaindrivenarchitecture.provs.core.entry.EntryTestKt")
-
- // then
- assertEquals("main is fun \n", outContent.toString())
- }
-
- @Test
- fun test_method_main_without_args() {
- // when
- main("org.domaindrivenarchitecture.provs.core.entry.EntryTestKt", "main")
-
- // then
- assertEquals("main is fun \n", outContent.toString())
- }
-
- @Test
- fun test_named_method_without_args() {
- // when
- main("org.domaindrivenarchitecture.provs.core.entry.EntryTestKt", "testfun")
-
- // then
- assertEquals("test is fun \n", outContent.toString())
- }
-
- @Test
- fun test_method_main_with_args() {
- // when
- main("org.domaindrivenarchitecture.provs.core.entry.EntryTestKt", "main", "arg1", "arg2")
-
- // then
- assertEquals("main is fun arg1 arg2\n", outContent.toString())
- }
-
- @Test
- fun test_named_method_with_args() {
- // when
- main("org.domaindrivenarchitecture.provs.core.entry.EntryTestKt", "testfun", "arg1", "arg2")
-
- // then
- assertEquals("test is fun arg1 arg2\n", outContent.toString())
- }
-}
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/platformTest/UbuntuProvTests.kt b/bin/test/org/domaindrivenarchitecture/provs/core/platformTest/UbuntuProvTests.kt
deleted file mode 100644
index b7f5bf0..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/platformTest/UbuntuProvTests.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.platformTest
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.test.tags.NonCi
-import org.domaindrivenarchitecture.provs.test.testLocal
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-
-internal class UbuntuProvTests {
-
- private fun Prov.ping(url: String) = def {
- xec("ping", "-c", "4", url)
- }
-
- private fun Prov.outerPing() = def {
- ping("gitlab.com")
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun that_ping_works() {
- // when
- val res = testLocal().outerPing()
-
- // then
- assert(res.success)
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun that_cmd_works() {
- // given
- val a = testLocal()
-
- // when
- val res1 = a.cmd("pwd")
- val dir = res1.out?.trim()
- val res2 = a.cmd("echo abc", dir)
-
- // then
- assert(res1.success)
- assert(res2.success)
- assert(res2.out?.trim() == "abc")
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- @NonCi
- fun that_cmd_works_with_sudo() {
- // given
- val a = testLocal()
-
- // when
- val res1 = a.cmd("echo abc", "/root", sudo = true)
-
- // then
- assert(res1.success)
- assert(res1.out?.trim() == "abc")
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun that_nested_shells_work() {
- // given
- val a = testLocal()
-
- // when
- val res1 = a.cmd("pwd")
- val dir = res1.out?.trim()
- val res2 = a.cmd("echo abc", dir)
-
- // then
- assert(res1.success)
- assert(res2.success)
- assert(res2.out?.trim() == "abc")
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun that_xec_works() {
- // given
- val a = testLocal()
-
- // when
- val res1 = a.xec("/usr/bin/printf", "hi")
- val res2 = a.xec("/bin/ping", "-c", "2", "gitlab.com")
- val res3 = a.xec("/bin/bash", "-c", "echo echoed")
-
- // then
- assert(res1.success)
- assert(res1.out?.trim() == "hi")
- assert(res2.success)
- assert(res3.success)
- assert(res3.out?.trim() == "echoed")
- }
-
-}
-
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/platformTest/WinProvTests.kt b/bin/test/org/domaindrivenarchitecture/provs/core/platformTest/WinProvTests.kt
deleted file mode 100644
index 9ed2d6d..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/platformTest/WinProvTests.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.platformTest
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.test.testLocal
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-
-internal class WinProvTests {
-
- private fun Prov.ping(url: String) = def {
- cmd("ping $url")
- }
-
- private fun Prov.outerPing() = def { ping("nu.nl") }
-
- @Test
- @EnabledOnOs(OS.WINDOWS)
- fun def_definesPing_function() {
- // when
- val res = testLocal().outerPing()
-
- // then
- assert(res.success)
- }
-
- @Test
- @EnabledOnOs(OS.WINDOWS)
- fun cmd_executesCommand() {
- // given
- val a = testLocal()
-
- // when
- val res1 = a.cmd("echo %cd%")
- val dir = res1.out?.trim()
- val res2 = a.cmd("echo abc", dir)
-
- // then
- assert(res1.success)
- assert(res1.success)
- assertEquals( "abc", res2.out?.trim())
- }
-}
-
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/processors/ContainerProcessorTest.kt b/bin/test/org/domaindrivenarchitecture/provs/core/processors/ContainerProcessorTest.kt
deleted file mode 100644
index 26fd034..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/processors/ContainerProcessorTest.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-import org.domaindrivenarchitecture.provs.core.newline
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-
-@EnabledOnOs(OS.LINUX)
-internal class ContainerProcessorTest {
-
- @Test
- @ContainerTest
- fun cmd_works_with_echo() {
-
- // given
- val prov = defaultTestContainer()
- val text = "abc123!§$%&/#äöü"
-
- // when
- val res = prov.cmd("echo '${text}'")
-
- // then
- assert(res.success)
- assertEquals(text + newline(), res.out)
- }
-
-
- @Test
- @ContainerTest
- fun cmdNoLog_works_with_echo() {
- // given
- val prov = defaultTestContainer()
- val text = "abc123!§$%&/#äöü"
-
- // when
- val res = prov.cmdNoLog("echo '${text}'")
-
- // then
- assert(res.success)
- assertEquals(text + newline(), res.out)
-
- // todo add check that cmd was not logged
- }
-}
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/processors/ContainerUbuntuHostProcessorTest.kt b/bin/test/org/domaindrivenarchitecture/provs/core/processors/ContainerUbuntuHostProcessorTest.kt
deleted file mode 100644
index b055d63..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/processors/ContainerUbuntuHostProcessorTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-import org.domaindrivenarchitecture.provs.core.platforms.SHELL
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.domaindrivenarchitecture.provs.test.testDockerWithSudo
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS.LINUX
-
-val DEFAULT_START_MODE_TEST_CONTAINER = ContainerStartMode.USE_RUNNING_ELSE_CREATE
-
-class ContainerUbuntuHostProcessorTest {
-
- @Test
- @EnabledOnOs(LINUX)
- @ContainerTest
- fun test_execution() {
- // given
- val processor =
- ContainerUbuntuHostProcessor("provs_ubuntuhost_test", "ubuntu", DEFAULT_START_MODE_TEST_CONTAINER, sudo = testDockerWithSudo)
-
- // when
- val res = processor.x(SHELL, "-c", "echo -n abc")
-
- // then
- assertEquals(0, res.exitCode)
- assertEquals("abc", res.out)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/core/processors/LocalProcessorTest.kt b/bin/test/org/domaindrivenarchitecture/provs/core/processors/LocalProcessorTest.kt
deleted file mode 100644
index f6e6dc5..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/core/processors/LocalProcessorTest.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.domaindrivenarchitecture.provs.core.processors
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.escapeAndEncloseByDoubleQuoteForShell
-import org.domaindrivenarchitecture.provs.core.escapeProcentForPrintf
-import org.domaindrivenarchitecture.provs.core.escapeSingleQuoteForShell
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-
-
-internal class LocalProcessorTest {
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun cmd_with_printf_on_Linux() {
- // given
- val prov = Prov.newInstance()
- val text = "abc123!§\\\$%%&/\"\\äöü'"
-
- // when
- val res = prov.cmd("printf '${text.replace("%", "%%").escapeSingleQuoteForShell()}'")
-
- // then
- assert(res.success)
- assert(res.out == text)
- }
-
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun cmd_with_nested_shell_and_printf_on_Linux() {
- // given
- val prov = Prov.newInstance()
- val text = "abc123!§\\$%%&/\"\\äöü'"
-
- // when
- val res = prov.cmd("sh -c " + ("sh -c " + ("printf ${text.escapeProcentForPrintf().escapeAndEncloseByDoubleQuoteForShell()}").escapeAndEncloseByDoubleQuoteForShell()).escapeAndEncloseByDoubleQuoteForShell())
-
- // then
- assertTrue(res.success)
- assertEquals(text, res.out)
- }
-
-
- @Test
- @EnabledOnOs(OS.WINDOWS)
- fun cmd_with_echo_on_Windows() {
- // given
- val prov = Prov.newInstance()
- val text = "abc123!\"#"
-
- // when
- val res = prov.cmd("echo $text")
-
- // then
- assert(res.success)
- assertEquals( text + "\r\n", res.out)
- }
-
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun cmdNoLog_linux() {
- // given
- val prov = Prov.newInstance()
- val text = "abc123!#"
- val osSpecificText = if (OS.WINDOWS.isCurrentOs) text else "'$text'"
-
-
- // when
- val res = prov.cmdNoLog("echo $osSpecificText")
-
- // then
- assert(res.success)
- assertEquals( text + System.lineSeparator(), res.out)
-
- // todo add check that cmd was not logged
- }
-
-
- @Test
- fun cmd_forUnkownCommand_resultWithError() {
- // given
- val prov = Prov.newInstance()
-
- // when
- val res = prov.cmd("iamanunknowncmd")
-
- // then
- assert(!res.success)
- assert(res.out.isNullOrEmpty())
- assert(!res.err.isNullOrEmpty())
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/ProvisionFirewallKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/ProvisionFirewallKtTest.kt
deleted file mode 100644
index 8014d3f..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/firewall/ProvisionFirewallKtTest.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.firewall
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.docker.dockerProvideImage
-import org.domaindrivenarchitecture.provs.core.docker.dockerimages.UbuntuPlusUser
-import org.domaindrivenarchitecture.provs.core.docker.exitAndRmContainer
-import org.domaindrivenarchitecture.provs.core.local
-import org.domaindrivenarchitecture.provs.core.processors.ContainerEndMode
-import org.domaindrivenarchitecture.provs.core.processors.ContainerStartMode
-import org.domaindrivenarchitecture.provs.core.processors.ContainerUbuntuHostProcessor
-import org.domaindrivenarchitecture.provs.test.tags.NonCi
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-
-
-internal class ProvisionFirewallKtTest {
-
- @Test
- @NonCi
- fun configureFirewall() {
- // given
- val dockerImage = UbuntuPlusUser()
- local().dockerProvideImage(dockerImage)
- val containerName = "firewall_test"
- local().exitAndRmContainer(containerName)
- local().cmd("sudo docker run --cap-add=NET_ADMIN -dit --name $containerName ${dockerImage.imageName()}")
- val a = Prov.newInstance(
- ContainerUbuntuHostProcessor(
- containerName,
- dockerImage.imageName(),
- ContainerStartMode.USE_RUNNING_ELSE_CREATE, // already started in previous statement
- ContainerEndMode.EXIT_AND_REMOVE
- ))
-
- // when
- val res = a.requireAll {
- aptInstall("iptables")
- provisionFirewall()
- }
- local().exitAndRmContainer(containerName)
-
- // then
- assertTrue(res.success)
- }
-}
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexusKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexusKtTest.kt
deleted file mode 100644
index 797f472..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexusKtTest.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package nexus
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.extensions.server_software.nexus.provisionNexusWithDocker
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-
-internal class ProvisionNexusKtTest {
-
- @Test
- @Disabled("Find out how to run docker in docker")
- fun provisionNexusWithDocker() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.requireAll {
- provisionNexusWithDocker()
- }
-
- // then
- assertTrue(res.success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/ProvisionNginxKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/ProvisionNginxKtTest.kt
deleted file mode 100644
index a020a35..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/ProvisionNginxKtTest.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nginx
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.NonCi
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.replaceTextInFile
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base.*
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileExists
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-
-
-internal class ProvisionNginxKtTest {
-
- @Test
- @NonCi
- fun provisionNginxStandAlone_customConfig() {
- // given
- val a = defaultTestContainer()
- val config = """
- events {} # event context have to be defined to consider config valid
-
- http {
- server {
- listen 80;
- server_name localhost;
-
- return 200 "Hello";
- }
- }
- """.trimIndent()
- a.aptInstall("curl")
-
- // when
- val res = a.requireAll {
- provisionNginxStandAlone(NginxConf(config))
- cmd("curl localhost")
- }
-
- // then
- assertTrue(res.success)
- }
-
- @Test
- @NonCi
- fun provisionNginxStandAlone_defaultConfig() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.requireAll {
- provisionNginxStandAlone()
- }
-
- // then
- assertTrue(res.success)
- }
-
- @Test
- @NonCi
- fun provisionNginxStandAlone_sslConfig() {
- // given
- val a = defaultTestContainer()
- a.def {
- val file = "/etc/ssl/openssl.cnf"
- if (fileExists(file)) {
- replaceTextInFile(file, "RANDFILE", "#RANDFILE")
- }
- aptInstall("openssl")
- }
-
- // when
- val res = a.def {
- nginxCreateSelfSignedCertificate()
-
- provisionNginxStandAlone(
- NginxConf.nginxReverseProxySslConfig(
- "localhost",
- dirSslCert + "/" + certificateName + ".crt",
- dirSslKey + "/" + certificateName + ".key"
- )
- )
- }
-
- // then
- assertTrue(res.success)
- }
-}
-
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/LocationsKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/LocationsKtTest.kt
deleted file mode 100644
index e1e1a24..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/server_software/nginx/base/LocationsKtTest.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.server_software.nginx.base
-
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileContainsText
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.configFile
-import org.domaindrivenarchitecture.provs.extensions.server_software.nginx.provisionNginxStandAlone
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.NonCi
-
-internal class LocationsKtTest {
-
- @Test
- @NonCi
- fun nginxIncludeLocationFolders() {
- // given
- val a = defaultTestContainer()
- a.provisionNginxStandAlone()
- a.createFile(configFile, NGINX_MINIMAL_CONF, sudo = true)
-
- // when
- val res = a.nginxIncludeLocationFolders()
-
- // then
- assertTrue(res.success)
- assertTrue(a.fileContainsText(
- configFile, """listen 80;
- include /etc/nginx/locations-enabled/port80*.conf
- include /etc/nginx/locations-enabled/port443*.conf"""))
- // just 1 occurrence
- assertEquals("1", a.cmd("grep -o 'listen 80;' $configFile | wc -l").out?.trim())
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/test_keys/TestKeys.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/test_keys/TestKeys.kt
deleted file mode 100644
index 8e66bcb..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/test_keys/TestKeys.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.test_keys
-
-
-fun publicGPGSnakeoilKey(): String {
- return """-----BEGIN PGP PUBLIC KEY BLOCK-----
-
-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
-KpkCQg==
-=cS1b
------END PGP PUBLIC KEY BLOCK----- """
-}
-
-fun privateGPGSnakeoilKey(): String {
- return """-----BEGIN PGP PRIVATE KEY BLOCK-----
-
-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
-i+XV3Dazj3nq/DxUB0neLU/r1afAEiqZAkI=
-=h5SJ
------END PGP PRIVATE KEY BLOCK-----""".trimIndent()
-}
-
-fun publicSSHSnakeoilKey(): String {
- return """ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOtQOq8a/Z7SdZVPrh+Icaq5rr+Qg1TZP4IPuRoFgfujUztQ2dy5DfTEbabJ0qHyo+PKwBDQorVohrW7CwvCEVQQh2NLuGgnukBN2ut5Lam7a/fZBoMjAyTvD4bXyEsUr/Bl5CLoBDkKM0elUxsc19ndzSofnDWeGyQjJIWlkNkVk/ybErAnIHVE+D+g3UxwA+emd7BF72RPqdVN39Eu4ntnxYzX0eepc8rkpFolVn6+Ai4CYHE4FaJ7bJ9WGPbwLuDl0pw/Cp3ps17cB+JlQfJ2spOq0tTVk+GcdGnt+mq0WaOnvVeQsGJ2O1HpY3VqQd1AsC2UOyHhAQ00pw7Pi9 snake@oil.com"""
-}
-
-fun privateSSHSnakeoilKey(): String {
- return """
- -----BEGIN RSA PRIVATE KEY-----
- MIIEowIBAAKCAQEAzrUDqvGv2e0nWVT64fiHGqua6/kINU2T+CD7kaBYH7o1M7UN
- ncuQ30xG2mydKh8qPjysAQ0KK1aIa1uwsLwhFUEIdjS7hoJ7pATdrreS2pu2v32Q
- aDIwMk7w+G18hLFK/wZeQi6AQ5CjNHpVMbHNfZ3c0qH5w1nhskIySFpZDZFZP8mx
- KwJyB1RPg/oN1McAPnpnewRe9kT6nVTd/RLuJ7Z8WM19HnqXPK5KRaJVZ+vgIuAm
- BxOBWie2yfVhj28C7g5dKcPwqd6bNe3AfiZUHydrKTqtLU1ZPhnHRp7fpqtFmjp7
- 1XkLBidjtR6WN1akHdQLAtlDsh4QENNKcOz4vQIDAQABAoIBAGrgAsZ28gJOcSLq
- IlGF62zpv0800n6k3tXTT98qtYWqBGn4udKVdxFNYfD7aYNm27OUMSbV9CUWN7Cy
- lre6fax8lIBxoWfZvU2/ylLUzZREIIf/xxNop6zLTiJUkaYV+P3E8CVt35mPhiLT
- AYuRL/s8DPnHD9lmdqBxQ4hPVm4Bg7JZxbyN8in3PP1UkdWKxg91O1LYewIZHszq
- y9BdklKyxQ+fcYP5DD9KkULAjdab48GIxQETrZKp7zV0KiGrjF4Axf5y5yT2jmFT
- nZ1uZrC1MJTMYyKTBR7wsSpVBMSMUsh5XtxdJo4FuP6g9Kn6AkeQ/Y1shcWVfQgw
- 6009o8ECgYEA8J1PtnVCHxMLiVKZznzvgCe+EV0RkvuB9PGPdfpLfkHa1DKS+FzH
- 80D+Vqe0rQNLudG5Qj53MPghNirGyrjXwTYFW9xCqq9hrzfxEI4xIYOd4gHoPMMQ
- pfWZylP9GYQp/uoa+e/fcdXRSv1IDLRwJZ5XpMtWAIfvMOyDhbfjehECgYEA2+yp
- poey1y6RWuaIQd2a/PKuYk9jvLEETiz6q7t63MFd6e9cUYX02cG/6yzz6piTWUtx
- pk9e9IjclLUgV/twVz8SUgSw5TcqBrMnuIT4yQ5rQNZqiEvpCfgb5itcW7I3ADGy
- dsz2kgaAm7QVZlndQKIy7xRYBCnCD3VQ+TiWh+0CgYAT3qnKg3xmXIhDWtLgvmh4
- yM9lV64v2R0uQRR7xaOeVYngpByG7gKFEATw2wCMmQ0T10HZOpdVL+huNLId443N
- osxmfZXzym/irFf36gYcomXTWBz5h5JEYjfFAZKRHNzq9CIuKaTmHaYe7zOX+P6Z
- 3K2YKkJ74L3b6GwkCr96QQKBgQC6n0iTTSGg4h5skaXcpq2HqnP6br4G9/vcTuTk
- Z/JpdBk6k2i2sULGqlguu/W8BH89Tf0CEOZWAfGUq2Ln5jE9iAMG4H4v9DDQgKTb
- OtNW4cp3uburLydw0z7xgagdE80CeCmmEGXIIoZuGlHyiZ1r5HfuU0ghOEI6FeaB
- pdhvPQKBgEpmHV66wqSzzxmYxKjUu8gl9rIniG8SWXHlvcoGVwt1qdOMtNtvwDgB
- DnbUbANSjzIfFSqVwlx7nXG1e1yN7F1YuyUa3I5QEm4+5URoTSDghk03LTFH+kfM
- OUxwE8Su4WnoQc7WjkTG0M3FECAu7TEcF9uqdcEsW+4+JMAhE5oo
- -----END RSA PRIVATE KEY-----
- """.trimIndent()
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/ProvisionWorkplaceKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/ProvisionWorkplaceKtTest.kt
deleted file mode 100644
index 752a210..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/ProvisionWorkplaceKtTest.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace
-
-import org.domaindrivenarchitecture.provs.core.Password
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-
-internal class ProvisionWorkplaceKtTest {
-
- @Test
- fun provisionWorkplace() {
- // given
- val a = defaultTestContainer()
-
- // when
- // in order to test WorkplaceType.OFFICE: fix installing libreoffice for a fresh container as it hangs the first time but succeeds 2nd time
- val res = a.provisionWorkplace(
- WorkplaceType.MINIMAL,
- gitUserName = "testuser",
- gitEmail = "testuser@test.org",
- userPassword = Password("testuser")
- )
-
- // then
- assertTrue(res.success)
- }
-
-
- @Test
- fun provisionWorkplaceFromConfigFile() {
- // given
- val a = defaultTestContainer()
-
- // when
- // in order to test WorkplaceType.OFFICE: fix installing libreoffice for a fresh container as it hangs the first time but succeeds 2nd time
- val config = readWorkplaceConfigFromFile("src/test/resources/WorkplaceConfigExample.json")
- ?: throw Exception("Could not read WorkplaceConfig")
- val res = a.provisionWorkplace(
- config.type,
- config.ssh?.keyPair(),
- config.gpg?.keyPair(),
- config.gitUserName,
- config.gitEmail,
- )
-
- // then
- assertTrue(res.success)
- }
-}
-
-
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/FakturamaKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/FakturamaKtTest.kt
deleted file mode 100644
index 4d3e47a..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/FakturamaKtTest.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-
-internal class FakturamaKtTest {
-
- @Test
- fun installFakturama() {
- // given
- val a = defaultTestContainer()
- // when
- val res = a.def { installFakturama() }
- // then
- assertTrue(res.success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassBridgeKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassBridgeKtTest.kt
deleted file mode 100644
index 7add4bc..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassBridgeKtTest.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.ProvResult
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.core.docker.exitAndRmContainer
-import org.domaindrivenarchitecture.provs.core.local
-import org.domaindrivenarchitecture.provs.core.processors.ContainerStartMode
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.domaindrivenarchitecture.provs.test.tags.NonCi
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.configureGpgKeys
-import org.junit.jupiter.api.Assertions.assertFalse
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-import org.domaindrivenarchitecture.provs.extensions.test_keys.privateGPGSnakeoilKey
-import org.domaindrivenarchitecture.provs.extensions.test_keys.publicGPGSnakeoilKey
-
-
-internal class GopassBridgeKtTest {
-
- @ContainerTest
- @Test
- fun test_downloadGopassBridge() {
- // given
- local().exitAndRmContainer("provs_test")
- val a = defaultTestContainer()
- a.aptInstallCurl()
-
- // when
- val res = a.downloadGopassBridge()
-
- // then
- assertTrue(res.success)
- }
-
- @ContainerTest
- @Test
- fun test_install_and_configure_GopassBridgeJsonApi() {
- // given
- local().exitAndRmContainer("provs_test")
- val a = defaultTestContainer()
- val preparationResult = a.def {
- aptInstallCurl()
- configureGpgKeys(
- KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())),
- trust = true,
- skipIfExistin = false
- )
- installGopass()
- if (!chk("gopass ls")) {
- // configure/init gopass in default location with gpg-key-fingerprint of snakeoil keys
- cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init 0x0674104CA81A4905")
- } else {
- ProvResult(true, out = "gopass already configured")
- }
- }
- assertTrue(preparationResult.success)
-
- // when
- val res = a.def {
- installGopassBridgeJsonApi()
- configureGopassBridgeJsonApi()
- }
-
- // then
- assertTrue(res.success)
- }
-
- @ContainerTest
- @Test
- @NonCi
- fun test_install_GopassBridgeJsonApi_with_incompatible_gopass_jsonapi_version_installed() {
- // given
- val a = defaultTestContainer(ContainerStartMode.CREATE_NEW_KILL_EXISTING)
- val preparationResult = a.def {
- aptInstallCurl()
-
- configureGpgKeys(
- KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())),
- trust = true,
- skipIfExistin = false
- )
- installGopass("1.11.0", enforceVersion = true)
- if (!chk("gopass ls")) {
- // configure gopass in default location with gpg-key-fingerprint of snakeoil keys
- cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init 0x0674104CA81A4905")
- } else {
- ProvResult(true, out = "gopass already configured")
- }
- }
- assertTrue(preparationResult.success)
-
- // when
- val res = a.def {
- installGopassBridgeJsonApi()
- configureGopassBridgeJsonApi()
- }
-
- // then
- assertFalse(res.success)
- }
-
- @ContainerTest
- @Test
- @NonCi
- fun test_install_GopassBridgeJsonApi_with_incompatible_gopass_version_installed() {
- // given
- val a = defaultTestContainer(ContainerStartMode.CREATE_NEW_KILL_EXISTING)
- val preparationResult = a.def {
- aptInstallCurl()
- configureGpgKeys(
- KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())),
- trust = true,
- skipIfExistin = false
- )
- installGopass("1.9.0", enforceVersion = true)
- if (!chk("gopass ls")) {
- // configure gopass in default location with gpg-key-fingerprint of snakeoil keys
- cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init 0x0674104CA81A4905")
- } else {
- ProvResult(true, out = "gopass already configured")
- }
- }
- assertTrue(preparationResult.success)
-
- // when
- val res = a.def {
- installGopassBridgeJsonApi()
- configureGopassBridgeJsonApi()
- }
-
- // then
- assertFalse(res.success)
- }
-
- private fun Prov.aptInstallCurl() = def {
- cmd("apt-get update", sudo = true)
- aptInstall("curl")
- }
-}
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassKtTest.kt
deleted file mode 100644
index 98880b9..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/GopassKtTest.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.core.remote
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.*
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.configureGpgKeys
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.gpgFingerprint
-import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.GopassSecretSource
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-import org.domaindrivenarchitecture.provs.extensions.test_keys.privateGPGSnakeoilKey
-import org.domaindrivenarchitecture.provs.extensions.test_keys.publicGPGSnakeoilKey
-
-
-internal class GopassKtTest {
-
- @ContainerTest
- @Test
- fun test_installAndConfigureGopassAndMountStore() {
- // given
- val a = defaultTestContainer()
- val gopassRootDir = ".password-store"
- a.aptInstall("wget git gnupg")
- a.createDir(gopassRootDir, "~/")
- a.cmd("git init", "~/$gopassRootDir")
- val fpr = a.gpgFingerprint(publicGPGSnakeoilKey())
- println("+++++++++++++++++++++++++++++++++++++ $fpr +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
- a.createFile("~/" + gopassRootDir + "/.gpg-id", fpr)
-
- a.createDir("exampleStoreFolder", "~/")
- a.createFile("~/exampleStoreFolder/.gpg-id", fpr)
-
- a.configureGpgKeys(KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())), true)
-
- // when
- val res = a.installGopass()
- val res2 = a.configureGopass(a.userHome() + gopassRootDir)
- val res3 = a.gopassMountStore("exampleStore", "~/exampleStoreFolder")
-
- // then
- a.fileContent("~/.config/gopass/config.yml") // displays the content in the logs
- assertTrue(res.success)
- assertTrue(res2.success)
- assertTrue(res3.success)
- assertTrue(a.fileContainsText("~/.config/gopass/config.yml", "/home/testuser/.password-store"))
- assertTrue(a.fileContainsText("~/.config/gopass/config.yml", "exampleStore"))
- }
-
- @Test
- @Disabled // Integrationtest; change user, host and keys, then remove this line to run this test
- fun test_install_and_configure_Gopass_and_GopassBridgeJsonApi() {
- // settings to change
- val host = "192.168.56.135"
- val user = "xxx"
- val pubKey = GopassSecretSource("path-to/pub.key").secret()
- val privateKey = GopassSecretSource("path-to/priv.key").secret()
-
- // given
- val a = remote(host, user)
-
- // when
- val res = a.def {
- configureGpgKeys(
- KeyPair(
- pubKey,
- privateKey
- ),
- trust = true,
- skipIfExistin = true
- )
- installGopass()
-
- if (!chk("gopass ls")) {
- // configure (=init) gopass
- cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init " + gpgFingerprint(pubKey.plain())) // gopass init in default location with gpg-key-fingerprint of given key
- }
- downloadGopassBridge()
- installGopassBridgeJsonApi()
- configureGopassBridgeJsonApi()
- }
-
- // then
- assertTrue(res.success)
- }
-}
diff --git a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/VSCodeKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/VSCodeKtTest.kt
deleted file mode 100644
index 8e22383..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/extensions/workplace/base/VSCodeKtTest.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.domaindrivenarchitecture.provs.extensions.workplace.base
-
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-
-
-internal class VSCodeKtTest {
-
- @Test
- @Disabled("Test currently not working, needs fix. VSC is installed by snapd which is not currently supported to run inside docker")
- fun installVSC() {
- // given
- val a = defaultTestContainer()
- a.aptInstall("xvfb libgbm-dev libasound2")
-
- // when
- val res = a.installVSC("python", "clojure")
-
- // then
- assertTrue(res.success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/filesystem/base/FilesystemKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/filesystem/base/FilesystemKtTest.kt
deleted file mode 100644
index df29d52..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/filesystem/base/FilesystemKtTest.kt
+++ /dev/null
@@ -1,194 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.filesystem.base
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.Test
-
-
-internal class FilesystemKtTest {
-
- @Test
- @ContainerTest
- fun checkingCreatingDeletingFile() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val res1 = prov.fileExists("testfile")
- val res2 = prov.createFile("testfile", "some content")
- val res3 = prov.fileExists("testfile")
- val res4a = prov.fileContainsText("testfile", "some content")
- val res4b = prov.fileContainsText("testfile", "some non-existing content")
- val res5 = prov.deleteFile("testfile")
- val res6 = prov.fileExists("testfile")
-
- // then
- assertFalse(res1)
- assertTrue(res2.success)
- assertTrue(res3)
- assertTrue(res4a)
- assertFalse(res4b)
- assertTrue(res5.success)
- assertFalse(res6)
- }
-
-
- @Test
- @ContainerTest
- fun checkingCreatingDeletingFileWithSudo() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val file = "/testfile"
- val res1 = prov.fileExists(file)
- val res2 = prov.createFile(file, "some content", sudo = true)
- val res3 = prov.fileExists(file)
- val res4a = prov.fileContainsText(file, "some content")
- val res4b = prov.fileContainsText(file, "some non-existing content")
- val res5 = prov.deleteFile(file)
- val res6 = prov.fileExists(file)
- val res7 = prov.deleteFile(file, true)
- val res8 = prov.fileExists(file)
-
- // then
- assertFalse(res1)
- assertTrue(res2.success)
- assertTrue(res3)
- assertTrue(res4a)
- assertFalse(res4b)
- assertFalse(res5.success)
- assertTrue(res6)
- assertTrue(res7.success)
- assertFalse(res8)
- }
-
-
- @Test
- @ContainerTest
- fun checkingCreatingDeletingDir() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val res1 = prov.dirExists("testdir")
- val res2 = prov.createDir("testdir", "~/")
- val res3 = prov.dirExists("testdir")
- val res4 = prov.deleteDir("testdir", "~/")
- val res5 = prov.dirExists("testdir")
-
- val res6 = prov.dirExists("testdir", "~/test")
- val res7 = prov.createDirs("test/testdir")
- val res8 = prov.dirExists("testdir", "~/test")
- prov.deleteDir("testdir", "~/test/")
-
- // then
- assertFalse(res1)
- assertTrue(res2.success)
- assertTrue(res3)
- assertTrue(res4.success)
- assertFalse(res5)
- assertFalse(res6)
- assertTrue(res7.success)
- assertTrue(res8)
- }
-
-
- @Test
- @ContainerTest
- fun checkingCreatingDeletingDirWithSudo() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val res1 = prov.dirExists("/testdir", sudo = true)
- val res2 = prov.createDir("testdir", "/", sudo = true)
- val res3 = prov.dirExists("/testdir", sudo = true)
- val res4 = prov.deleteDir("testdir", "/", true)
- val res5 = prov.dirExists("testdir", sudo = true)
-
- // then
- assertFalse(res1)
- assertTrue(res2.success)
- assertTrue(res3)
- assertTrue(res4.success)
- assertFalse(res5)
- }
-
-
- @Test
- fun userHome() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val res1 = prov.userHome()
-
- // then
- assertEquals("/home/testuser/", res1)
- }
-
-
- @Test
- @ContainerTest
- fun replaceTextInFile() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val file = "replaceTest"
- val res1 = prov.createFile(file, "a\nb\nc\nd")
- val res2 = prov.replaceTextInFile(file,"b", "hi\nho")
- val res3 = prov.fileContent(file).equals("a\nhi\nho\nc\nd")
- val res4 = prov.deleteFile(file)
-
- // then
- assertTrue(res1.success)
- assertTrue(res2.success)
- assertTrue(res3)
- assertTrue(res4.success)
- }
-
-
- @Test
- @ContainerTest
- fun replaceTextInFileRegex() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val file = "replaceTest"
- val res1 = prov.createFile(file, "a\nbananas\nc\nd")
- val res2 = prov.replaceTextInFile(file, Regex("b.*n?nas\n"), "hi\nho\n")
- val res3 = prov.fileContent(file)
- val res4 = prov.deleteFile(file)
-
- // then
- assertTrue(res1.success)
- assertTrue(res2.success)
- assertEquals("a\nhi\nho\nc\nd",res3)
- assertTrue(res4.success)
- }
-
-
- @Test
- @ContainerTest
- fun insertTextInFile() {
- // given
- val prov = defaultTestContainer()
-
- // when
- val file = "insertTest"
- val res1 = prov.createFile(file, "a\nbananas\nc\nd")
- val res2 = prov.insertTextInFile(file, Regex("b.*n.nas\n"), "hi\n")
- val res3 = prov.fileContent(file)
- val res4 = prov.deleteFile(file)
-
- // then
- assertTrue(res1.success)
- assertTrue(res2.success)
- assertEquals("a\nbananas\nhi\nc\nd", res3)
- assertTrue(res4.success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/git/base/GitKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/git/base/GitKtTest.kt
deleted file mode 100644
index feee9e5..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/git/base/GitKtTest.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.git.base
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.keys.base.isHostKnown
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-
-
-internal class GitKtTest {
-
- @Test
- fun trustGitServers(){
- // given
- val a = defaultTestContainer()
- a.aptInstall("openssh-client")
-
- // when
- val res = a.trustGithub()
- val known = a.isHostKnown("github.com")
- val res2 = a.trustGitlab()
- val known2 = a.isHostKnown("gitlab.com")
-
- // then
- assertTrue(res.success)
- assertTrue(known)
- assertTrue(res2.success)
- assertTrue(known2)
- }
-
- @Test
- fun gitClone() {
- // given
- val prov = defaultTestContainer()
- prov.aptInstall("openssh-client ssh git")
-
- // when
- prov.trustGithub()
- prov.gitClone("https://github.com/DomainDrivenArchitecture/dda-git-crate.git", "~/")
- val res = prov.gitClone("https://github.com/DomainDrivenArchitecture/dda-git-crate.git", "~/")
-
- // then
- assertTrue(res.success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/install/base/InstallKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/install/base/InstallKtTest.kt
deleted file mode 100644
index a70853f..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/install/base/InstallKtTest.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.install.base
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-
-
-internal class InstallKtTest {
-
- @ContainerTest
- @Test
- fun aptInstall_installsPackage() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.aptInstall("rolldice")
-
- // then
- assertTrue(res.success)
- }
-
- @ContainerTest
- @Test
- @Disabled // run manually if needed;
- // todo: replace zim by a smaller repo
- fun aptInstallFromPpa_installsPackage() {
- // given
- val a = defaultTestContainer()
- a.aptInstall("software-properties-common") // prereq for adding a repo to apt
-
- // when
- val res = a.aptInstallFromPpa("jaap.karssenberg", "zim", "zim")
-
- // then
- assertTrue(res.success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/ProvisionKeysTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/ProvisionKeysTest.kt
deleted file mode 100644
index da62673..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/ProvisionKeysTest.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.keys
-
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-
-internal class ProvisionKeysTest {
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun provisionKeysCurrentUser() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.provisionKeysCurrentUser(
- KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())),
- KeyPair(Secret(publicSSHSnakeoilKey()), Secret(privateSSHSnakeoilKey()))
- )
-
- // then
- assert(res.success)
- }
-}
-
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/TestKeys.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/TestKeys.kt
deleted file mode 100644
index 1140588..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/TestKeys.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.keys
-
-
-fun publicGPGSnakeoilKey(): String {
- return """-----BEGIN PGP PUBLIC KEY BLOCK-----
-
-mQGNBF5tPEsBDADaHpW0//tcPnliBJP65gOil/WvIDi3GLGmBKN5tNmocoD9bj7C
-0yK9RVmwS6rXdf5h/CdNL33+yFyHfUyHtT68By+jYHVvakHVWKE9ac7GL6ToLMRV
-3AJKXjQYs+r+BClVShC24ipOEc+t/MJSie1mi+yr0CsrHhfcvD3WWxfZnL8DRxs6
-0UTpDxjZyA9TOHP/uLqxKLW+iwSo9TG0gEcRhfYfeejVBaWXhXmaA4iTYTO6yqvy
-BC6HInOVs654oBBrxVNyNJNhu6IPjKd7DbM42vKxSezXHEVuYggDRz8Hi3gzvfxp
-5gPdcHCoifjJdvOcN+WDh/NRhJC5frnu+yAQxf/OJF1VsTh/ezpG0TUsTagig1jF
-0tTYNZZuDjLEtW6xFEJHvRu07kx57RI3rzfJAFk2q8S1VuZvmYhxC6CQDIoZMSgi
-wxK/mkEhMW1jesfz49JPdYzTFtjtLElkGXUJ1YaCpDLrU9C9KaoKVuxx483tT6HU
-b28X37laHwNC3xMAEQEAAbQYc25ha2VvaWwgPHNuYWtlQG9pbC5jb20+iQHOBBMB
-CgA4FiEEhQUsaVQmLWHU6Zd+BnQQTKgaSQUFAl5tPEsCGwMFCwkIBwIGFQoJCAsC
-BBYCAwECHgECF4AACgkQBnQQTKgaSQW/rAwAhH0h8CTbXo8CWv0u4HbNAfx0wQf1
-/a7mQyNsSHmfenZEJjabF2s81A06+aw1hejz+QLxnklQWaz7NxVgIbfm3ArwXidB
-LQJ8PYjl8y4fxu+6+xsEdFqJXfLgaDTOUV8e2gxin5W4fbiTmGyW1kq7yZ8mhIzF
-pJ0W59GqkIKpowdQ+Sj6C8JkPn25+AQwh71LZWU/3dGakfyn/9gamgoYQgtDLzF7
-EA2zIUhBItVj44W1jv9xfpsxnoqyVZWGKqk/iOgZ9pe4kVKzCee1YkGRAnNwgB1B
-Brb5ujUcfZeem1GlA1WFzuMvtKLkk1KdfrcanJHI93SlcmZyoLsju6j2pJW6zu+H
-vEy3/uCx7LFhMVwvGAq8kWG6yWFUjQprc68sW+082/zztR2IUc8AzW3fdoCx8LPX
-4CKQt1aByYk6H8+PaRYnA8e1DuWH4dtrN3hYJBfCYmhI3WRoz+puNx3AZID31fSx
-ekBcw1lCH2c3jt7J6KB7hbovQ9J45XhKtCNkuQGNBF5tPEsBDAC2WoZBjHF+5Q7V
-0EhS6DODA5/1hbxbGvZa7QS+gHFeQDeI2QCKg/Hnesd2bjmBA7UiAzHTBDO6HuYi
-qG+K/usJdWbxGbSFThnkimc5TZ25Kvm2PglcMcxsCV/IKr+60j9Kp345X6Pp/f/L
-SuUd/Or/VJnZDWJc9vcPk3TPA5Raw+nS9pzpbROqtWPD7JjbHnA894ZgqLTbHRg/
-aO8QG7ZF/7cw+92eJ+valM1XbHdpD2VNh8P8p9IjVemL3Hsu2fyIchCkOtE9FUqt
-1HlAfIp0CW9iZnO+9kIbtfIMADb1xZjPfm1KJifjbzvRiKxAUuBw9EomhhW0hnJf
-fArgE1ceDzrHXxFw0o4TMVZSDyOjSTOAy1a8fEW6qqRVTrXWb1JTSBCur6vGT1D3
-nOontlC2fVo61cHl1M1M71iTn9kbeJwicFXoMgG948PpNIQxx+b8TJrFTv57cvbZ
-NKuldTcJcX1JZ2X9OLEh40VZUFMeVloF0M8fsvq+tA8mxkhL9yEAEQEAAYkBtgQY
-AQoAIBYhBIUFLGlUJi1h1OmXfgZ0EEyoGkkFBQJebTxLAhsMAAoJEAZ0EEyoGkkF
-dVIL/AmZZEKwo0db2nNG4SgbiGkvqYBwvDTKc9z+29a0ll32F6mfCI9efEx3KzvU
-cCOL+nRC3/cmYHEyCP1wJ8Bfg9DnJz2Df3K3P7pK2jdBsLwHIOqe+d/z7mF+IDiC
-en07VwfNyTxyqtX5WGocf2I9URRwrmOIpWZjB3Z9SODmM5k0iPnJ0d4cHg6kaUPM
-ftKszvOqrsub0yc788df3ajIlRcfNsTBs8Ba3PuzauX4DtoNbjqCY8aVbTvasYjZ
-Vnok+5aVwvltxDAkxYRUDApwH2IQNxUO/FdvkeSYWJjjrmeR2z0HOyDk7zZmCTSu
-L+JBNIfBqXaZuzTItR3bOUvwkRIodCgHp7CwrWlvtaX741uQNWQXVrFUU/Dgj8ts
-sfptcoSbXxdor4VQRCQVvclNStsEMqiqj1AafP6SmK1eYMe8U2b4TIyhSIxvgICF
-onKkzP4DFnouGGIQg99NOJP4oF2hmQslusiL5dXcNrOPeer8PFQHSd4tT+vVp8AS
-KpkCQg==
-=cS1b
------END PGP PUBLIC KEY BLOCK----- """
-}
-
-fun privateGPGSnakeoilKey(): String {
- return """-----BEGIN PGP PRIVATE KEY BLOCK-----
-
-lQVYBF5tPEsBDADaHpW0//tcPnliBJP65gOil/WvIDi3GLGmBKN5tNmocoD9bj7C
-0yK9RVmwS6rXdf5h/CdNL33+yFyHfUyHtT68By+jYHVvakHVWKE9ac7GL6ToLMRV
-3AJKXjQYs+r+BClVShC24ipOEc+t/MJSie1mi+yr0CsrHhfcvD3WWxfZnL8DRxs6
-0UTpDxjZyA9TOHP/uLqxKLW+iwSo9TG0gEcRhfYfeejVBaWXhXmaA4iTYTO6yqvy
-BC6HInOVs654oBBrxVNyNJNhu6IPjKd7DbM42vKxSezXHEVuYggDRz8Hi3gzvfxp
-5gPdcHCoifjJdvOcN+WDh/NRhJC5frnu+yAQxf/OJF1VsTh/ezpG0TUsTagig1jF
-0tTYNZZuDjLEtW6xFEJHvRu07kx57RI3rzfJAFk2q8S1VuZvmYhxC6CQDIoZMSgi
-wxK/mkEhMW1jesfz49JPdYzTFtjtLElkGXUJ1YaCpDLrU9C9KaoKVuxx483tT6HU
-b28X37laHwNC3xMAEQEAAQAL/j39p0qz3fqPfuwOpQgPy0Swr5DANZ5EFGk8tEFo
-1tt6/5IHfSrd2ue0CBOEzd9Cl7O9eGYFc2ewBiwzvkZripLh7/Yc+gNaTa+W6uyL
-X8sPy2x5HKvSRYxhTakfqU/cWur0i9+OU7uwcDfguFHBBYm5huAl3773ZIzFq0V6
-ykJ8vATwdpq200Dxm3x50XEzgDRTiivDiDPJSt/CIAhO1OP0EMlNWpEAc9mmg7L0
-AiLw40TZSRkVeyvI7NTFJnb99mY095S0ypncU4aW1F7FOwgNOTeu3JfqUOabfC1R
-dF+Jmu0+ZEZ0W6CYRQXXRDAUaTID/8e5H8lzWEmg4b7N3/6IjRjzHEz2DNMRbnBQ
-RNMEf9llaOjlpIOA7FQbPh9p5MtCwKUDhHy5+K4hjnOnUkEHVP8o/xGo6wycYb3c
-WyKWwzEJWWXoQ9do2m0NeCpHfhSegRIo5dnnd4hDzClhZTzMMSEwYYLN2LeDA47Z
-T2+8/i2wtaRnCsf8CPR0aMGH0QYA3eHKVY4e82z/e83pqoK0Lq6dmu5KbTesUdZq
-ZF/a8XnIOB3SPTfneoxDw/TFbS/mx8u1LO/tfZs/i/Z924L7n8OgkKznYxw4Tni3
-Yc5Fge/u8qGuRQ7QrIUdRYzfvhbxWV1SnYElnUn88j6qX+ky/uMqLvtkQL8oTB5F
-pRxreZ/tre0KEtvJDa5vm067BKs1n7bFyW3s/SShjbU5PR5+gw4hpK+KJ4WTafAj
-bH746PeyYppUcVPH4E9l7HDTG25fBgD7qK+LlqiRSYfYhC2IgE5TiU7x6DvtDi1K
-AYfIqfVgZe7kb0wAThezPdIKwqN+r1LkWXjUQjXlrk2QQS+EpP4W5QT5kTpL8TMx
-1Ljps8gCa8IRNu5XHPMVpr6iiEaXkMUgaf9PIp+xWdpDSWewVKhXTOdAO5pIOf9R
-+Ofjkrj212gcegs3G0yrESZonJyobfuNl2Dna/wMaQBtWyEDlM6xa9vDWoWXQXNE
-Kiwucso0jefhsmzYnJzeBcx0EQUbo80F/3QJTV1OzFtXBT5VKVnA4J6dbUmFLfZ4
-W3HXBfRvV2/U+SWi1hQNpM0eOgb+pxUdmkyeEanYSNYdvThVQzA+0OXPJnreh98S
-miUPuInfE40uOY3sV8+RP45dP4VsZLMS/HcbQmLLR+i82d50+Le5iIxBAlVpuZty
-V93sgsRMWX3BenjnvxXTvbSSFpfxKhmQW9J9lTjn9XCbZvWKAw2OryuvBUG0U0w8
-prqcgKNSMihTxkNgd0W3Cq0tUMUtztZEBewytBhzbmFrZW9pbCA8c25ha2VAb2ls
-LmNvbT6JAc4EEwEKADgWIQSFBSxpVCYtYdTpl34GdBBMqBpJBQUCXm08SwIbAwUL
-CQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRAGdBBMqBpJBb+sDACEfSHwJNtejwJa
-/S7gds0B/HTBB/X9ruZDI2xIeZ96dkQmNpsXazzUDTr5rDWF6PP5AvGeSVBZrPs3
-FWAht+bcCvBeJ0EtAnw9iOXzLh/G77r7GwR0Wold8uBoNM5RXx7aDGKflbh9uJOY
-bJbWSrvJnyaEjMWknRbn0aqQgqmjB1D5KPoLwmQ+fbn4BDCHvUtlZT/d0ZqR/Kf/
-2BqaChhCC0MvMXsQDbMhSEEi1WPjhbWO/3F+mzGeirJVlYYqqT+I6Bn2l7iRUrMJ
-57ViQZECc3CAHUEGtvm6NRx9l56bUaUDVYXO4y+0ouSTUp1+txqckcj3dKVyZnKg
-uyO7qPaklbrO74e8TLf+4LHssWExXC8YCryRYbrJYVSNCmtzryxb7Tzb/PO1HYhR
-zwDNbd92gLHws9fgIpC3VoHJiTofz49pFicDx7UO5Yfh22s3eFgkF8JiaEjdZGjP
-6m43HcBkgPfV9LF6QFzDWUIfZzeO3snooHuFui9D0njleEq0I2SdBVgEXm08SwEM
-ALZahkGMcX7lDtXQSFLoM4MDn/WFvFsa9lrtBL6AcV5AN4jZAIqD8ed6x3ZuOYED
-tSIDMdMEM7oe5iKob4r+6wl1ZvEZtIVOGeSKZzlNnbkq+bY+CVwxzGwJX8gqv7rS
-P0qnfjlfo+n9/8tK5R386v9UmdkNYlz29w+TdM8DlFrD6dL2nOltE6q1Y8PsmNse
-cDz3hmCotNsdGD9o7xAbtkX/tzD73Z4n69qUzVdsd2kPZU2Hw/yn0iNV6Yvcey7Z
-/IhyEKQ60T0VSq3UeUB8inQJb2Jmc772Qhu18gwANvXFmM9+bUomJ+NvO9GIrEBS
-4HD0SiaGFbSGcl98CuATVx4POsdfEXDSjhMxVlIPI6NJM4DLVrx8RbqqpFVOtdZv
-UlNIEK6vq8ZPUPec6ie2ULZ9WjrVweXUzUzvWJOf2Rt4nCJwVegyAb3jw+k0hDHH
-5vxMmsVO/nty9tk0q6V1NwlxfUlnZf04sSHjRVlQUx5WWgXQzx+y+r60DybGSEv3
-IQARAQABAAv+KYmwWGEV/1pNCU5jEyOajEb4mnRmxff70xV3ha97Y4VMQStxMJxC
-r8BrjCIqjiVajs9ce51S7RwZvx5QHkDYKDTqiJQa51y1kDYoskhoW6Qa8rTp6+ra
-DmgKPe3i87rtuOMzYP1UuLnnmRbL3wtcOmI6k1M1q0iEWbN0oa1Gj3BeJHSRpKh4
-mOOtwJT18r/ZwEGABieX3uufON59ylUNrZ9Eyu8sedjNJGLN7ZKjFrbvk/wPnE9c
-EjmBNB86nh8AQSw5hfluFanLQGHzfwzE1A2PtR7IP3x20Eoh/k5OI7Ybu3POWVKP
-DbdnOK8AF4yJHPTflVHTzPLTpI4gyE4oIZHsmygFDJTZUl0edJw81ZT0HK0i9TXo
-5wsiJoy6EFfguJfJXoBeRrqkWTtRbfTyUSHkAXWn+PG9vW7ntdXb0ttZ8nPDkLVy
-bGgGJgc0u0560eNGLKOqDkrV6Ltam0cVbrFfSBM8PwNXD3kJ3+DyHblpf/LaZdmL
-nWbsNfBTM8zZBgDKN8C1H4n6sJd9MN0Y7O/6FCNLsq0ZM26/k4zQlXCn+FkfcbV6
-INVts04NzRDiBBhXLZp4hNKzi95sbhJEkOib/scYSlFZsFwQr4NdwKba8q3//h4y
-tusyHNcX9+KXPJjGsfjpjpHcQh2W/t/jtdQ4YdD1ELjhL3tqd2F6J0mTTze7eRw3
-p121lHOAYk8sWVZftzTs4DX5Sa9DfAW/0V3OGciKC0D9Z1vhHRpvLZ7L3ui6BtfP
-Sj162/HkP1OPHq0GAObaS4GdYd9Afhhyot49BwDOfGSDaUCvR6XA3hqMCyD2hqWS
-Q7/9FZzVTQf0N7fYkPouL02s31Lv/LptBwws8qzvMIVSkRxOOb11x8c4WYuyPriJ
-zLHHyWpzAzg7JU0A7LqllBmBBB3xrRlWTjhVo/4buPTM+eIJYK5EMRUskJUzNoiZ
-RNhZ9EOIYhAW1KE66WZZonMLqX8M+QSs8D3ft/e9BO8x9DUzACGse2BXtc+mQy+1
-/9eKILw5sgQfngZMxQYAhnrhsw5ag6RWIPQlhX5VNV1nXnDVrEUbCa7phhcegpbp
-quN+ytXd5eEI5YZyrHc+HqL7VJ6qpxOLniy+5c8gi2SzAO9NfJ2cYbWXe5N5GsUn
-o4Yg44r5P5HXAOdK+MgMzp2JWiDRH0H9FmUuJb/UxJvpvtQbithHRibNlXHz8Pvi
-VA90wJB+ACq8hpr/5vWxeiTUyfeMC8oPLXS/U0HLEicaKDT80j9by1HkC+gKNx+h
-NUEELT5hVjxd4icpAxCW4NOJAbYEGAEKACAWIQSFBSxpVCYtYdTpl34GdBBMqBpJ
-BQUCXm08SwIbDAAKCRAGdBBMqBpJBXVSC/wJmWRCsKNHW9pzRuEoG4hpL6mAcLw0
-ynPc/tvWtJZd9hepnwiPXnxMdys71HAji/p0Qt/3JmBxMgj9cCfAX4PQ5yc9g39y
-tz+6Sto3QbC8ByDqnvnf8+5hfiA4gnp9O1cHzck8cqrV+VhqHH9iPVEUcK5jiKVm
-Ywd2fUjg5jOZNIj5ydHeHB4OpGlDzH7SrM7zqq7Lm9MnO/PHX92oyJUXHzbEwbPA
-Wtz7s2rl+A7aDW46gmPGlW072rGI2VZ6JPuWlcL5bcQwJMWEVAwKcB9iEDcVDvxX
-b5HkmFiY465nkds9Bzsg5O82Zgk0ri/iQTSHwal2mbs0yLUd2zlL8JESKHQoB6ew
-sK1pb7Wl++NbkDVkF1axVFPw4I/LbLH6bXKEm18XaK+FUEQkFb3JTUrbBDKoqo9Q
-Gnz+kpitXmDHvFNm+EyMoUiMb4CAhaJypMz+AxZ6LhhiEIPfTTiT+KBdoZkLJbrI
-i+XV3Dazj3nq/DxUB0neLU/r1afAEiqZAkI=
-=h5SJ
------END PGP PRIVATE KEY BLOCK-----""".trimIndent()
-}
-
-fun publicSSHSnakeoilKey(): String {
- return """ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOtQOq8a/Z7SdZVPrh+Icaq5rr+Qg1TZP4IPuRoFgfujUztQ2dy5DfTEbabJ0qHyo+PKwBDQorVohrW7CwvCEVQQh2NLuGgnukBN2ut5Lam7a/fZBoMjAyTvD4bXyEsUr/Bl5CLoBDkKM0elUxsc19ndzSofnDWeGyQjJIWlkNkVk/ybErAnIHVE+D+g3UxwA+emd7BF72RPqdVN39Eu4ntnxYzX0eepc8rkpFolVn6+Ai4CYHE4FaJ7bJ9WGPbwLuDl0pw/Cp3ps17cB+JlQfJ2spOq0tTVk+GcdGnt+mq0WaOnvVeQsGJ2O1HpY3VqQd1AsC2UOyHhAQ00pw7Pi9 snake@oil.com"""
-}
-
-fun privateSSHSnakeoilKey(): String {
- return """
- -----BEGIN RSA PRIVATE KEY-----
- MIIEowIBAAKCAQEAzrUDqvGv2e0nWVT64fiHGqua6/kINU2T+CD7kaBYH7o1M7UN
- ncuQ30xG2mydKh8qPjysAQ0KK1aIa1uwsLwhFUEIdjS7hoJ7pATdrreS2pu2v32Q
- aDIwMk7w+G18hLFK/wZeQi6AQ5CjNHpVMbHNfZ3c0qH5w1nhskIySFpZDZFZP8mx
- KwJyB1RPg/oN1McAPnpnewRe9kT6nVTd/RLuJ7Z8WM19HnqXPK5KRaJVZ+vgIuAm
- BxOBWie2yfVhj28C7g5dKcPwqd6bNe3AfiZUHydrKTqtLU1ZPhnHRp7fpqtFmjp7
- 1XkLBidjtR6WN1akHdQLAtlDsh4QENNKcOz4vQIDAQABAoIBAGrgAsZ28gJOcSLq
- IlGF62zpv0800n6k3tXTT98qtYWqBGn4udKVdxFNYfD7aYNm27OUMSbV9CUWN7Cy
- lre6fax8lIBxoWfZvU2/ylLUzZREIIf/xxNop6zLTiJUkaYV+P3E8CVt35mPhiLT
- AYuRL/s8DPnHD9lmdqBxQ4hPVm4Bg7JZxbyN8in3PP1UkdWKxg91O1LYewIZHszq
- y9BdklKyxQ+fcYP5DD9KkULAjdab48GIxQETrZKp7zV0KiGrjF4Axf5y5yT2jmFT
- nZ1uZrC1MJTMYyKTBR7wsSpVBMSMUsh5XtxdJo4FuP6g9Kn6AkeQ/Y1shcWVfQgw
- 6009o8ECgYEA8J1PtnVCHxMLiVKZznzvgCe+EV0RkvuB9PGPdfpLfkHa1DKS+FzH
- 80D+Vqe0rQNLudG5Qj53MPghNirGyrjXwTYFW9xCqq9hrzfxEI4xIYOd4gHoPMMQ
- pfWZylP9GYQp/uoa+e/fcdXRSv1IDLRwJZ5XpMtWAIfvMOyDhbfjehECgYEA2+yp
- poey1y6RWuaIQd2a/PKuYk9jvLEETiz6q7t63MFd6e9cUYX02cG/6yzz6piTWUtx
- pk9e9IjclLUgV/twVz8SUgSw5TcqBrMnuIT4yQ5rQNZqiEvpCfgb5itcW7I3ADGy
- dsz2kgaAm7QVZlndQKIy7xRYBCnCD3VQ+TiWh+0CgYAT3qnKg3xmXIhDWtLgvmh4
- yM9lV64v2R0uQRR7xaOeVYngpByG7gKFEATw2wCMmQ0T10HZOpdVL+huNLId443N
- osxmfZXzym/irFf36gYcomXTWBz5h5JEYjfFAZKRHNzq9CIuKaTmHaYe7zOX+P6Z
- 3K2YKkJ74L3b6GwkCr96QQKBgQC6n0iTTSGg4h5skaXcpq2HqnP6br4G9/vcTuTk
- Z/JpdBk6k2i2sULGqlguu/W8BH89Tf0CEOZWAfGUq2Ln5jE9iAMG4H4v9DDQgKTb
- OtNW4cp3uburLydw0z7xgagdE80CeCmmEGXIIoZuGlHyiZ1r5HfuU0ghOEI6FeaB
- pdhvPQKBgEpmHV66wqSzzxmYxKjUu8gl9rIniG8SWXHlvcoGVwt1qdOMtNtvwDgB
- DnbUbANSjzIfFSqVwlx7nXG1e1yN7F1YuyUa3I5QEm4+5URoTSDghk03LTFH+kfM
- OUxwE8Su4WnoQc7WjkTG0M3FECAu7TEcF9uqdcEsW+4+JMAhE5oo
- -----END RSA PRIVATE KEY-----
- """.trimIndent()
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/base/GpgKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/base/GpgKtTest.kt
deleted file mode 100644
index f76e6e4..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/base/GpgKtTest.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.keys.base
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.core.processors.ContainerStartMode
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
-import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
-import org.domaindrivenarchitecture.provs.ubuntu.keys.privateGPGSnakeoilKey
-import org.domaindrivenarchitecture.provs.ubuntu.keys.publicGPGSnakeoilKey
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-
-internal class GpgKtTest {
-
- @Test
- @ContainerTest
- fun gpgFingerprint_returnsCorrectFingerprint() {
- // given
- val a = defaultTestContainer()
- a.aptInstall("gpg")
- a.cmd("gpg --version") // just for info reasons
-
- // when
- val fingerprint = a.gpgFingerprint(publicGPGSnakeoilKey())
-
- // then
- assertEquals("85052C6954262D61D4E9977E0674104CA81A4905", fingerprint)
- }
-
-
- @Test
- @ContainerTest
- fun configureGpgKeys() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.configureGpgKeys(KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())))
-
- // then
- assertTrue(res.success)
- }
-
-
- @Test
- @ContainerTest
- fun configureGpgKeysTrusted() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.configureGpgKeys(KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())), true)
-
- // then
- assertTrue(res.success)
- val trustedKey = a.cmd("gpg -K | grep ultimate").out
- assertEquals("uid [ultimate] snakeoil ", trustedKey?.trim())
- }
-
-
- @Test
- @ContainerTest
- fun configureGpgKeysIsIdempotent() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.configureGpgKeys(KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())))
- val res2 = a.configureGpgKeys(KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())))
-
- // then
- assertTrue(res.success)
- assertTrue(res2.success)
- }
-}
-
-
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/base/SshKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/base/SshKtTest.kt
deleted file mode 100644
index 88b542c..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/keys/base/SshKtTest.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.keys.base
-
-import org.domaindrivenarchitecture.provs.core.Secret
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.ubuntu.keys.*
-import org.junit.jupiter.api.Test
-
-import org.junit.jupiter.api.Assertions.*
-
-internal class SshKtTest {
-
- @Test
- fun configureSshKeys() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.configureSshKeys(KeyPair(Secret(publicSSHSnakeoilKey()), Secret(privateSSHSnakeoilKey())))
-
- // then
- assertTrue(res.success)
-
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PromptSecretSourceTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PromptSecretSourceTest.kt
deleted file mode 100644
index 3374435..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/secret/secretSources/PromptSecretSourceTest.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources
-
-import org.junit.jupiter.api.Disabled
-import org.junit.jupiter.api.Test
-
-internal class PromptSecretSourceTest {
-
- @Test
- @Disabled // run manually
- fun secret() {
- println("Secret: " + PromptSecretSource().secret().plain())
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/user/ProvisionUserKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/user/ProvisionUserKtTest.kt
deleted file mode 100644
index be3f1db..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/user/ProvisionUserKtTest.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.user
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.ubuntu.keys.*
-import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSourceType
-import org.domaindrivenarchitecture.provs.ubuntu.user.base.configureUser
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.condition.EnabledOnOs
-import org.junit.jupiter.api.condition.OS
-
-
-internal class ProvisionUserKtTest {
-
- @Test
- @EnabledOnOs(OS.LINUX)
- fun configureUser() {
- // given
- val a = defaultTestContainer()
-
- // when
- val res = a.configureUser(
- UserConfig(
- "testuser",
- "test@mail.com",
- KeyPairSource(SecretSourceType.PLAIN, publicGPGSnakeoilKey(), privateGPGSnakeoilKey()),
- KeyPairSource(SecretSourceType.PLAIN, publicSSHSnakeoilKey(), privateSSHSnakeoilKey())
- )
- )
-
- // then
- assert(res.success)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/utils/UtilsKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/utils/UtilsKtTest.kt
deleted file mode 100644
index 8c39d98..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/utils/UtilsKtTest.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.utils
-
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-
-internal class UtilsKtTest {
-
- @ContainerTest
- @Test
- fun printToShell_escapes_successfully() {
- // given
- val a = Prov.defaultInstance()
-
- // when
- val testString = "test if newline \n and apostrophe's ' \" and special chars !§$%[]\\ äöüß are handled correctly"
- val res = a.cmd(printToShell(testString)).out
-
- // then
- assertEquals(testString, res)
- }
-}
\ No newline at end of file
diff --git a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/web/base/WebKtTest.kt b/bin/test/org/domaindrivenarchitecture/provs/ubuntu/web/base/WebKtTest.kt
deleted file mode 100644
index 07f5879..0000000
--- a/bin/test/org/domaindrivenarchitecture/provs/ubuntu/web/base/WebKtTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.domaindrivenarchitecture.provs.ubuntu.web.base
-
-import org.domaindrivenarchitecture.provs.test.defaultTestContainer
-import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile
-import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileContent
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-
-internal class WebKtTest {
-
- @ContainerTest
- @Test
- fun downloadFromURL_downloadsFile() {
- // given
- val a = defaultTestContainer()
- val file = "file1"
- a.createFile("/tmp/" + file, "hello")
-
- // when
- val res = a.downloadFromURL("file:///tmp/" + file, "file2", "/tmp")
-
- // then
- val res2 = a.fileContent("/tmp/file2")
-
- assertTrue(res.success)
- assertEquals("hello", res2)
- }
-}
\ No newline at end of file
diff --git a/bin/testFixtures/logback-test.xml b/bin/testFixtures/logback-test.xml
deleted file mode 100644
index a43a2a2..0000000
--- a/bin/testFixtures/logback-test.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- System.err
-
-
- %d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{35}) - %msg %n
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/bin/testFixtures/org/domaindrivenarchitecture/provs/test/TestSetup.kt b/bin/testFixtures/org/domaindrivenarchitecture/provs/test/TestSetup.kt
deleted file mode 100644
index 5cf6261..0000000
--- a/bin/testFixtures/org/domaindrivenarchitecture/provs/test/TestSetup.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.domaindrivenarchitecture.provs.test
-
-import org.domaindrivenarchitecture.provs.core.ProgressType
-import org.domaindrivenarchitecture.provs.core.Prov
-import org.domaindrivenarchitecture.provs.core.docker.dockerImageExists
-import org.domaindrivenarchitecture.provs.core.docker.dockerProvideImage
-import org.domaindrivenarchitecture.provs.core.docker.dockerimages.UbuntuPlusUser
-import org.domaindrivenarchitecture.provs.core.processors.ContainerStartMode
-import org.domaindrivenarchitecture.provs.core.processors.ContainerUbuntuHostProcessor
-
-val testDockerWithSudo = !"true".equals(System.getProperty("testdockerwithoutsudo")?.toLowerCase())
-
-const val defaultTestContainerName = "provs_test"
-
-fun defaultTestContainer(startMode: ContainerStartMode = ContainerStartMode.USE_RUNNING_ELSE_CREATE): Prov {
- val image = UbuntuPlusUser()
- val prov = testLocal()
- if (!prov.dockerImageExists(image.imageName(), testDockerWithSudo)) {
- prov.dockerProvideImage(image, sudo = testDockerWithSudo)
- }
-
- return Prov.newInstance(
- ContainerUbuntuHostProcessor(
- defaultTestContainerName,
- startMode = startMode,
- sudo = testDockerWithSudo,
- dockerImage = image.imageName()
- ),
- progressType = ProgressType.NONE
- )
-}
-
-fun testLocal(): Prov {
- return Prov.newInstance(name = "testing", progressType = ProgressType.NONE)
-}
\ No newline at end of file
diff --git a/bin/testFixtures/org/domaindrivenarchitecture/provs/test/tags/Tags.kt b/bin/testFixtures/org/domaindrivenarchitecture/provs/test/tags/Tags.kt
deleted file mode 100644
index bc24bc5..0000000
--- a/bin/testFixtures/org/domaindrivenarchitecture/provs/test/tags/Tags.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.domaindrivenarchitecture.provs.test.tags
-
-import org.junit.jupiter.api.Tag
-import org.junit.jupiter.api.Test
-
-private const val CONTAINER_TEST = "containertest"
-private const val CONTAINER_TEST_NON_CI = "containernonci"
-
-
-@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
-@kotlin.annotation.Retention
-@Tag(CONTAINER_TEST)
-@Test
-annotation class ContainerTest
-
-
-@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
-@kotlin.annotation.Retention
-@Tag(CONTAINER_TEST_NON_CI)
-@Test
-annotation class NonCi
\ No newline at end of file