From 3bf20157162f9c670a4b0932e6eb0ba63d7e1789 Mon Sep 17 00:00:00 2001 From: zwa Date: Sun, 6 Feb 2022 20:30:53 +0100 Subject: [PATCH] non-strict parse of configs --- .../infrastructure/ConfigRepository.kt | 39 ++++++------------- .../provs/framework/core/YamlUtils.kt | 20 ++++++++++ .../provs/server/domain/k3s/K3sService.kt | 4 +- .../infrastructure/k3s/ConfigRepository.kt | 25 ++++-------- .../domain/CliTargetCommandTest.kt | 11 +++--- .../infrastructure/ConfigRepositoryKtTest.kt | 14 ++++--- .../k3s/ConfigRepositoryTest.kt | 19 +++++---- src/test/resources/InvalidServerConfig.yaml | 1 + .../resources/InvalidWorkplaceConfig.yaml | 1 - 9 files changed, 67 insertions(+), 67 deletions(-) create mode 100644 src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/YamlUtils.kt create mode 100644 src/test/resources/InvalidServerConfig.yaml diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepository.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepository.kt index f7f977a..ab3964a 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepository.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepository.kt @@ -1,11 +1,9 @@ package org.domaindrivenarchitecture.provs.desktop.infrastructure 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 java.io.BufferedReader -import java.io.FileReader +import org.domaindrivenarchitecture.provs.framework.core.readFromFile +import org.domaindrivenarchitecture.provs.framework.core.yamlToType 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. */ internal fun getConfig(filename: String = "WorkplaceConfig.yaml"): 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 + return readFromFile(filename).yamlToType() } -@Api + +@Suppress("unused") internal fun writeConfig(config: DesktopConfig, fileName: String = "WorkplaceConfigExample.yaml") { - if (fileName.lowercase().endsWith(".yaml")) { - FileWriter(fileName).use { - it.write( - Yaml.default.encodeToString( - DesktopConfig.serializer(), - config - ) + FileWriter(fileName).use { + it.write( + Yaml.default.encodeToString( + DesktopConfig.serializer(), + config ) - } - } else { - FileWriter(fileName).use { it.write(Json.encodeToString(DesktopConfig.serializer(), config)) } + ) } + } \ No newline at end of file diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/YamlUtils.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/YamlUtils.kt new file mode 100644 index 0000000..94c8956 --- /dev/null +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/core/YamlUtils.kt @@ -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 String.yamlToType() = Yaml(configuration = YamlConfiguration(strictMode = false)).decodeFromString( + T::class.serializer(), + this +) diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/server/domain/k3s/K3sService.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/server/domain/k3s/K3sService.kt index 2e2eaef..d615589 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/server/domain/k3s/K3sService.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/server/domain/k3s/K3sService.kt @@ -8,11 +8,9 @@ import org.domaindrivenarchitecture.provs.server.infrastructure.k3s.getK3sConfig /** * 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 { - val k3sConfig: K3sConfig = getK3sConfig(configFileName!!) + val k3sConfig: K3sConfig = getK3sConfig(configFileName) provisionNetwork(k3sConfig) if (k3sConfig.reprovision && testConfigExists()) { diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepository.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepository.kt index 3f2b96b..c164a88 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepository.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepository.kt @@ -1,23 +1,14 @@ 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.server.domain.k3s.* -import java.io.BufferedReader -import java.io.FileReader +import org.domaindrivenarchitecture.provs.framework.core.readFromFile +import org.domaindrivenarchitecture.provs.framework.core.yamlToType +import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sConfig -public fun getK3sConfig(configFileName: ConfigFileName): K3sConfig { - // read file - val inputAsString = BufferedReader(FileReader(configFileName.fileName)).use { it.readText() } +private const val DEFAULT_CONFIG_FILE = "ServerConfig.yaml" + +fun getK3sConfig(fileName: ConfigFileName?): K3sConfig { + return readFromFile(fileName?.fileName ?: DEFAULT_CONFIG_FILE).yamlToType() +} - // deserializing - val config = - if (configFileName.fileName.lowercase().endsWith(".yaml")) { - Yaml.default.decodeFromString(K3sConfig.serializer(), inputAsString) - } else { - Json.decodeFromString(K3sConfig.serializer(), inputAsString) - } - return config -} \ No newline at end of file diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/cofiguration/domain/CliTargetCommandTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/cofiguration/domain/CliTargetCommandTest.kt index ce02da9..2fb9e4b 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/cofiguration/domain/CliTargetCommandTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/cofiguration/domain/CliTargetCommandTest.kt @@ -1,12 +1,11 @@ -package org.domaindrivenarchitecture.provs.framework.core.cli +package org.domaindrivenarchitecture.provs.cofiguration.domain -import io.mockk.every -import io.mockk.mockkStatic -import io.mockk.unmockkStatic -import io.mockk.verify +import io.mockk.* import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand import org.domaindrivenarchitecture.provs.framework.core.Prov 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.processors.PrintOnlyProcessor import org.domaindrivenarchitecture.provs.framework.core.remote @@ -20,6 +19,7 @@ internal class CliTargetCommandKtTest { @BeforeAll @JvmStatic internal fun beforeAll() { + mockkObject(Prov) mockkStatic(::local) mockkStatic(::remote) every { remote(any(), any(), any(), any()) } returns Prov.newInstance(PrintOnlyProcessor()) @@ -31,6 +31,7 @@ internal class CliTargetCommandKtTest { @AfterAll @JvmStatic internal fun afterAll() { + unmockkObject(Prov) unmockkStatic(::local) unmockkStatic(::remote) unmockkStatic(::retrievePassword) diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepositoryKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepositoryKtTest.kt index 6817a60..acd2d72 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepositoryKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/ConfigRepositoryKtTest.kt @@ -1,8 +1,10 @@ package org.domaindrivenarchitecture.provs.desktop.infrastructure import com.charleskorn.kaml.InvalidPropertyValueException +import org.domaindrivenarchitecture.provs.configuration.domain.ConfigFileName import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.SecretSourceType 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.Test import org.junit.jupiter.api.assertThrows @@ -31,17 +33,17 @@ internal class ConfigRepositoryKtTest { @Test fun getConfig_fails_due_to_invalidProperty() { - assertThrows { + val exception = assertThrows { 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 - fun getConfig_fails_due_to_non_existing_file() { - assertThrows { - getConfig("src/test/resources/Idonotexist.yaml") + fun getConfig_fails_due_to_missing_file() { + val exception = assertThrows { + getK3sConfig(ConfigFileName("src/test/resources/Idonotexist.yaml")) } - + assertEquals("src/test/resources/Idonotexist.yaml (No such file or directory)", exception.message) } } \ No newline at end of file diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepositoryTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepositoryTest.kt index 11fb0b4..9e1f943 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepositoryTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/ConfigRepositoryTest.kt @@ -1,9 +1,12 @@ 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.server.domain.k3s.* 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.Test import org.junit.jupiter.api.assertThrows @@ -33,18 +36,18 @@ internal class ConfigRepositoryTest { } @Test - fun getConfig_fails_due_to_invalidProperty() { - assertThrows { + fun getConfig_fails_due_to_missing_property() { + val exception = assertThrows { 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 - fun getConfig_fails_due_to_non_existing_file() { - assertThrows { + fun getConfig_fails_due_to_missing_file() { + val exception = assertThrows { getK3sConfig(ConfigFileName("src/test/resources/Idonotexist.yaml")) } - + assertEquals("src/test/resources/Idonotexist.yaml (No such file or directory)", exception.message) } } \ No newline at end of file diff --git a/src/test/resources/InvalidServerConfig.yaml b/src/test/resources/InvalidServerConfig.yaml new file mode 100644 index 0000000..2594264 --- /dev/null +++ b/src/test/resources/InvalidServerConfig.yaml @@ -0,0 +1 @@ +wrongfield: 123 \ No newline at end of file diff --git a/src/test/resources/InvalidWorkplaceConfig.yaml b/src/test/resources/InvalidWorkplaceConfig.yaml index be21c3e..865ae7a 100644 --- a/src/test/resources/InvalidWorkplaceConfig.yaml +++ b/src/test/resources/InvalidWorkplaceConfig.yaml @@ -1,2 +1 @@ type: WRONGTYPE # IDE, OFFICE or MINIMAL -nonexistingkey: foo \ No newline at end of file