Skip to content
Snippets Groups Projects
Commit 0968e10b authored by Benedikt Wetzel's avatar Benedikt Wetzel
Browse files

change patcherDefinition in order to use a map for all configuration params

parent 806191c8
No related branches found
No related tags found
4 merge requests!159Re-implementation of Theodolite with Kotlin/Quarkus,!157Update Graal Image in CI pipeline,!148Make patcher parameters flexible,!83WIP: Re-implementation of Theodolite with Kotlin/Quarkus
Showing
with 123 additions and 70 deletions
...@@ -183,7 +183,7 @@ class TheodoliteController( ...@@ -183,7 +183,7 @@ class TheodoliteController(
val configurationOverride = ConfigurationOverride() val configurationOverride = ConfigurationOverride()
configurationOverride.patcher = PatcherDefinition() configurationOverride.patcher = PatcherDefinition()
configurationOverride.patcher.type = "LabelPatcher" configurationOverride.patcher.type = "LabelPatcher"
configurationOverride.patcher.variableName = labelName configurationOverride.patcher.config = mutableListOf(hashMapOf("key" to "variableName", "value" to labelName))
configurationOverride.patcher.resource = it configurationOverride.patcher.resource = it
configurationOverride.value = labelValue configurationOverride.value = labelValue
additionalConfigOverrides.add(configurationOverride) additionalConfigOverrides.add(configurationOverride)
......
...@@ -20,7 +20,5 @@ import io.fabric8.kubernetes.api.model.KubernetesResource ...@@ -20,7 +20,5 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
* *
*/ */
abstract class AbstractPatcher( abstract class AbstractPatcher(
k8sResource: KubernetesResource, k8sResource: KubernetesResource
container: String? = null,
variableName: String? = null
) : Patcher ) : Patcher
...@@ -16,7 +16,7 @@ class EnvVarPatcher( ...@@ -16,7 +16,7 @@ class EnvVarPatcher(
private val k8sResource: KubernetesResource, private val k8sResource: KubernetesResource,
private val container: String, private val container: String,
private val variableName: String private val variableName: String
) : AbstractPatcher(k8sResource, container, variableName) { ) : AbstractPatcher(k8sResource) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
......
...@@ -11,7 +11,7 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet ...@@ -11,7 +11,7 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet
* @param container Container to be patched. * @param container Container to be patched.
*/ */
class ImagePatcher(private val k8sResource: KubernetesResource, private val container: String) : class ImagePatcher(private val k8sResource: KubernetesResource, private val container: String) :
AbstractPatcher(k8sResource, container) { AbstractPatcher(k8sResource) {
override fun <String> patch(imagePath: String) { override fun <String> patch(imagePath: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
......
...@@ -8,10 +8,9 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet ...@@ -8,10 +8,9 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet
import io.fabric8.kubernetes.client.CustomResource import io.fabric8.kubernetes.client.CustomResource
class LabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) : class LabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) :
AbstractPatcher(k8sResource, variableName) { AbstractPatcher(k8sResource) {
override fun <String> patch(labelValue: String) { override fun <String> patch(labelValue: String) {
println("call patcher for resource $k8sResource !")
if(labelValue is kotlin.String){ if(labelValue is kotlin.String){
when(k8sResource){ when(k8sResource){
is Deployment -> { is Deployment -> {
......
...@@ -10,7 +10,7 @@ import io.fabric8.kubernetes.api.model.apps.Deployment ...@@ -10,7 +10,7 @@ import io.fabric8.kubernetes.api.model.apps.Deployment
* @param variableName The `label-key` of the node for which the `label-value` is to be patched. * @param variableName The `label-key` of the node for which the `label-value` is to be patched.
*/ */
class NodeSelectorPatcher(private val k8sResource: KubernetesResource, private val variableName: String) : class NodeSelectorPatcher(private val k8sResource: KubernetesResource, private val variableName: String) :
AbstractPatcher(k8sResource, variableName) { AbstractPatcher(k8sResource) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
k8sResource.spec.template.spec.nodeSelector = mapOf(variableName to value as kotlin.String) k8sResource.spec.template.spec.nodeSelector = mapOf(variableName to value as kotlin.String)
......
...@@ -4,16 +4,17 @@ import io.fabric8.kubernetes.api.model.KubernetesResource ...@@ -4,16 +4,17 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.Deployment
import kotlin.math.pow import kotlin.math.pow
private const val NUM_SENSORS = 4.0 class NumNestedGroupsLoadGeneratorReplicaPatcher(
private const val LOAD_GEN_MAX_RECORDS = 150000 private val k8sResource: KubernetesResource,
private val numSensors: String,
class NumNestedGroupsLoadGeneratorReplicaPatcher(private val k8sResource: KubernetesResource) : private val loadGenMaxRecords: String
) :
AbstractPatcher(k8sResource) { AbstractPatcher(k8sResource) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
if (value is kotlin.String) { if (value is kotlin.String) {
val approxNumSensors = NUM_SENSORS.pow(Integer.parseInt(value).toDouble()) val approxNumSensors = numSensors.toDouble().pow(Integer.parseInt(value).toDouble())
val loadGenInstances = (approxNumSensors + LOAD_GEN_MAX_RECORDS - 1) / LOAD_GEN_MAX_RECORDS val loadGenInstances = (approxNumSensors + loadGenMaxRecords.toDouble() - 1) / loadGenMaxRecords.toDouble()
this.k8sResource.spec.replicas = loadGenInstances.toInt() this.k8sResource.spec.replicas = loadGenInstances.toInt()
} }
} }
......
...@@ -3,14 +3,16 @@ package theodolite.patcher ...@@ -3,14 +3,16 @@ package theodolite.patcher
import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.Deployment
private const val LOAD_GEN_MAX_RECORDS = 150000
class NumSensorsLoadGeneratorReplicaPatcher(private val k8sResource: KubernetesResource) : class NumSensorsLoadGeneratorReplicaPatcher(
private val k8sResource: KubernetesResource,
private val loadGenMaxRecords: String
) :
AbstractPatcher(k8sResource) { AbstractPatcher(k8sResource) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
if (k8sResource is Deployment) { if (k8sResource is Deployment) {
if (value is kotlin.String) { if (value is kotlin.String) {
val loadGenInstances = (Integer.parseInt(value) + LOAD_GEN_MAX_RECORDS - 1) / LOAD_GEN_MAX_RECORDS val loadGenInstances = (Integer.parseInt(value) + loadGenMaxRecords.toInt() - 1) / loadGenMaxRecords.toInt()
this.k8sResource.spec.replicas = loadGenInstances this.k8sResource.spec.replicas = loadGenInstances
} }
} }
......
...@@ -28,27 +28,50 @@ class PatcherFactory { ...@@ -28,27 +28,50 @@ class PatcherFactory {
k8sResources: List<Pair<String, KubernetesResource>> k8sResources: List<Pair<String, KubernetesResource>>
): Patcher { ): Patcher {
val resource = val resource =
k8sResources.filter { it.first == patcherDefinition.resource }.map { resource -> resource.second }.firstOrNull() k8sResources.filter { it.first == patcherDefinition.resource }
.map { resource -> resource.second }
.firstOrNull()
?: throw DeploymentFailedException("Could not find resource ${patcherDefinition.resource}") ?: throw DeploymentFailedException("Could not find resource ${patcherDefinition.resource}")
return when (patcherDefinition.type) { return when (patcherDefinition.type) {
"ReplicaPatcher" -> ReplicaPatcher(resource) "ReplicaPatcher" -> ReplicaPatcher(
"NumNestedGroupsLoadGeneratorReplicaPatcher" -> NumNestedGroupsLoadGeneratorReplicaPatcher(resource) k8sResource = resource
"NumSensorsLoadGeneratorReplicaPatcher" -> NumSensorsLoadGeneratorReplicaPatcher(resource) )
"EnvVarPatcher" -> EnvVarPatcher(resource, patcherDefinition.container, patcherDefinition.variableName) "NumNestedGroupsLoadGeneratorReplicaPatcher" -> NumNestedGroupsLoadGeneratorReplicaPatcher(
"NodeSelectorPatcher" -> NodeSelectorPatcher(resource, patcherDefinition.variableName) k8sResource = resource,
loadGenMaxRecords = patcherDefinition.getValueByKey("loadGenMaxRecords"),
numSensors = patcherDefinition.getValueByKey("numSensors")
)
"NumSensorsLoadGeneratorReplicaPatcher" -> NumSensorsLoadGeneratorReplicaPatcher(
k8sResource = resource,
loadGenMaxRecords = patcherDefinition.getValueByKey("loadGenMaxRecords")
)
"EnvVarPatcher" -> EnvVarPatcher(
k8sResource = resource,
container = patcherDefinition.getValueByKey("container"),
variableName = patcherDefinition.getValueByKey("variableName")
)
"NodeSelectorPatcher" -> NodeSelectorPatcher(
k8sResource = resource,
variableName = patcherDefinition.getValueByKey("variableName"))
"ResourceLimitPatcher" -> ResourceLimitPatcher( "ResourceLimitPatcher" -> ResourceLimitPatcher(
resource, k8sResource = resource,
patcherDefinition.container, container = patcherDefinition.getValueByKey("container"),
patcherDefinition.variableName limitedResource = patcherDefinition.getValueByKey("limitedResource")
) )
"ResourceRequestPatcher" -> ResourceRequestPatcher( "ResourceRequestPatcher" -> ResourceRequestPatcher(
resource, k8sResource = resource,
patcherDefinition.container, container = patcherDefinition.getValueByKey("container"),
patcherDefinition.variableName requestedResource = patcherDefinition.getValueByKey("requestedResource")
)
"SchedulerNamePatcher" -> SchedulerNamePatcher(
k8sResource = resource
)
"LabelPatcher" -> LabelPatcher(
k8sResource = resource,
variableName = patcherDefinition.getValueByKey("variableName")
) )
"SchedulerNamePatcher" -> SchedulerNamePatcher(resource)
"LabelPatcher" -> LabelPatcher(resource, patcherDefinition.variableName)
else -> throw IllegalArgumentException("Patcher type ${patcherDefinition.type} not found") else -> throw IllegalArgumentException("Patcher type ${patcherDefinition.type} not found")
} }
} }
......
...@@ -18,7 +18,7 @@ class ResourceLimitPatcher( ...@@ -18,7 +18,7 @@ class ResourceLimitPatcher(
private val k8sResource: KubernetesResource, private val k8sResource: KubernetesResource,
private val container: String, private val container: String,
private val limitedResource: String private val limitedResource: String
) : AbstractPatcher(k8sResource, container, limitedResource) { ) : AbstractPatcher(k8sResource) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
when (k8sResource) { when (k8sResource) {
......
...@@ -18,7 +18,7 @@ class ResourceRequestPatcher( ...@@ -18,7 +18,7 @@ class ResourceRequestPatcher(
private val k8sResource: KubernetesResource, private val k8sResource: KubernetesResource,
private val container: String, private val container: String,
private val requestedResource: String private val requestedResource: String
) : AbstractPatcher(k8sResource, container, requestedResource) { ) : AbstractPatcher(k8sResource) {
override fun <String> patch(value: String) { override fun <String> patch(value: String) {
when (k8sResource) { when (k8sResource) {
......
package theodolite.util
class InvalidPatcherConfigurationException(message:String): Exception(message) {
}
package theodolite.util package theodolite.util
import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import io.quarkus.runtime.annotations.RegisterForReflection import io.quarkus.runtime.annotations.RegisterForReflection
/** /**
...@@ -19,13 +20,24 @@ class PatcherDefinition { ...@@ -19,13 +20,24 @@ class PatcherDefinition {
*/ */
lateinit var resource: String lateinit var resource: String
/** @JsonSerialize
* The container which the patcher is applied to lateinit var config: MutableList<Map<String, String>>
*/
lateinit var container: String
/** fun getValueByKey(key: String): String {
* The variable name for the patcher val value = this.config
*/ .filter { it["key"] == key }
lateinit var variableName: String .map {
try {
it.getValue("value")
} catch (e: Exception) {
throw InvalidPatcherConfigurationException("No value found for key $key.")
}
}
return when {
value.isEmpty() -> throw InvalidPatcherConfigurationException("Required argument $key missing.")
value.size > 1 -> throw InvalidPatcherConfigurationException("Can not handle duplicate declaration for key $key.")
else -> value.first()
}
}
} }
...@@ -54,10 +54,15 @@ spec: ...@@ -54,10 +54,15 @@ spec:
resource: resource:
type: string type: string
default: "" default: ""
container: config:
type: array
items:
type: object
properties:
key:
type: string type: string
default: "" default: ""
variableName: value:
type: string type: string
default: "" default: ""
loadTypes: loadTypes:
...@@ -80,10 +85,15 @@ spec: ...@@ -80,10 +85,15 @@ spec:
resource: resource:
type: string type: string
default: "" default: ""
container: config:
type: array
items:
type: object
properties:
key:
type: string type: string
default: "" default: ""
variableName: value:
type: string type: string
default: "" default: ""
kafkaConfig: kafkaConfig:
......
...@@ -22,8 +22,11 @@ spec: ...@@ -22,8 +22,11 @@ spec:
patchers: patchers:
- type: "EnvVarPatcher" - type: "EnvVarPatcher"
resource: "uc1-load-generator-deployment.yaml" resource: "uc1-load-generator-deployment.yaml"
container: "workload-generator" config:
variableName: "NUM_SENSORS" - key: container
value: "workload-generator"
- key: variableName
value: "NUM_SENSORS"
kafkaConfig: kafkaConfig:
bootstrapServer: "localhost:31290" bootstrapServer: "localhost:31290"
topics: topics:
......
...@@ -27,15 +27,10 @@ spec: ...@@ -27,15 +27,10 @@ spec:
restrictions: restrictions:
- "LowerBound" - "LowerBound"
configOverrides: configOverrides:
- patcher:
type: "NodeSelectorPatcher"
resource: "uc1-load-generator-deployment.yaml"
container: ""
variableName: "env"
value: "prod"
- patcher: - patcher:
type: "NodeSelectorPatcher" type: "NodeSelectorPatcher"
resource: "uc1-kstreams-deployment.yaml" resource: "uc1-kstreams-deployment.yaml"
container: "" config:
variableName: "env" - key: variableName
value: env
value: "prod" value: "prod"
...@@ -95,10 +95,15 @@ spec: ...@@ -95,10 +95,15 @@ spec:
resource: resource:
type: string type: string
default: "" default: ""
container: config:
type: array
items:
type: object
properties:
key:
type: string type: string
default: "" default: ""
variableName: value:
type: string type: string
default: "" default: ""
value: value:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment