Merge branch 'master' into local-sudoer-without-pw

This commit is contained in:
az 2023-02-23 21:10:42 +01:00
commit f672624928
8 changed files with 46 additions and 35 deletions

View file

@ -1,6 +1,7 @@
package org.domaindrivenarchitecture.provs.desktop.application package org.domaindrivenarchitecture.provs.desktop.application
import kotlinx.cli.ArgType import kotlinx.cli.ArgType
import kotlinx.cli.ExperimentalCli
import kotlinx.cli.Subcommand import kotlinx.cli.Subcommand
import org.domaindrivenarchitecture.provs.configuration.application.CliTargetParser import org.domaindrivenarchitecture.provs.configuration.application.CliTargetParser
import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName
@ -10,6 +11,7 @@ import org.domaindrivenarchitecture.provs.desktop.domain.DesktopOnlyModule
import org.domaindrivenarchitecture.provs.desktop.domain.DesktopType import org.domaindrivenarchitecture.provs.desktop.domain.DesktopType
@OptIn(ExperimentalCli::class)
open class CliArgumentsParser(name: String) : CliTargetParser(name) { open class CliArgumentsParser(name: String) : CliTargetParser(name) {
private val modules: List<DesktopSubcommand> = listOf(Basic(), Office(), Ide()) private val modules: List<DesktopSubcommand> = listOf(Basic(), Office(), Ide())
@ -55,7 +57,7 @@ open class CliArgumentsParser(name: String) : CliTargetParser(name) {
override fun execute() { override fun execute() {
configFileName = cliConfigFileName?.let { ConfigFileName(it) } configFileName = cliConfigFileName?.let { ConfigFileName(it) }
parsed = true parsed = true
onlyModules = if (only != null) listOf(only!!.name.lowercase()) else null onlyModules = only?.let { listOf(it.name.lowercase()) }
} }
} }

View file

@ -1,18 +1,18 @@
package org.domaindrivenarchitecture.provs.server.application package org.domaindrivenarchitecture.provs.server.application
import kotlinx.cli.ArgType import kotlinx.cli.ArgType
import kotlinx.cli.ExperimentalCli
import kotlinx.cli.Subcommand import kotlinx.cli.Subcommand
import org.domaindrivenarchitecture.provs.configuration.application.CliTargetParser import org.domaindrivenarchitecture.provs.configuration.application.CliTargetParser
import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName
import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand
import org.domaindrivenarchitecture.provs.server.domain.ServerCliCommand import org.domaindrivenarchitecture.provs.server.domain.ServerCliCommand
import org.domaindrivenarchitecture.provs.server.domain.ServerType import org.domaindrivenarchitecture.provs.server.domain.ServerType
import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFile
import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileName import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileName
import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sCliCommand import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sCliCommand
import org.domaindrivenarchitecture.provs.server.domain.k3s.ServerOnlyModule import org.domaindrivenarchitecture.provs.server.domain.k3s.ServerOnlyModule
import org.domaindrivenarchitecture.provs.server.infrastructure.DefaultApplicationFileRepository
@OptIn(ExperimentalCli::class)
class CliArgumentsParser(name: String) : CliTargetParser(name) { class CliArgumentsParser(name: String) : CliTargetParser(name) {
private val modules: List<ServerSubcommand> = listOf(K3s(), K3d()) private val modules: List<ServerSubcommand> = listOf(K3s(), K3d())
@ -86,7 +86,7 @@ class CliArgumentsParser(name: String) : CliTargetParser(name) {
override fun execute() { override fun execute() {
super.configFileName = cliConfigFileName?.let { ConfigFileName(it) } super.configFileName = cliConfigFileName?.let { ConfigFileName(it) }
super.applicationFileName = cliApplicationFileName?.let { ApplicationFileName(it) } super.applicationFileName = cliApplicationFileName?.let { ApplicationFileName(it) }
super.onlyModules = if (only != null) listOf(only!!.name.lowercase()) else null super.onlyModules = only?.let { listOf(it.name.lowercase()) }
super.reprovision = cliReprovision == true super.reprovision = cliReprovision == true
super.parsed = true super.parsed = true
} }

View file

@ -1,8 +1,5 @@
package org.domaindrivenarchitecture.provs.server.domain.k3s package org.domaindrivenarchitecture.provs.server.domain.k3s
import org.domaindrivenarchitecture.provs.framework.core.getLocalFileContent
import java.io.File
data class ApplicationFile(val id: ApplicationFileName, val fileContent: String) { data class ApplicationFile(val id: ApplicationFileName, val fileContent: String) {
fun validate() : List<String> { fun validate() : List<String> {
@ -13,13 +10,14 @@ data class ApplicationFile(val id: ApplicationFileName, val fileContent: String)
if(fileContent.isEmpty()) { if(fileContent.isEmpty()) {
output.add("fileContent is empty.") output.add("fileContent is empty.")
} }
if (fileContent.contains(specRegex)) { val specMatch = specRegex.find(fileContent)
output.add(specRegex.find(fileContent)!!.value) if (specMatch != null) {
output.add(specMatch.value)
} }
if (fileContent.contains(javaRegex)) { val javaMatch = javaRegex.find(fileContent)
output.add(javaRegex.find(fileContent)!!.value) if (javaMatch != null) {
output.add(javaMatch.value)
} }
return output return output
} }
fun isValid() : Boolean { fun isValid() : Boolean {

View file

@ -12,12 +12,12 @@ fun Prov.provisionK3sCommand(cli: K3sCliCommand) = task {
val grafanaConfigResolved: GrafanaAgentConfigResolved? = findK8sGrafanaConfig(cli.configFileName)?.resolveSecret() val grafanaConfigResolved: GrafanaAgentConfigResolved? = findK8sGrafanaConfig(cli.configFileName)?.resolveSecret()
if (cli.onlyModules == null ) { if (cli.onlyModules == null) {
val k3sConfig: K3sConfig = getK3sConfig(cli.configFileName) val k3sConfig: K3sConfig = getK3sConfig(cli.configFileName)
DefaultConfigFileRepository().assertExists(cli.configFileName) DefaultConfigFileRepository().assertExists(cli.configFileName)
val k3sConfigReprovision = k3sConfig.copy(reprovision = cli.reprovision || k3sConfig.reprovision) val k3sConfigReprovision = k3sConfig.copy(reprovision = cli.reprovision || k3sConfig.reprovision)
val applicationFile = DefaultApplicationFileRepository(cli.applicationFileName).getFile() val applicationFile = cli.applicationFileName?.let { DefaultApplicationFileRepository(cli.applicationFileName).getFile() }
provisionK3s(k3sConfigReprovision, grafanaConfigResolved, applicationFile) provisionK3s(k3sConfigReprovision, grafanaConfigResolved, applicationFile)
} else { } else {
provisionGrafana(cli.onlyModules, grafanaConfigResolved) provisionGrafana(cli.onlyModules, grafanaConfigResolved)
@ -30,7 +30,8 @@ fun Prov.provisionK3sCommand(cli: K3sCliCommand) = task {
fun Prov.provisionK3s( fun Prov.provisionK3s(
k3sConfig: K3sConfig, k3sConfig: K3sConfig,
grafanaConfigResolved: GrafanaAgentConfigResolved? = null, grafanaConfigResolved: GrafanaAgentConfigResolved? = null,
applicationFile: ApplicationFile? = null) = task { applicationFile: ApplicationFile? = null
) = task {
if (k3sConfig.reprovision) { if (k3sConfig.reprovision) {
deprovisionK3sInfra() deprovisionK3sInfra()
@ -56,7 +57,6 @@ fun Prov.provisionK3s(
provisionK3sApplication(applicationFile) provisionK3sApplication(applicationFile)
} }
if (!k3sConfig.reprovision) { if (!k3sConfig.reprovision) {
provisionServerCliConvenience() provisionServerCliConvenience()
} }
@ -64,7 +64,8 @@ fun Prov.provisionK3s(
private fun Prov.provisionGrafana( private fun Prov.provisionGrafana(
onlyModules: List<String>?, onlyModules: List<String>?,
grafanaConfigResolved: GrafanaAgentConfigResolved?) = task { grafanaConfigResolved: GrafanaAgentConfigResolved?
) = task {
if (onlyModules != null && onlyModules.contains(ServerOnlyModule.GRAFANA.name.lowercase())) { if (onlyModules != null && onlyModules.contains(ServerOnlyModule.GRAFANA.name.lowercase())) {
if (grafanaConfigResolved == null) { if (grafanaConfigResolved == null) {

View file

@ -5,22 +5,26 @@ import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.check
import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFile import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFile
import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileName import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileName
import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileRepository import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileRepository
import java.io.File
class DefaultApplicationFileRepository(val applicationFileName: ApplicationFileName?) : ApplicationFileRepository {
private fun assertExists(applicationFileName: String?) { class DefaultApplicationFileRepository(val applicationFileName: ApplicationFileName) : ApplicationFileRepository {
if (applicationFileName != null && !checkLocalFile(applicationFileName)) {
private fun assertExists(applicationFileName: String) {
if (!checkLocalFile(applicationFileName)) {
throw RuntimeException("Application file not found. Please check if path is correct.") throw RuntimeException("Application file not found. Please check if path is correct.")
} }
} }
override fun getFile() : ApplicationFile {
assertExists(applicationFileName!!.fullyQualifiedName()) override fun getFile(): ApplicationFile {
assertExists(applicationFileName.fullyQualifiedName())
val applicationFileContents = getLocalFileContent(applicationFileName.fullyQualifiedName()) val applicationFileContents = getLocalFileContent(applicationFileName.fullyQualifiedName())
val applicationFile = ApplicationFile(applicationFileName, applicationFileContents) val applicationFile = ApplicationFile(applicationFileName, applicationFileContents)
return if (applicationFile.isValid()) { applicationFile } return if (applicationFile.isValid()) {
else { throw RuntimeException("Application file was invalid.") } applicationFile
} else {
throw RuntimeException("Application file was invalid.")
}
} }
} }

View file

@ -22,8 +22,8 @@ private const val k3sResourceDir = "org/domaindrivenarchitecture/provs/server/in
// ----------------------------------- files -------------------------------- // ----------------------------------- files --------------------------------
private val k3sInstallScript = File( "/usr/local/bin/k3s-install.sh") private val k3sInstallScript = File("/usr/local/bin/k3s-install.sh")
private val k3sConfigFile = File( "/etc/rancher/k3s/config.yaml") private val k3sConfigFile = File("/etc/rancher/k3s/config.yaml")
private val k3sKubeConfig = File("/etc/rancher/k3s/k3s.yaml") private val k3sKubeConfig = File("/etc/rancher/k3s/k3s.yaml")
private val k3sTraefikWorkaround = File(k3sManualManifestsDir, "traefik.yaml") private val k3sTraefikWorkaround = File(k3sManualManifestsDir, "traefik.yaml")
@ -75,14 +75,20 @@ fun Prov.installK3s(k3sConfig: K3sConfig): ProvResult {
if (k3sConfig.isDualStack()) { if (k3sConfig.isDualStack()) {
k3sConfigResourceFileName += ".dual.template.yaml" k3sConfigResourceFileName += ".dual.template.yaml"
metallbConfigResourceFileName += ".dual.template.yaml" metallbConfigResourceFileName += ".dual.template.yaml"
k3sConfigMap = k3sConfigMap.plus("node_ipv6" to k3sConfig.node.ipv6!!) require(k3sConfig.node.ipv6 != null && k3sConfig.loopback.ipv6 != null)
.plus("loopback_ipv6" to k3sConfig.loopback.ipv6!!) k3sConfigMap = k3sConfigMap
.plus("node_ipv6" to k3sConfig.node.ipv6)
.plus("loopback_ipv6" to k3sConfig.loopback.ipv6)
} else { } else {
k3sConfigResourceFileName += ".ipv4.template.yaml" k3sConfigResourceFileName += ".ipv4.template.yaml"
metallbConfigResourceFileName += ".ipv4.template.yaml" metallbConfigResourceFileName += ".ipv4.template.yaml"
} }
createK3sFileFromResourceTemplate(k3sConfigFile, k3sConfigMap, alternativeResourceTemplate = File(k3sConfigResourceFileName)) createK3sFileFromResourceTemplate(
k3sConfigFile,
k3sConfigMap,
alternativeResourceTemplate = File(k3sConfigResourceFileName)
)
createK3sFileFromResource(k3sInstallScript, posixFilePermission = "755") createK3sFileFromResource(k3sInstallScript, posixFilePermission = "755")
cmd("INSTALL_K3S_VERSION=$K3S_VERSION k3s-install.sh") cmd("INSTALL_K3S_VERSION=$K3S_VERSION k3s-install.sh")
@ -217,5 +223,5 @@ private fun File.templateName(): String {
} }
internal fun Prov.configureShellAliases() = task { internal fun Prov.configureShellAliases() = task {
addTextToFile( "\nalias k=\"sudo kubectl\"\n", File(".bash_aliases",)) addTextToFile("\nalias k=\"sudo kubectl\"\n", File(".bash_aliases"))
} }

View file

@ -16,11 +16,12 @@ fun Prov.testNetworkExists(): Boolean {
fun Prov.provisionNetwork(k3sConfig: K3sConfig) = task { fun Prov.provisionNetwork(k3sConfig: K3sConfig) = task {
if(!testNetworkExists()) { if(!testNetworkExists()) {
if(k3sConfig.isDualStack()) { if(k3sConfig.isDualStack()) {
require(k3sConfig.loopback.ipv6 != null)
createFileFromResourceTemplate( createFileFromResourceTemplate(
loopbackFile, loopbackFile,
"99-loopback.dual.template.yaml", "99-loopback.dual.template.yaml",
resourcePathNetwork, resourcePathNetwork,
mapOf("loopback_ipv4" to k3sConfig.loopback.ipv4, "loopback_ipv6" to k3sConfig.loopback.ipv6!!), mapOf("loopback_ipv4" to k3sConfig.loopback.ipv4, "loopback_ipv6" to k3sConfig.loopback.ipv6),
"644", "644",
sudo = true sudo = true
) )

View file

@ -1,7 +1,6 @@
package org.domaindrivenarchitecture.provs.server.application package org.domaindrivenarchitecture.provs.server.application
import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand
import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFile
import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileName import org.domaindrivenarchitecture.provs.server.domain.k3s.ApplicationFileName
import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sCliCommand import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sCliCommand
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
@ -46,7 +45,7 @@ internal class CliArgumentParserTest {
// then // then
assertTrue(result.isValidTarget()) assertTrue(result.isValidTarget())
assertEquals(ApplicationFileName("app.yaml").fullyQualifiedName(), result.applicationFileName!!.fullyQualifiedName()) assertEquals(ApplicationFileName("app.yaml").fullyQualifiedName(), result.applicationFileName?.fullyQualifiedName())
assertEquals(TargetCliCommand("user@host.com"), result.target) assertEquals(TargetCliCommand("user@host.com"), result.target)
} }
} }