2121package eu.openanalytics.shinyproxyoperator.components
2222
2323import com.fasterxml.jackson.databind.ObjectMapper
24+ import com.fasterxml.jackson.databind.module.SimpleModule
2425import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
2526import com.fasterxml.jackson.datatype.jsr353.JSR353Module
26- import io.fabric8.kubernetes.api.model.HTTPGetAction
27+ import eu.openanalytics.shinyproxyoperator.IntOrStringDeserializer
2728import io.fabric8.kubernetes.api.model.IntOrString
2829import io.fabric8.kubernetes.api.model.PodTemplateSpec
30+ import io.fabric8.kubernetes.api.model.Service
31+ import io.fabric8.kubernetes.api.model.networking.v1.Ingress
2932import mu.KotlinLogging
3033import javax.json.JsonPatch
3134import javax.json.JsonStructure
3235
33- class PodTemplateSpecPatcher {
36+
37+ class Patcher {
3438 private val mapper = ObjectMapper (YAMLFactory ())
3539 private val logger = KotlinLogging .logger { }
3640
3741 init {
3842 mapper.registerModule(JSR353Module ())
43+ val module = SimpleModule ()
44+ module.addDeserializer(IntOrString ::class .java, IntOrStringDeserializer ())
45+ mapper.registerModule(module)
46+ }
47+
48+ /* *
49+ * Applies a JsonPatch to the given Service.
50+ */
51+ fun patch (service : Service , patch : JsonPatch ? ): Service {
52+ if (patch == null ) {
53+ return service
54+ }
55+
56+ logger.debug { " Original Service (before applying patches): ${mapper.writeValueAsString(service)} " }
57+
58+ // 1. convert Service to javax.json.JsonValue object.
59+ // This conversion does not actually convert to a string, but some internal
60+ // representation of Jackson.
61+ val podAsJsonValue: JsonStructure = mapper.convertValue(service, JsonStructure ::class .java)
62+ // 2. apply patch
63+ val patchedAsJsonValue: JsonStructure = patch.apply (podAsJsonValue)
64+ // 3. convert back to a Service
65+ val patchedService = mapper.convertValue(patchedAsJsonValue, Service ::class .java)
66+
67+ logger.debug { " Patched Service (after applying patches): ${mapper.writeValueAsString(patchedService)} " }
68+
69+ return patchedService
70+ }
71+
72+ /* *
73+ * Applies a JsonPatch to the given Ingress.
74+ */
75+ fun patch (ingress : Ingress , patch : JsonPatch ? ): Ingress {
76+ if (patch == null ) {
77+ return ingress
78+ }
79+
80+ logger.debug { " Original Ingress (before applying patches): ${mapper.writeValueAsString(ingress)} " }
81+
82+ // 1. convert PodTemplate to javax.json.JsonValue object.
83+ // This conversion does not actually convert to a string, but some internal
84+ // representation of Jackson.
85+ val podAsJsonValue: JsonStructure = mapper.convertValue(ingress, JsonStructure ::class .java)
86+ // 2. apply patch
87+ val patchedAsJsonValue: JsonStructure = patch.apply (podAsJsonValue)
88+ // 3. convert back to a PodTemplate
89+ val patchedIngress = mapper.convertValue(patchedAsJsonValue, Ingress ::class .java)
90+
91+ logger.debug { " Patched Ingress (after applying patches): ${mapper.writeValueAsString(patchedIngress)} " }
92+
93+ return patchedIngress
3994 }
4095
4196 /* *
@@ -57,24 +112,9 @@ class PodTemplateSpecPatcher {
57112 // 3. convert back to a PodTemplate
58113 val patchedPodTemplateSpec = mapper.convertValue(patchedPodAsJsonValue, PodTemplateSpec ::class .java)
59114
60- for (container in patchedPodTemplateSpec.spec.containers) {
61- container.livenessProbe?.httpGet?.let { patchHttpGet(it) }
62- container.readinessProbe?.httpGet?.let { patchHttpGet(it) }
63- container.startupProbe?.httpGet?.let { patchHttpGet(it) }
64- }
65-
66115 logger.debug { " Patched PodTemplateSpec (after applying patches): ${mapper.writeValueAsString(patchedPodTemplateSpec)} " }
67116
68117 return patchedPodTemplateSpec
69118 }
70119
71- private fun patchHttpGet (httpGet : HTTPGetAction ) {
72- if (httpGet.port.intVal == null ) {
73- val asInt = httpGet.port.strVal.toIntOrNull()
74- if (asInt != null ) {
75- httpGet.port = IntOrString (asInt)
76- }
77- }
78- }
79-
80120}
0 commit comments