add test app apple for k3s

This commit is contained in:
az 2021-11-26 19:16:01 +01:00
parent caaab02b7c
commit 1ea82db32e
7 changed files with 88 additions and 27 deletions

View file

@ -16,7 +16,7 @@ import java.net.InetAddress
*/ */
fun getCallingMethodName(): String? { fun getCallingMethodName(): String? {
val offsetVal = 1 val offsetVal = 1
val exclude = arrayOf("def", "record", "invoke", "invoke0", "handle", "def\$default", "addResultToEval", "handle\$default") val exclude = arrayOf("task", "def", "record", "invoke", "invoke0", "handle", "task\$default", "def\$default", "addResultToEval", "handle\$default")
// suffixes are also ignored as method names but will be added as suffix in the evaluation results // suffixes are also ignored as method names but will be added as suffix in the evaluation results
val suffixes = arrayOf("optional", "requireAll", "requireLast", "inContainer") val suffixes = arrayOf("optional", "requireAll", "requireLast", "inContainer")
@ -45,15 +45,25 @@ fun String.escapeControlChars(): String = replace("\r", "\\r").replace("\n", "\\
fun String.escapeBackslash(): String = replace("\\", "\\\\") fun String.escapeBackslash(): String = replace("\\", "\\\\")
fun String.escapeDoubleQuote(): String = replace("\"", "\\\"") fun String.escapeDoubleQuote(): String = replace("\"", "\\\"")
fun String.escapeSingleQuote(): String = replace("'", "\'") fun String.escapeSingleQuote(): String = replace("'", "\'")
fun String.escapeBacktick(): String = replace("`", "\\`")
fun String.escapeDollar(): String = replace("$", "\\$")
fun String.escapeSingleQuoteForShell(): String = replace("'", "'\"'\"'") fun String.escapeSingleQuoteForShell(): String = replace("'", "'\"'\"'")
fun String.escapeProcentForPrintf(): String = replace("%", "%%") fun String.escapeProcentForPrintf(): String = replace("%", "%%")
fun String.endingWithFileSeparator(): String = if (length > 0 && (last() != fileSeparatorChar())) this + fileSeparator() else this fun String.endingWithFileSeparator(): String = if (length > 0 && (last() != fileSeparatorChar())) this + fileSeparator() else this
// see https://www.shellscript.sh/escape.html
fun String.escapeAndEncloseByDoubleQuoteForShell(): String { fun String.escapeAndEncloseByDoubleQuoteForShell(): String {
return "\"" + this.escapeBackslash().replace("`", "\\`").escapeDoubleQuote().replace("$", "\\$") + "\"" return "\"" + this.escapeForShell() + "\""
} }
fun String.escapeForShell(): String {
// see https://www.shellscript.sh/escape.html
return this.escapeBackslash().escapeBacktick().escapeDoubleQuote().escapeDollar()
}
internal fun echoCommandForText(text: String): String {
return "echo -n ${text.escapeAndEncloseByDoubleQuoteForShell()}"
}
fun fileSeparator(): String = File.separator fun fileSeparator(): String = File.separator
fun fileSeparatorChar(): Char = File.separatorChar fun fileSeparatorChar(): Char = File.separatorChar
fun newline(): String = System.getProperty("line.separator") fun newline(): String = System.getProperty("line.separator")

View file

@ -2,7 +2,10 @@ package org.domaindrivenarchitecture.provs.extensions.server_software.k3s
import org.domaindrivenarchitecture.provs.core.Prov import org.domaindrivenarchitecture.provs.core.Prov
import org.domaindrivenarchitecture.provs.core.ProvResult import org.domaindrivenarchitecture.provs.core.ProvResult
import org.domaindrivenarchitecture.provs.core.echoCommandForText
import org.domaindrivenarchitecture.provs.core.remote import org.domaindrivenarchitecture.provs.core.remote
import org.domaindrivenarchitecture.provs.extensions.server_software.k3s.apple.appleConfig
import org.domaindrivenarchitecture.provs.extensions.server_software.k3s.apple.checkAppleService
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.PromptSecretSource import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.PromptSecretSource
@ -12,7 +15,7 @@ import org.domaindrivenarchitecture.provs.ubuntu.secret.secretSources.PromptSecr
* If docker is true, then k3s will be installed with docker option and also docker will be installed (may conflict if docker is already existing). * If docker is true, then k3s will be installed with docker option and also docker will be installed (may conflict if docker is already existing).
* If host is specified, then tls (if configured) also applies to host. * If host is specified, then tls (if configured) also applies to host.
*/ */
fun Prov.installK3sServer(docker: Boolean = false, host: String? = null) = def { fun Prov.installK3sServer(docker: Boolean = false, host: String? = null) = task {
val tls = host?.let { "INSTALL_K3S_EXEC=\"--tls-san ${it}\"" } ?: "" val tls = host?.let { "INSTALL_K3S_EXEC=\"--tls-san ${it}\"" } ?: ""
aptInstall("curl") aptInstall("curl")
if (!chk("k3s -version")) { if (!chk("k3s -version")) {
@ -31,25 +34,35 @@ fun Prov.installK3sServer(docker: Boolean = false, host: String? = null) = def {
} }
fun Prov.uninstallK3sServer() = def { fun Prov.uninstallK3sServer() = task {
cmd("sudo /usr/local/bin/k3s-uninstall.sh") cmd("sudo /usr/local/bin/k3s-uninstall.sh")
} }
fun Prov.applyConfig(configAsYaml: String) = task {
cmd(echoCommandForText(configAsYaml) + " | sudo k3s kubectl apply -f -")
}
fun main() { fun main() {
val host = "192.168.56.123" val host = "192.168.56.141"
val remoteUser = "remoteUsername" val remoteUser = "usr"
val passwordK3sUser = PromptSecretSource("Enter Password").secret() val passwordK3sUser = PromptSecretSource("Enter Password").secret()
remote(host, remoteUser, passwordK3sUser).def { remote(host, remoteUser, passwordK3sUser).def {
// local().task {
val result = installK3sServer() installK3sServer()
// print pods for information purpose // print pods for information purpose
println(cmd("sudo k3s kubectl get pods --all-namespaces").out) println(cmd("sudo k3s kubectl get pods --all-namespaces").out)
// return result of installation applyConfig(appleConfig())
result
// print pods for information purpose
println(cmd("sudo k3s kubectl get services").out)
checkAppleService("sudo k3s kubectl")
} }
} }

View file

@ -0,0 +1,48 @@
package org.domaindrivenarchitecture.provs.extensions.server_software.k3s.apple
import org.domaindrivenarchitecture.provs.core.Prov
import org.domaindrivenarchitecture.provs.core.ProvResult
fun Prov.checkAppleService(kubeCtlCmd: String = "kubectl") = task {
val ip = cmd(kubeCtlCmd + " get svc apple-service -o jsonpath=\"{.spec.clusterIP}\"\n").out
val port = cmd(kubeCtlCmd + " get svc apple-service -o jsonpath=\"{.spec.ports[0].port}\"\n").out
if (ip == null || port == null) {
return@task ProvResult(false)
}
val apple = cmd("curl -m 30 $ip:$port").out
if ("apple" == apple) {
ProvResult(true)
} else {
ProvResult(false, err = "Apple service did not return \"apple\" but instead: " + apple)
}
}
fun appleConfig() =
"""
kind: Pod
apiVersion: v1
metadata:
name: apple-app
labels:
app: apple
spec:
containers:
- name: apple-app
image: hashicorp/http-echo
args:
- "-text=apple"
---
kind: Service
apiVersion: v1
metadata:
name: apple-service
spec:
selector:
app: apple
ports:
- port: 5678 # Default port for image
"""

View file

@ -4,7 +4,7 @@ import org.domaindrivenarchitecture.provs.core.Prov
import org.domaindrivenarchitecture.provs.core.ProvResult import org.domaindrivenarchitecture.provs.core.ProvResult
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.* import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.*
import org.domaindrivenarchitecture.provs.ubuntu.keys.base.isHostKnown import org.domaindrivenarchitecture.provs.ubuntu.keys.base.isHostKnown
import org.domaindrivenarchitecture.provs.ubuntu.utils.printToShell import org.domaindrivenarchitecture.provs.core.echoCommandForText
import java.io.File import java.io.File
val knownHostsFile = "~/.ssh/known_hosts" val knownHostsFile = "~/.ssh/known_hosts"
@ -93,7 +93,7 @@ private fun Prov.trustHost(host: String, fingerprintsOfKeysToBeAdded: Set<String
err = "Fingerprint ($fingerprintToBeAdded) could not be found in actual fingerprints: $actualFingerprints" err = "Fingerprint ($fingerprintToBeAdded) could not be found in actual fingerprints: $actualFingerprints"
) )
} }
cmd(printToShell(actualKeys.get(indexOfKeyFound)) + " >> $knownHostsFile") cmd(echoCommandForText(actualKeys.get(indexOfKeyFound)) + " >> $knownHostsFile")
} }
ProvResult(true) ProvResult(true)
} }

