non-strict parse of configs

This commit is contained in:
zwa 2022-02-06 20:30:53 +01:00
parent 0178a09b80
commit 3bf2015716
9 changed files with 67 additions and 67 deletions

View file

@ -1,11 +1,9 @@
package org.domaindrivenarchitecture.provs.desktop.infrastructure package org.domaindrivenarchitecture.provs.desktop.infrastructure
import com.charleskorn.kaml.Yaml import com.charleskorn.kaml.Yaml
import kotlinx.serialization.json.Json
import org.domaindrivenarchitecture.provs.framework.core.tags.Api
import org.domaindrivenarchitecture.provs.desktop.domain.DesktopConfig import org.domaindrivenarchitecture.provs.desktop.domain.DesktopConfig
import java.io.BufferedReader import org.domaindrivenarchitecture.provs.framework.core.readFromFile
import java.io.FileReader import org.domaindrivenarchitecture.provs.framework.core.yamlToType
import java.io.FileWriter import java.io.FileWriter
@ -14,32 +12,19 @@ import java.io.FileWriter
* Throws exceptions FileNotFoundException, SerializationException if file is not found resp. cannot be parsed. * Throws exceptions FileNotFoundException, SerializationException if file is not found resp. cannot be parsed.
*/ */
internal fun getConfig(filename: String = "WorkplaceConfig.yaml"): DesktopConfig { internal fun getConfig(filename: String = "WorkplaceConfig.yaml"): DesktopConfig {
return readFromFile(filename).yamlToType<DesktopConfig>()
// read file
val inputAsString = BufferedReader(FileReader(filename)).use { it.readText() }
// deserializing
val config =
if (filename.lowercase().endsWith(".yaml")) {
Yaml.default.decodeFromString(DesktopConfig.serializer(), inputAsString)
} else {
Json.decodeFromString(DesktopConfig.serializer(), inputAsString)
}
return config
} }
@Api
@Suppress("unused")
internal fun writeConfig(config: DesktopConfig, fileName: String = "WorkplaceConfigExample.yaml") { internal fun writeConfig(config: DesktopConfig, fileName: String = "WorkplaceConfigExample.yaml") {
if (fileName.lowercase().endsWith(".yaml")) { FileWriter(fileName).use {
FileWriter(fileName).use { it.write(
it.write( Yaml.default.encodeToString(
Yaml.default.encodeToString( DesktopConfig.serializer(),
DesktopConfig.serializer(), config
config
)
) )
} )
} else {
FileWriter(fileName).use { it.write(Json.encodeToString(DesktopConfig.serializer(), config)) }
} }
} }

View file

@ -0,0 +1,20 @@
package org.domaindrivenarchitecture.provs.framework.core
import com.charleskorn.kaml.Yaml
import com.charleskorn.kaml.YamlConfiguration
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.serializer
import java.io.BufferedReader
import java.io.FileReader
fun readFromFile(fileName: String): String {
return BufferedReader(FileReader(fileName)).use { it.readText() }
}
@OptIn(InternalSerializationApi::class)
inline fun <reified T : Any> String.yamlToType() = Yaml(configuration = YamlConfiguration(strictMode = false)).decodeFromString(
T::class.serializer(),
this
)

View file

