diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sCustomResourceWrapper.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sCustomResourceWrapper.kt new file mode 100644 index 0000000000000000000000000000000000000000..a20018dd4ec050a6a20adde3f0e4d5b595a61585 --- /dev/null +++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sCustomResourceWrapper.kt @@ -0,0 +1,34 @@ +package theodolite.k8s + +import io.fabric8.kubernetes.client.CustomResource +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext + +class K8sCustomResourceWrapper(private val map : Map<String,String>) : CustomResource() { + + + fun deploy(client : NamespacedKubernetesClient){ + val kind = this.map["kind"] + val crds = client.apiextensions().v1beta1().customResourceDefinitions().list() + crds.items + .filter { crd -> crd.toString().contains("kind=$kind") } + .map { crd -> CustomResourceDefinitionContext.fromCrd(crd) } + .forEach { context -> + client.customResource(context).createOrReplace(client.configuration.namespace,this.map as Map<String, Any>) + } + } + + fun delete(client : NamespacedKubernetesClient){ + val kind = this.map["kind"] + val metadata = this.map["metadata"] as HashMap<String,String> + val name = metadata["name"] + + val crds = client.apiextensions().v1beta1().customResourceDefinitions().list() + crds.items + .filter { crd -> crd.toString().contains("kind=$kind") } + .map { crd -> CustomResourceDefinitionContext.fromCrd(crd) } + .forEach { context -> + client.customResource(context).delete(client.configuration.namespace,name) } + } + +} \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt index 2a50db23f158b74a65bc7af0690c325c198550e6..38a07545513d7713f61e484702cb48143ab3aed0 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt @@ -3,7 +3,6 @@ package theodolite.k8s import io.fabric8.kubernetes.api.model.ConfigMap import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.Service -import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.StatefulSet import io.fabric8.kubernetes.client.NamespacedKubernetesClient @@ -20,8 +19,7 @@ class K8sManager(private val client: NamespacedKubernetesClient) { this.client.configMaps().createOrReplace(resource) is StatefulSet -> this.client.apps().statefulSets().createOrReplace(resource) - is CustomResourceDefinition -> - this.client.customResourceDefinitions().createOrReplace(resource) + is K8sCustomResourceWrapper -> resource.deploy(client) else -> throw IllegalArgumentException("Unknown Kubernetes resource.") } } @@ -36,8 +34,7 @@ class K8sManager(private val client: NamespacedKubernetesClient) { this.client.configMaps().delete(resource) is StatefulSet -> this.client.apps().statefulSets().delete(resource) - is CustomResourceDefinition -> - this.client.customResourceDefinitions().delete(resource) + is K8sCustomResourceWrapper -> resource.delete(client) else -> throw IllegalArgumentException("Unknown Kubernetes resource.") } } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt index dbc31de96df4d1a4a48347c5f33853c0c98e1f95..658af46611ec7e1e784d286391ecf1e25a25366e 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt @@ -3,10 +3,10 @@ package theodolite.k8s import io.fabric8.kubernetes.api.model.ConfigMap import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.Service -import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.client.NamespacedKubernetesClient import mu.KotlinLogging +import theodolite.util.YamlParser private val logger = KotlinLogging.logger {} @@ -22,12 +22,12 @@ class K8sResourceLoader(private val client: NamespacedKubernetesClient) { } /** - * Parses a Service from a service yaml + * Parses a CustomResource from a yaml * @param path of the yaml file - * @return service from fabric8 + * @return customResource from fabric8 */ - private fun loadServiceMonitor(path: String): CustomResourceDefinition { - return loadGenericResource(path) { x: String -> client.customResourceDefinitions().load(x).get() } + fun loadCustomResource(path: String): K8sCustomResourceWrapper { + return loadGenericResource(path) { x: String -> K8sCustomResourceWrapper(YamlParser().parse(path, HashMap<String, String>()::class.java)!!) } } /** @@ -73,9 +73,17 @@ class K8sResourceLoader(private val client: NamespacedKubernetesClient) { return when (kind) { "Deployment" -> loadDeployment(path) "Service" -> loadService(path) - "ServiceMonitor" -> loadServiceMonitor(path) + "ServiceMonitor" -> loadCustomResource(path) "ConfigMap" -> loadConfigmap(path) - else -> throw IllegalArgumentException("Unknown resource with type $kind located in $path") + else -> { + logger.warn { "Try to load $kind from $path as Custom ressource" } + try{ + loadCustomResource(path) + } catch (e:Exception){ + logger.error { "Error during loading of unspecified CustomResource: $e" } + throw e + } + } } } } diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/CustomRessourceTest.kt b/theodolite-quarkus/src/test/kotlin/theodolite/CustomRessourceTest.kt deleted file mode 100644 index b3ea2c01feaef6a274dbc3bb9656f50db34d2355..0000000000000000000000000000000000000000 --- a/theodolite-quarkus/src/test/kotlin/theodolite/CustomRessourceTest.kt +++ /dev/null @@ -1,104 +0,0 @@ -package theodolite - -import io.fabric8.kubernetes.client.DefaultKubernetesClient -import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext -import io.quarkus.test.junit.QuarkusTest -import io.smallrye.common.constraint.Assert.assertTrue -import org.junit.jupiter.api.Test -import theodolite.k8s.K8sResourceLoader -import io.fabric8.kubernetes.api.model.ObjectMeta -import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition -import io.fabric8.kubernetes.client.CustomResource -import io.fabric8.kubernetes.api.model.HasMetadata - -import io.fabric8.kubernetes.internal.KubernetesDeserializer -import theodolite.util.YamlParser -import java.io.File -import java.io.IOException -import javax.json.Json - - -@QuarkusTest -class CustomRessourceTest { - - val client = DefaultKubernetesClient() - val loader = K8sResourceLoader(client) - val path = "./src/main/resources/yaml/" - - @Test - fun aids(){ - val crd = loader.loadK8sResource("ServiceMonitor", path + "uc1-service-monitor.yaml") - - - val crds = client.apiextensions().v1beta1().customResourceDefinitions().list() - - println(crd.toString()) -// val context = CustomResourceDefinitionContext.Builder().build() - //.withGroup() - //.withScope() - //.withPlural() - //.withKind("ServiceMonitor").build() - //.withName("kafka") -// -// println(client.customResource(context).list("default")) -// -// client.customResource(context).create(crd.toString()) - - val crdsItems = crds.getItems() - println("Found ${crdsItems.size} CRD(s)") - var dummy: CustomResourceDefinition? = null - val dummyCRDName: String = "servicemonitors.monitoring.coreos.com" - for (crd in crdsItems) { - val metadata: ObjectMeta = crd.getMetadata() - if (metadata != null) { - val name = metadata.name - //println(" " + name + " => " + metadata.selfLink) - if (dummyCRDName.equals(name)) { - dummy = crd; - println("dummy found") - } - } - - } - val context = CustomResourceDefinitionContext.fromCrd(dummy) - - val customclient = client.customResource(context) - - println(customclient.list()) - val f = File(path + "uc1-service-monitor.yaml") - - - val customr = customclient.load(f.inputStream()) - println("Customressource: $customr") - - println("Dummy: $dummy") - - customclient.create(customr) - - } - - //@Test - fun loadTest(){ - val crd = loader.loadK8sResource("ServiceMonitor", path + "uc1-service-monitor.yaml") - - println(crd) - } - - @Test - fun testTypelessAPI() { - try { - DefaultKubernetesClient().use { client -> - val svmAsMap = YamlParser().parse(path + "uc1-service-monitor.yaml", HashMap<String, String>()::class.java) - val kind = svmAsMap?.get("kind") - val crds = client.apiextensions().v1beta1().customResourceDefinitions().list() - crds.items - .filter { crd -> crd.toString().contains("kind=$kind") } // the filtered list should contain exactly 1 element, iff the CRD is known. TODO("Check if there is a case in which the list contains more than 1 element") - .map { crd -> CustomResourceDefinitionContext.fromCrd(crd)} - .forEach {context -> client.customResource(context).createOrReplace("default", svmAsMap as Map<String, Any>?)} - - } - } catch (e: IOException) { - e.printStackTrace() - } - } -} \ No newline at end of file