View file

@ -8,7 +8,7 @@ import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createSecretFil
import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.dirExists import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.dirExists
import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall import org.domaindrivenarchitecture.provs.ubuntu.install.base.aptInstall
import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair import org.domaindrivenarchitecture.provs.ubuntu.keys.KeyPair
import org.domaindrivenarchitecture.provs.ubuntu.utils.printToShell import org.domaindrivenarchitecture.provs.core.echoCommandForText
/** /**
@ -69,6 +69,6 @@ private fun Prov.gpgKeysInstalled(fingerprint: String): Boolean {
fun Prov.gpgFingerprint(pubKey: String): String? { fun Prov.gpgFingerprint(pubKey: String): String? {
val result = val result =
cmdNoLog(" " + printToShell(pubKey) + " | gpg --with-colons --import-options show-only --import --fingerprint") cmdNoLog(" " + echoCommandForText(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) } return result.out?.let { """^fpr:*([A-Z0-9]*):$""".toRegex(RegexOption.MULTILINE).find(it)?.groupValues?.get(1) }
} }

View file

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

View file

@ -1,6 +1,7 @@
package org.domaindrivenarchitecture.provs.ubuntu.utils package org.domaindrivenarchitecture.provs.ubuntu.utils
import org.domaindrivenarchitecture.provs.core.Prov import org.domaindrivenarchitecture.provs.core.Prov
import org.domaindrivenarchitecture.provs.core.echoCommandForText
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -14,8 +15,8 @@ internal class UtilsKtTest {
val a = Prov.defaultInstance() val a = Prov.defaultInstance()
// when // when
val testString = "test if newline \n and apostrophe's ' \" and special chars !§$%[]\\ äöüß are handled correctly" val testString = "test if newline \n and apostrophe's ' \" and special chars !§$%[]\\ äöüß \$variable are handled correctly"
val res = a.cmd(printToShell(testString)).out val res = a.cmd(echoCommandForText(testString)).out
// then // then
assertEquals(testString, res) assertEquals(testString, res)