@ -8,11 +8,9 @@ import org.domaindrivenarchitecture.provs.server.infrastructure.k3s.getK3sConfig
/** /**
* Installs a k3s server. * Installs a k3s server.
* If docker is true, then docker will be installed (may conflict if docker is already existing) and k3s will be installed with docker option.
* If tlsHost is specified, then tls (if configured) also applies to the specified host.
*/ */
fun Prov.provisionK3s(configFileName: ConfigFileName?) = task { fun Prov.provisionK3s(configFileName: ConfigFileName?) = task {
val k3sConfig: K3sConfig = getK3sConfig(configFileName!!) val k3sConfig: K3sConfig = getK3sConfig(configFileName)
provisionNetwork(k3sConfig) provisionNetwork(k3sConfig)
if (k3sConfig.reprovision && testConfigExists()) { if (k3sConfig.reprovision && testConfigExists()) {

View file

@ -1,23 +1,14 @@
package org.domaindrivenarchitecture.provs.server.infrastructure.k3s package org.domaindrivenarchitecture.provs.server.infrastructure.k3s
import com.charleskorn.kaml.Yaml
import kotlinx.serialization.json.Json
import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName
import org.domaindrivenarchitecture.provs.server.domain.k3s.* import org.domaindrivenarchitecture.provs.framework.core.readFromFile
import java.io.BufferedReader import org.domaindrivenarchitecture.provs.framework.core.yamlToType
import java.io.FileReader import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sConfig
public fun getK3sConfig(configFileName: ConfigFileName): K3sConfig { private const val DEFAULT_CONFIG_FILE = "ServerConfig.yaml"
// read file
val inputAsString = BufferedReader(FileReader(configFileName.fileName)).use { it.readText() }
// deserializing fun getK3sConfig(fileName: ConfigFileName?): K3sConfig {
val config = return readFromFile(fileName?.fileName ?: DEFAULT_CONFIG_FILE).yamlToType()
if (configFileName.fileName.lowercase().endsWith(".yaml")) {
Yaml.default.decodeFromString(K3sConfig.serializer(), inputAsString)
} else {
Json.decodeFromString(K3sConfig.serializer(), inputAsString)
}
return config
} }

View file

@ -1,12 +1,11 @@
package org.domaindrivenarchitecture.provs.framework.core.cli package org.domaindrivenarchitecture.provs.cofiguration.domain
import io.mockk.every import io.mockk.*
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import io.mockk.verify
import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand
import org.domaindrivenarchitecture.provs.framework.core.Prov import org.domaindrivenarchitecture.provs.framework.core.Prov
import org.domaindrivenarchitecture.provs.framework.core.Secret import org.domaindrivenarchitecture.provs.framework.core.Secret
import org.domaindrivenarchitecture.provs.framework.core.cli.createProvInstance
import org.domaindrivenarchitecture.provs.framework.core.cli.retrievePassword
import org.domaindrivenarchitecture.provs.framework.core.local import org.domaindrivenarchitecture.provs.framework.core.local
import org.domaindrivenarchitecture.provs.framework.core.processors.PrintOnlyProcessor import org.domaindrivenarchitecture.provs.framework.core.processors.PrintOnlyProcessor
import org.domaindrivenarchitecture.provs.framework.core.remote import org.domaindrivenarchitecture.provs.framework.core.remote
@ -20,6 +19,7 @@ internal class CliTargetCommandKtTest {
@BeforeAll @BeforeAll
@JvmStatic @JvmStatic
internal fun beforeAll() { internal fun beforeAll() {
mockkObject(Prov)
mockkStatic(::local) mockkStatic(::local)
mockkStatic(::remote) mockkStatic(::remote)
every { remote(any(), any(), any(), any()) } returns Prov.newInstance(PrintOnlyProcessor()) every { remote(any(), any(), any(), any()) } returns Prov.newInstance(PrintOnlyProcessor())
@ -31,6 +31,7 @@ internal class CliTargetCommandKtTest {
@AfterAll @AfterAll
@JvmStatic @JvmStatic
internal fun afterAll() { internal fun afterAll() {
unmockkObject(Prov)
unmockkStatic(::local) unmockkStatic(::local)
unmockkStatic(::remote) unmockkStatic(::remote)
unmockkStatic(::retrievePassword) unmockkStatic(::retrievePassword)

View file

@ -1,8 +1,10 @@
package org.domaindrivenarchitecture.provs.desktop.infrastructure package org.domaindrivenarchitecture.provs.desktop.infrastructure
import com.charleskorn.kaml.InvalidPropertyValueException import com.charleskorn.kaml.InvalidPropertyValueException
import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName
import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.SecretSourceType import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.SecretSourceType
import org.domaindrivenarchitecture.provs.desktop.domain.WorkplaceType import org.domaindrivenarchitecture.provs.desktop.domain.WorkplaceType
import org.domaindrivenarchitecture.provs.server.infrastructure.k3s.getK3sConfig
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
import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.assertThrows
@ -31,17 +33,17 @@ internal class ConfigRepositoryKtTest {
@Test @Test
fun getConfig_fails_due_to_invalidProperty() { fun getConfig_fails_due_to_invalidProperty() {
assertThrows<InvalidPropertyValueException> { val exception = assertThrows<InvalidPropertyValueException> {
getConfig("src/test/resources/InvalidWorkplaceConfig.yaml") getConfig("src/test/resources/InvalidWorkplaceConfig.yaml")
} }
assertEquals("Value for 'type' is invalid: Value 'WRONGTYPE' is not a valid option, permitted choices are: IDE, MINIMAL, OFFICE", exception.message)
} }
@Test @Test
fun getConfig_fails_due_to_non_existing_file() { fun getConfig_fails_due_to_missing_file() {
assertThrows<FileNotFoundException> { val exception = assertThrows<FileNotFoundException> {
getConfig("src/test/resources/Idonotexist.yaml") getK3sConfig(ConfigFileName("src/test/resources/Idonotexist.yaml"))
} }
assertEquals("src/test/resources/Idonotexist.yaml (No such file or directory)", exception.message)
} }
} }

View file

@ -1,9 +1,12 @@
package org.domaindrivenarchitecture.provs.server.infrastructure.k3s package org.domaindrivenarchitecture.provs.server.infrastructure.k3s
import com.charleskorn.kaml.UnknownPropertyException import kotlinx.serialization.SerializationException
import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName
import org.domaindrivenarchitecture.provs.server.domain.k3s.*
import org.domaindrivenarchitecture.provs.server.domain.CertmanagerEndpoint import org.domaindrivenarchitecture.provs.server.domain.CertmanagerEndpoint
import org.domaindrivenarchitecture.provs.server.domain.k3s.Certmanager
import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sConfig
import org.domaindrivenarchitecture.provs.server.domain.k3s.Loopback
import org.domaindrivenarchitecture.provs.server.domain.k3s.Node
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
import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.assertThrows
@ -33,18 +36,18 @@ internal class ConfigRepositoryTest {
} }
@Test @Test
fun getConfig_fails_due_to_invalidProperty() { fun getConfig_fails_due_to_missing_property() {
assertThrows<UnknownPropertyException> { val exception = assertThrows<SerializationException> {
getK3sConfig(ConfigFileName("src/test/resources/InvalidWorkplaceConfig.yaml")) getK3sConfig(ConfigFileName("src/test/resources/InvalidWorkplaceConfig.yaml"))
} }
assertEquals("Fields [fqdn, node] are required for type with serial name 'org.domaindrivenarchitecture.provs.server.domain.k3s.K3sConfig', but they were missing", exception.message)
} }
@Test @Test
fun getConfig_fails_due_to_non_existing_file() { fun getConfig_fails_due_to_missing_file() {
assertThrows<FileNotFoundException> { val exception = assertThrows<FileNotFoundException> {
getK3sConfig(ConfigFileName("src/test/resources/Idonotexist.yaml")) getK3sConfig(ConfigFileName("src/test/resources/Idonotexist.yaml"))
} }
assertEquals("src/test/resources/Idonotexist.yaml (No such file or directory)", exception.message)
} }
} }

View file

@ -0,0 +1 @@
wrongfield: 123

View file

@ -1,2 +1 @@
type: WRONGTYPE # IDE, OFFICE or MINIMAL type: WRONGTYPE # IDE, OFFICE or MINIMAL
nonexistingkey: foo