diff --git a/docs/crd-benchmark-doc.md b/docs/crd-benchmark-doc.md deleted file mode 100644 index 1e12d6ebd776b11d76241cfb530daeba9e0b5c24..0000000000000000000000000000000000000000 --- a/docs/crd-benchmark-doc.md +++ /dev/null @@ -1,374 +0,0 @@ -# API Reference - -Packages: - -- [theodolite.com/v1](#theodolitecomv1) - -# theodolite.com/v1 - -Resource Types: - -- [benchmark](#benchmark) - - - - -## benchmark -<sup><sup>[↩ Parent](#theodolitecomv1 )</sup></sup> - - - - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>apiVersion</b></td> - <td>string</td> - <td>theodolite.com/v1</td> - <td>true</td> - </tr> - <tr> - <td><b>kind</b></td> - <td>string</td> - <td>benchmark</td> - <td>true</td> - </tr> - <tr> - <td><b><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#objectmeta-v1-meta">metadata</a></b></td> - <td>object</td> - <td>Refer to the Kubernetes API documentation for the fields of the `metadata` field.</td> - <td>true</td> - </tr><tr> - <td><b><a href="#benchmarkspec">spec</a></b></td> - <td>object</td> - <td> - <br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### benchmark.spec -<sup><sup>[↩ Parent](#benchmark)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>name</b></td> - <td>string</td> - <td> - This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten.<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>appResource</b></td> - <td>[]string</td> - <td> - A list of file names that reference Kubernetes resources that are deployed on the cluster for the system under test (SUT).<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#benchmarkspeckafkaconfig">kafkaConfig</a></b></td> - <td>object</td> - <td> - Contains the Kafka configuration.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>loadGenResource</b></td> - <td>[]string</td> - <td> - A list of file names that reference Kubernetes resources that are deployed on the cluster for the load generator.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#benchmarkspecloadtypesindex">loadTypes</a></b></td> - <td>[]object</td> - <td> - A list of load types that can be scaled for this benchmark. For each load type the concrete values are defined in the execution object.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#benchmarkspecresourcetypesindex">resourceTypes</a></b></td> - <td>[]object</td> - <td> - A list of resource types that can be scaled for this `benchmark` resource. For each resource type the concrete values are defined in the `execution` object.<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### benchmark.spec.kafkaConfig -<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> - - - -Contains the Kafka configuration. - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>bootstrapServer</b></td> - <td>string</td> - <td> - The bootstrap servers connection string.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#benchmarkspeckafkaconfigtopicsindex">topics</a></b></td> - <td>[]object</td> - <td> - List of topics to be created for each experiment. Alternative theodolite offers the possibility to remove certain topics after each experiment.<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### benchmark.spec.kafkaConfig.topics[index] -<sup><sup>[↩ Parent](#benchmarkspeckafkaconfig)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>removeOnly</b></td> - <td>boolean</td> - <td> - Determines if this topic should only be deleted after each experiement. For removeOnly topics the name can be a RegEx describing the topic.<br/> - <br/> - <i>Default</i>: false<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>name</b></td> - <td>string</td> - <td> - The name of the topic.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>true</td> - </tr><tr> - <td><b>numPartitions</b></td> - <td>integer</td> - <td> - The number of partitions of the topic.<br/> - <br/> - <i>Default</i>: 0<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>replicationFactor</b></td> - <td>integer</td> - <td> - The replication factor of the topic.<br/> - <br/> - <i>Default</i>: 0<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### benchmark.spec.loadTypes[index] -<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b><a href="#benchmarkspecloadtypesindexpatchersindex">patchers</a></b></td> - <td>[]object</td> - <td> - List of patchers used to scale this resource type.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>typeName</b></td> - <td>string</td> - <td> - Name of the load type.<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### benchmark.spec.loadTypes[index].patchers[index] -<sup><sup>[↩ Parent](#benchmarkspecloadtypesindex)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>properties</b></td> - <td>object</td> - <td> - (Optional) Patcher specific additional arguments.<br/> - <br/> - <i>Default</i>: map[]<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>resource</b></td> - <td>string</td> - <td> - Specifies the Kubernetes resource to be patched.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>true</td> - </tr><tr> - <td><b>type</b></td> - <td>string</td> - <td> - Type of the Patcher.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### benchmark.spec.resourceTypes[index] -<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b><a href="#benchmarkspecresourcetypesindexpatchersindex">patchers</a></b></td> - <td>[]object</td> - <td> - List of patchers used to scale this resource type.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>typeName</b></td> - <td>string</td> - <td> - Name of the resource type.<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### benchmark.spec.resourceTypes[index].patchers[index] -<sup><sup>[↩ Parent](#benchmarkspecresourcetypesindex)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>properties</b></td> - <td>object</td> - <td> - (Optional) Patcher specific additional arguments.<br/> - <br/> - <i>Default</i>: map[]<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>resource</b></td> - <td>string</td> - <td> - Specifies the Kubernetes resource to be patched.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>true</td> - </tr><tr> - <td><b>type</b></td> - <td>string</td> - <td> - Type of the patcher.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>true</td> - </tr></tbody> -</table> \ No newline at end of file diff --git a/docs/crd-docu.md b/docs/crd-docu.md new file mode 100644 index 0000000000000000000000000000000000000000..4002f9b0ec50bcc64822799a0256b30dd37ac9e4 --- /dev/null +++ b/docs/crd-docu.md @@ -0,0 +1,992 @@ +# API Reference + +Packages: + +- [theodolite.com/v1](#theodolitecomv1) + +# theodolite.com/v1 + +Resource Types: + +- [benchmark](#benchmark) + +- [execution](#execution) + + + + +## benchmark +<sup><sup>[↩ Parent](#theodolitecomv1 )</sup></sup> + + + + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>apiVersion</b></td> + <td>string</td> + <td>theodolite.com/v1</td> + <td>true</td> + </tr> + <tr> + <td><b>kind</b></td> + <td>string</td> + <td>benchmark</td> + <td>true</td> + </tr> + <tr> + <td><b><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#objectmeta-v1-meta">metadata</a></b></td> + <td>object</td> + <td>Refer to the Kubernetes API documentation for the fields of the `metadata` field.</td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspec">spec</a></b></td> + <td>object</td> + <td> + <br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec +<sup><sup>[↩ Parent](#benchmark)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>name</b></td> + <td>string</td> + <td> + This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b><a href="#benchmarkspecappresourcesetsindex">appResourceSets</a></b></td> + <td>[]object</td> + <td> + The appResourceSets specifies all Kubernetes resources required to start the sut. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspeckafkaconfig">kafkaConfig</a></b></td> + <td>object</td> + <td> + Contains the Kafka configuration.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecloadgenresourcesetsindex">loadGenResourceSets</a></b></td> + <td>[]object</td> + <td> + The loadGenResourceSets specifies all Kubernetes resources required to start the load generator. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecloadtypesindex">loadTypes</a></b></td> + <td>[]object</td> + <td> + A list of load types that can be scaled for this benchmark. For each load type the concrete values are defined in the execution object.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecresourcetypesindex">resourceTypes</a></b></td> + <td>[]object</td> + <td> + A list of resource types that can be scaled for this `benchmark` resource. For each resource type the concrete values are defined in the `execution` object.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.appResourceSets[index] +<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecappresourcesetsindexconfigmap">configMap</a></b></td> + <td>object</td> + <td> + The configMap resourceSet loads the Kubernetes manifests from an Kubernetes configMap.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b><a href="#benchmarkspecappresourcesetsindexfilesystem">fileSystem</a></b></td> + <td>object</td> + <td> + The fileSystem resourceSet loads the Kubernetes manifests from the filesystem.<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.appResourceSets[index].configMap +<sup><sup>[↩ Parent](#benchmarkspecappresourcesetsindex)</sup></sup> + + + +The configMap resourceSet loads the Kubernetes manifests from an Kubernetes configMap. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>files</b></td> + <td>[]string</td> + <td> + (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>name</b></td> + <td>string</td> + <td> + The name of the configMap<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.appResourceSets[index].fileSystem +<sup><sup>[↩ Parent](#benchmarkspecappresourcesetsindex)</sup></sup> + + + +The fileSystem resourceSet loads the Kubernetes manifests from the filesystem. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>files</b></td> + <td>[]string</td> + <td> + (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>path</b></td> + <td>string</td> + <td> + The path to the folder which contains the Kubernetes manifests files.<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.kafkaConfig +<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> + + + +Contains the Kafka configuration. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>bootstrapServer</b></td> + <td>string</td> + <td> + The bootstrap servers connection string.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspeckafkaconfigtopicsindex">topics</a></b></td> + <td>[]object</td> + <td> + List of topics to be created for each experiment. Alternative theodolite offers the possibility to remove certain topics after each experiment.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.kafkaConfig.topics[index] +<sup><sup>[↩ Parent](#benchmarkspeckafkaconfig)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>numPartitions</b></td> + <td>integer</td> + <td> + The number of partitions of the topic.<br/> + <br/> + <i>Default</i>: 0<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>removeOnly</b></td> + <td>boolean</td> + <td> + Determines if this topic should only be deleted after each experiement. For removeOnly topics the name can be a RegEx describing the topic.<br/> + <br/> + <i>Default</i>: false<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>replicationFactor</b></td> + <td>integer</td> + <td> + The replication factor of the topic.<br/> + <br/> + <i>Default</i>: 0<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>name</b></td> + <td>string</td> + <td> + The name of the topic.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadGenResourceSets[index] +<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecloadgenresourcesetsindexconfigmap">configMap</a></b></td> + <td>object</td> + <td> + The configMap resourceSet loads the Kubernetes manifests from an Kubernetes configMap.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b><a href="#benchmarkspecloadgenresourcesetsindexfilesystem">fileSystem</a></b></td> + <td>object</td> + <td> + The fileSystem resourceSet loads the Kubernetes manifests from the filesystem.<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadGenResourceSets[index].configMap +<sup><sup>[↩ Parent](#benchmarkspecloadgenresourcesetsindex)</sup></sup> + + + +The configMap resourceSet loads the Kubernetes manifests from an Kubernetes configMap. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>files</b></td> + <td>[]string</td> + <td> + (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>name</b></td> + <td>string</td> + <td> + The name of the configMap<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadGenResourceSets[index].fileSystem +<sup><sup>[↩ Parent](#benchmarkspecloadgenresourcesetsindex)</sup></sup> + + + +The fileSystem resourceSet loads the Kubernetes manifests from the filesystem. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>files</b></td> + <td>[]string</td> + <td> + (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>path</b></td> + <td>string</td> + <td> + The path to the folder which contains the Kubernetes manifests files.<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadTypes[index] +<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecloadtypesindexpatchersindex">patchers</a></b></td> + <td>[]object</td> + <td> + List of patchers used to scale this resource type.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>typeName</b></td> + <td>string</td> + <td> + Name of the load type.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadTypes[index].patchers[index] +<sup><sup>[↩ Parent](#benchmarkspecloadtypesindex)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>properties</b></td> + <td>map[string]string</td> + <td> + (Optional) Patcher specific additional arguments.<br/> + <br/> + <i>Default</i>: map[]<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>resource</b></td> + <td>string</td> + <td> + Specifies the Kubernetes resource to be patched.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>true</td> + </tr><tr> + <td><b>type</b></td> + <td>string</td> + <td> + Type of the Patcher.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.resourceTypes[index] +<sup><sup>[↩ Parent](#benchmarkspec)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecresourcetypesindexpatchersindex">patchers</a></b></td> + <td>[]object</td> + <td> + List of patchers used to scale this resource type.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>typeName</b></td> + <td>string</td> + <td> + Name of the resource type.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.resourceTypes[index].patchers[index] +<sup><sup>[↩ Parent](#benchmarkspecresourcetypesindex)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>properties</b></td> + <td>map[string]string</td> + <td> + (Optional) Patcher specific additional arguments.<br/> + <br/> + <i>Default</i>: map[]<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>resource</b></td> + <td>string</td> + <td> + Specifies the Kubernetes resource to be patched.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>true</td> + </tr><tr> + <td><b>type</b></td> + <td>string</td> + <td> + Type of the patcher.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>true</td> + </tr></tbody> +</table> + +## execution +<sup><sup>[↩ Parent](#theodolitecomv1 )</sup></sup> + + + + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>apiVersion</b></td> + <td>string</td> + <td>theodolite.com/v1</td> + <td>true</td> + </tr> + <tr> + <td><b>kind</b></td> + <td>string</td> + <td>execution</td> + <td>true</td> + </tr> + <tr> + <td><b><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#objectmeta-v1-meta">metadata</a></b></td> + <td>object</td> + <td>Refer to the Kubernetes API documentation for the fields of the `metadata` field.</td> + <td>true</td> + </tr><tr> + <td><b><a href="#executionstatus">status</a></b></td> + <td>object</td> + <td> + <br/> + </td> + <td>false</td> + </tr><tr> + <td><b><a href="#executionspec">spec</a></b></td> + <td>object</td> + <td> + <br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### execution.status +<sup><sup>[↩ Parent](#execution)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>executionDuration</b></td> + <td>string</td> + <td> + Duration of the execution in seconds<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>executionState</b></td> + <td>string</td> + <td> + <br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### execution.spec +<sup><sup>[↩ Parent](#execution)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>name</b></td> + <td>string</td> + <td> + This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>false</td> + </tr><tr> + <td><b>benchmark</b></td> + <td>string</td> + <td> + The name of the benchmark this execution is referring to.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#executionspecconfigoverridesindex">configOverrides</a></b></td> + <td>[]object</td> + <td> + List of patchers that are used to override existing configurations.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#executionspecexecution">execution</a></b></td> + <td>object</td> + <td> + Defines the overall parameter for the execution.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#executionspecload">load</a></b></td> + <td>object</td> + <td> + Specifies the load values that are benchmarked.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#executionspecresources">resources</a></b></td> + <td>object</td> + <td> + Specifies the scaling resource that is benchmarked.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b><a href="#executionspecslosindex">slos</a></b></td> + <td>[]object</td> + <td> + List of resource values for the specified resource type.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### execution.spec.configOverrides[index] +<sup><sup>[↩ Parent](#executionspec)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#executionspecconfigoverridesindexpatcher">patcher</a></b></td> + <td>object</td> + <td> + Patcher used to patch a resource<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>value</b></td> + <td>string</td> + <td> + <br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### execution.spec.configOverrides[index].patcher +<sup><sup>[↩ Parent](#executionspecconfigoverridesindex)</sup></sup> + + + +Patcher used to patch a resource + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>properties</b></td> + <td>map[string]string</td> + <td> + (Optional) Patcher specific additional arguments.<br/> + <br/> + <i>Default</i>: map[]<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>resource</b></td> + <td>string</td> + <td> + Specifies the Kubernetes resource to be patched.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>true</td> + </tr><tr> + <td><b>type</b></td> + <td>string</td> + <td> + Type of the Patcher.<br/> + <br/> + <i>Default</i>: <br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### execution.spec.execution +<sup><sup>[↩ Parent](#executionspec)</sup></sup> + + + +Defines the overall parameter for the execution. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>loadGenerationDelay</b></td> + <td>integer</td> + <td> + Seconds to wait between the start of the SUT and the load generator.<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>duration</b></td> + <td>integer</td> + <td> + Defines the duration of each experiment in seconds.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>repetitions</b></td> + <td>integer</td> + <td> + Numper of repititions for each experiments.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>restrictions</b></td> + <td>[]string</td> + <td> + List of restriction strategys used to delimit the search space.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>strategy</b></td> + <td>string</td> + <td> + Defines the used strategy for the execution, either 'LinearSearch' or 'BinarySearch'<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### execution.spec.load +<sup><sup>[↩ Parent](#executionspec)</sup></sup> + + + +Specifies the load values that are benchmarked. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>loadType</b></td> + <td>string</td> + <td> + The type of the load. It must match one of the load types specified in the referenced benchmark.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>loadValues</b></td> + <td>[]integer</td> + <td> + List of load values for the specified load type.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### execution.spec.resources +<sup><sup>[↩ Parent](#executionspec)</sup></sup> + + + +Specifies the scaling resource that is benchmarked. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>resourceType</b></td> + <td>string</td> + <td> + The type of the resource. It must match one of the resource types specified in the referenced benchmark.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>resourceValues</b></td> + <td>[]integer</td> + <td> + List of resource values for the specified resource type.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### execution.spec.slos[index] +<sup><sup>[↩ Parent](#executionspec)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>properties</b></td> + <td>map[string]string</td> + <td> + (Optional) SLO specific additional arguments.<br/> + <br/> + <i>Default</i>: map[]<br/> + </td> + <td>false</td> + </tr><tr> + <td><b>offset</b></td> + <td>integer</td> + <td> + Hours by which the start and end timestamp will be shifted (for different timezones).<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>prometheusUrl</b></td> + <td>string</td> + <td> + Connection string for Promehteus.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>sloType</b></td> + <td>string</td> + <td> + The type of the SLO. It must match 'lag trend'.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> \ No newline at end of file diff --git a/docs/crd-execution-doc.md b/docs/crd-execution-doc.md deleted file mode 100644 index 21b5cdecabd4a247df9f2c0c8d376ad578f4032f..0000000000000000000000000000000000000000 --- a/docs/crd-execution-doc.md +++ /dev/null @@ -1,438 +0,0 @@ -# API Reference - -Packages: - -- [theodolite.com/v1](#theodolitecomv1) - -# theodolite.com/v1 - -Resource Types: - -- [execution](#execution) - - - - -## execution -<sup><sup>[↩ Parent](#theodolitecomv1 )</sup></sup> - - - - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>apiVersion</b></td> - <td>string</td> - <td>theodolite.com/v1</td> - <td>true</td> - </tr> - <tr> - <td><b>kind</b></td> - <td>string</td> - <td>execution</td> - <td>true</td> - </tr> - <tr> - <td><b><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#objectmeta-v1-meta">metadata</a></b></td> - <td>object</td> - <td>Refer to the Kubernetes API documentation for the fields of the `metadata` field.</td> - <td>true</td> - </tr><tr> - <td><b><a href="#executionstatus">status</a></b></td> - <td>object</td> - <td> - <br/> - </td> - <td>false</td> - </tr><tr> - <td><b><a href="#executionspec">spec</a></b></td> - <td>object</td> - <td> - <br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### execution.status -<sup><sup>[↩ Parent](#execution)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>executionDuration</b></td> - <td>string</td> - <td> - Duration of the execution in seconds<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>executionState</b></td> - <td>string</td> - <td> - <br/> - </td> - <td>false</td> - </tr></tbody> -</table> - - -### execution.spec -<sup><sup>[↩ Parent](#execution)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>name</b></td> - <td>string</td> - <td> - This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>false</td> - </tr><tr> - <td><b>benchmark</b></td> - <td>string</td> - <td> - The name of the benchmark this execution is referring to.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#executionspecconfigoverridesindex">configOverrides</a></b></td> - <td>[]object</td> - <td> - List of patchers that are used to override existing configurations.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#executionspecexecution">execution</a></b></td> - <td>object</td> - <td> - Defines the overall parameter for the execution.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#executionspecload">load</a></b></td> - <td>object</td> - <td> - Specifies the load values that are benchmarked.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#executionspecresources">resources</a></b></td> - <td>object</td> - <td> - Specifies the scaling resource that is benchmarked.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b><a href="#executionspecslosindex">slos</a></b></td> - <td>[]object</td> - <td> - List of resource values for the specified resource type.<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### execution.spec.configOverrides[index] -<sup><sup>[↩ Parent](#executionspec)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b><a href="#executionspecconfigoverridesindexpatcher">patcher</a></b></td> - <td>object</td> - <td> - Patcher used to patch a resource<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>value</b></td> - <td>string</td> - <td> - <br/> - </td> - <td>false</td> - </tr></tbody> -</table> - - -### execution.spec.configOverrides[index].patcher -<sup><sup>[↩ Parent](#executionspecconfigoverridesindex)</sup></sup> - - - -Patcher used to patch a resource - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>properties</b></td> - <td>object</td> - <td> - (Optional) Patcher specific additional arguments.<br/> - <br/> - <i>Default</i>: map[]<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>resource</b></td> - <td>string</td> - <td> - Specifies the Kubernetes resource to be patched.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>true</td> - </tr><tr> - <td><b>type</b></td> - <td>string</td> - <td> - Type of the Patcher.<br/> - <br/> - <i>Default</i>: <br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### execution.spec.execution -<sup><sup>[↩ Parent](#executionspec)</sup></sup> - - - -Defines the overall parameter for the execution. - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>loadGenerationDelay</b></td> - <td>integer</td> - <td> - Seconds to wait between the start of the SUT and the load generator.<br/> - </td> - <td>false</td> - </tr><tr> - <td><b>duration</b></td> - <td>integer</td> - <td> - Defines the duration of each experiment in seconds.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>repetitions</b></td> - <td>integer</td> - <td> - Numper of repititions for each experiments.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>restrictions</b></td> - <td>[]string</td> - <td> - List of restriction strategys used to delimit the search space.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>strategy</b></td> - <td>string</td> - <td> - Defines the used strategy for the execution, either 'LinearSearch' or 'BinarySearch'<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### execution.spec.load -<sup><sup>[↩ Parent](#executionspec)</sup></sup> - - - -Specifies the load values that are benchmarked. - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>loadType</b></td> - <td>string</td> - <td> - The type of the load. It must match one of the load types specified in the referenced benchmark.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>loadValues</b></td> - <td>[]integer</td> - <td> - List of load values for the specified load type.<br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### execution.spec.resources -<sup><sup>[↩ Parent](#executionspec)</sup></sup> - - - -Specifies the scaling resource that is benchmarked. - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>resourceType</b></td> - <td>string</td> - <td> - The type of the resource. It must match one of the resource types specified in the referenced benchmark.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>resourceValues</b></td> - <td>[]integer</td> - <td> - <br/> - </td> - <td>true</td> - </tr></tbody> -</table> - - -### execution.spec.slos[index] -<sup><sup>[↩ Parent](#executionspec)</sup></sup> - - - - - -<table> - <thead> - <tr> - <th>Name</th> - <th>Type</th> - <th>Description</th> - <th>Required</th> - </tr> - </thead> - <tbody><tr> - <td><b>externalSloUrl</b></td> - <td>string</td> - <td> - Connection string for a external slo analysis.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>offset</b></td> - <td>integer</td> - <td> - Hours by which the start and end timestamp will be shifted (for different timezones).<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>prometheusUrl</b></td> - <td>string</td> - <td> - Connection string for Promehteus.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>sloType</b></td> - <td>string</td> - <td> - The type of the SLO. It must match 'lag trend'.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>threshold</b></td> - <td>integer</td> - <td> - The threshold the SUT should meet for a sucessful experiment.<br/> - </td> - <td>true</td> - </tr><tr> - <td><b>warmup</b></td> - <td>integer</td> - <td> - Seconds of time that are ignored in the analysis.<br/> - </td> - <td>true</td> - </tr></tbody> -</table> \ No newline at end of file diff --git a/theodolite-benchmarks/definitions/install-configmaps.sh b/theodolite-benchmarks/definitions/install-configmaps.sh index 7ddd606a162185993ce402ef4d3b84d8d00eb82c..c5c0283f434d7a4c13da0e93a855cef7e112bbb9 100755 --- a/theodolite-benchmarks/definitions/install-configmaps.sh +++ b/theodolite-benchmarks/definitions/install-configmaps.sh @@ -1,8 +1,17 @@ +# flink kubectl create configmap benchmark-resources-uc1-flink --from-file uc1-flink/resources kubectl create configmap benchmark-resources-uc2-flink --from-file uc2-flink/resources kubectl create configmap benchmark-resources-uc3-flink --from-file uc3-flink/resources kubectl create configmap benchmark-resources-uc4-flink --from-file uc4-flink/resources + +# kafka kubectl create configmap benchmark-resources-uc1-kstreams --from-file uc1-kstreams/resources kubectl create configmap benchmark-resources-uc2-kstreams --from-file uc2-kstreams/resources kubectl create configmap benchmark-resources-uc3-kstreams --from-file uc3-kstreams/resources -kubectl create configmap benchmark-resources-uc4-kstreams --from-file uc4-kstreams/resources \ No newline at end of file +kubectl create configmap benchmark-resources-uc4-kstreams --from-file uc4-kstreams/resources + +# load generator +kubectl create configmap benchmark-resources-uc1-loadgen --from-file uc1-loadGen +kubectl create configmap benchmark-resources-uc2-loadgen --from-file uc2-loadGen +kubectl create configmap benchmark-resources-uc3-loadgen --from-file uc3-loadGen +kubectl create configmap benchmark-resources-uc4-loadgen --from-file uc4-loadGen \ No newline at end of file diff --git a/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml index 3e16e486446d568d2cac0fe5196ab7446be25978..070a2cd89b64fde8fc462709112e2af1f1e79544 100644 --- a/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml @@ -3,17 +3,23 @@ kind: benchmark metadata: name: uc1-flink spec: - appResource: - - "uc1-flink/flink-configuration-configmap.yaml" - - "uc1-flink/taskmanager-deployment.yaml" - - "uc1-flink/taskmanager-service.yaml" - - "uc1-flink/service-monitor.yaml" - - "uc1-flink/jobmanager-service.yaml" - - "uc1-flink/jobmanager-deployment.yaml" - #- "uc1-flink/jobmanager-rest-service.yaml" - loadGenResource: - - "uc1-kstreams/uc1-load-generator-deployment.yaml" - - "uc1-kstreams/uc1-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc1-flink" + files: + - "uc1-flink/flink-configuration-configmap.yaml" + - "uc1-flink/taskmanager-deployment.yaml" + - "uc1-flink/taskmanager-service.yaml" + - "uc1-flink/service-monitor.yaml" + - "uc1-flink/jobmanager-service.yaml" + - "uc1-flink/jobmanager-deployment.yaml" + #- "uc1-flink/jobmanager-rest-service.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc1-loadgen" + files: + - "uc1-kstreams/uc1-load-generator-deployment.yaml" + - "uc1-kstreams/uc1-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-operator.yaml index 8bcc7d5a1d750eed140527e7c6176a881bc9e6e1..283b3baa53b2090b445a379641086f2dc6c7753e 100644 --- a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-operator.yaml @@ -3,14 +3,20 @@ kind: benchmark metadata: name: uc1-kstreams spec: - appResource: - - "uc1-kstreams/uc1-kstreams-deployment.yaml" - - "uc1-kstreams/uc1-kstreams-service.yaml" - - "uc1-kstreams/uc1-jmx-configmap.yaml" - - "uc1-kstreams/uc1-service-monitor.yaml" - loadGenResource: - - "uc1-kstreams/uc1-load-generator-deployment.yaml" - - "uc1-kstreams/uc1-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc1-kstreams" + files: + - "uc1-kstreams/uc1-kstreams-deployment.yaml" + - "uc1-kstreams/uc1-kstreams-service.yaml" + - "uc1-kstreams/uc1-jmx-configmap.yaml" + - "uc1-kstreams/uc1-service-monitor.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc1-loadgen" + files: + - "uc1-kstreams/uc1-load-generator-deployment.yaml" + - "uc1-kstreams/uc1-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-standalone.yaml index 871210c213b70070e2aae8f4986058763be74b7e..b90edf5e4dcae0a4f338fb5edb90c73f34b3d14b 100644 --- a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-standalone.yaml @@ -1,12 +1,18 @@ name: "uc1-kstreams" -appResource: - - "uc1-kstreams-deployment.yaml" - - "uc1-kstreams-service.yaml" - - "uc1-jmx-configmap.yaml" - - "uc1-service-monitor.yaml" -loadGenResource: - - "uc1-load-generator-deployment.yaml" - - "uc1-load-generator-service.yaml" +appResourceSet: + - configMap: + name: "benchmark-resources-uc1-kstreams" + files: + - "uc1-kstreams/uc1-kstreams-deployment.yaml" + - "uc1-kstreams/uc1-kstreams-service.yaml" + - "uc1-kstreams/uc1-jmx-configmap.yaml" + - "uc1-kstreams/uc1-service-monitor.yaml" +loadGenResourceSet: + - configMap: + name: "benchmark-resources-uc1-loadgen" + files: + - "uc1-kstreams/uc1-load-generator-deployment.yaml" + - "uc1-kstreams/uc1-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc1-kstreams/resources/uc1-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc1-kstreams/resources/uc1-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc1-kstreams/resources/uc1-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc1-kstreams/resources/uc1-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-service.yaml diff --git a/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml index ab335cc4f9f8413dd7871fc2184491235aad67e4..dcbdf57efe7397d2a7b646b6388550e205f39957 100644 --- a/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml @@ -3,17 +3,23 @@ kind: benchmark metadata: name: uc2-flink spec: - appResource: - - "uc2-flink/flink-configuration-configmap.yaml" - - "uc2-flink/taskmanager-deployment.yaml" - - "uc2-flink/taskmanager-service.yaml" - - "uc2-flink/service-monitor.yaml" - - "uc2-flink/jobmanager-service.yaml" - - "uc2-flink/jobmanager-deployment.yaml" - #- "uc2-flink/jobmanager-rest-service.yaml" - loadGenResource: - - "uc2-kstreams/uc2-load-generator-deployment.yaml" - - "uc2-kstreams/uc2-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc2-flink" + files: + - "uc2-flink/flink-configuration-configmap.yaml" + - "uc2-flink/taskmanager-deployment.yaml" + - "uc2-flink/taskmanager-service.yaml" + - "uc2-flink/service-monitor.yaml" + - "uc2-flink/jobmanager-service.yaml" + - "uc2-flink/jobmanager-deployment.yaml" + #- "uc2-flink/jobmanager-rest-service.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc2-loadgen" + files: + - "uc2-kstreams/uc2-load-generator-deployment.yaml" + - "uc2-kstreams/uc2-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-operator.yaml index c71318c95ceb9d462f64e19b135ce59b43b03099..aaf479ae89329cabb1180925bb8984b25f40aa48 100644 --- a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-operator.yaml @@ -3,14 +3,20 @@ kind: benchmark metadata: name: uc2-kstreams spec: - appResource: - - "uc2-kstreams/uc2-kstreams-deployment.yaml" - - "uc2-kstreams/uc2-kstreams-service.yaml" - - "uc2-kstreams/uc2-jmx-configmap.yaml" - - "uc2-kstreams/uc2-service-monitor.yaml" - loadGenResource: - - "uc2-kstreams/uc2-load-generator-deployment.yaml" - - "uc2-kstreams/uc2-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc2-kstreams" + files: + - "uc2-kstreams/uc2-kstreams-deployment.yaml" + - "uc2-kstreams/uc2-kstreams-service.yaml" + - "uc2-kstreams/uc2-jmx-configmap.yaml" + - "uc2-kstreams/uc2-service-monitor.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc2-loadgen" + files: + - "uc2-kstreams/uc2-load-generator-deployment.yaml" + - "uc2-kstreams/uc2-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-standalone.yaml index 48269b38a086f074ead80964df3bd4633742743e..b0dbd6bf26b1751add491836a76580e5ce980611 100644 --- a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-standalone.yaml @@ -1,12 +1,18 @@ name: "uc2-kstreams" -appResource: - - "uc2-kstreams-deployment.yaml" - - "uc2-kstreams-service.yaml" - - "uc2-jmx-configmap.yaml" - - "uc2-service-monitor.yaml" -loadGenResource: - - "uc2-load-generator-deployment.yaml" - - "uc2-load-generator-service.yaml" +appResourceSets: + - configMap: + name: "benchmark-resources-uc2-kstreams" + files: + - "uc2-kstreams/uc2-kstreams-deployment.yaml" + - "uc2-kstreams/uc2-kstreams-service.yaml" + - "uc2-kstreams/uc2-jmx-configmap.yaml" + - "uc2-kstreams/uc2-service-monitor.yaml" +loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc2-loadgen" + files: + - "uc2-kstreams/uc2-load-generator-deployment.yaml" + - "uc2-kstreams/uc2-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc2-kstreams/resources/uc2-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc2-kstreams/resources/uc2-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc2-kstreams/resources/uc2-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc2-kstreams/resources/uc2-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-service.yaml diff --git a/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml index bc881d83d622f49409c4b2023b7fd9445038c2e8..7ba17f8e4dee447e7adda0f7c3d0e16eb01f35c5 100644 --- a/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml @@ -3,17 +3,23 @@ kind: benchmark metadata: name: uc3-flink spec: - appResource: - - "uc3-flink/flink-configuration-configmap.yaml" - - "uc3-flink/taskmanager-deployment.yaml" - - "uc3-flink/taskmanager-service.yaml" - - "uc3-flink/service-monitor.yaml" - - "uc3-flink/jobmanager-service.yaml" - - "uc3-flink/jobmanager-deployment.yaml" - #- "uc3-flink/jobmanager-rest-service.yaml" - loadGenResource: - - "uc3-kstreams/uc3-load-generator-deployment.yaml" - - "uc3-kstreams/uc3-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc3-flink" + files: + - "uc3-flink/flink-configuration-configmap.yaml" + - "uc3-flink/taskmanager-deployment.yaml" + - "uc3-flink/taskmanager-service.yaml" + - "uc3-flink/service-monitor.yaml" + - "uc3-flink/jobmanager-service.yaml" + - "uc3-flink/jobmanager-deployment.yaml" + #- "uc3-flink/jobmanager-rest-service.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc3-loadgen" + files: + - "uc3-kstreams/uc3-load-generator-deployment.yaml" + - "uc3-kstreams/uc3-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-operator.yaml index cc10020b17c7a31b61f5fdaf6963be9fda75865f..ef49aac8bcfbe5d3798982689fc73b540d0aade7 100644 --- a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-operator.yaml @@ -3,14 +3,20 @@ kind: benchmark metadata: name: uc3-kstreams spec: - appResource: - - "uc3-kstreams/uc3-kstreams-deployment.yaml" - - "uc3-kstreams/uc3-kstreams-service.yaml" - - "uc3-kstreams/uc3-jmx-configmap.yaml" - - "uc3-kstreams/uc3-service-monitor.yaml" - loadGenResource: - - "uc3-kstreams/uc3-load-generator-deployment.yaml" - - "uc3-kstreams/uc3-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc3-kstreams" + files: + - "uc3-kstreams/uc3-kstreams-deployment.yaml" + - "uc3-kstreams/uc3-kstreams-service.yaml" + - "uc3-kstreams/uc3-jmx-configmap.yaml" + - "uc3-kstreams/uc3-service-monitor.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc3-loadgen" + files: + - "uc3-kstreams/uc3-load-generator-deployment.yaml" + - "uc3-kstreams/uc3-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-standalone.yaml index 0c2311388f1dfa87e8a182eb8399020bc83ae4ce..8bb0b6733bc474d224def09cf22b0315c050b5dd 100644 --- a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-standalone.yaml @@ -1,12 +1,18 @@ name: "uc3-kstreams" -appResource: - - "uc3-kstreams-deployment.yaml" - - "uc3-kstreams-service.yaml" - - "uc3-jmx-configmap.yaml" - - "uc3-service-monitor.yaml" -loadGenResource: - - "uc3-load-generator-deployment.yaml" - - "uc3-load-generator-service.yaml" +appResourceSets: + - configMap: + name: "benchmark-resources-uc3-kstreams" + files: + - "uc3-kstreams/uc3-kstreams-deployment.yaml" + - "uc3-kstreams/uc3-kstreams-service.yaml" + - "uc3-kstreams/uc3-jmx-configmap.yaml" + - "uc3-kstreams/uc3-service-monitor.yaml" +loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc3-loadgen" + files: + - "uc3-kstreams/uc3-load-generator-deployment.yaml" + - "uc3-kstreams/uc3-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc3-kstreams/resources/uc3-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc3-kstreams/resources/uc3-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc3-kstreams/resources/uc3-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc3-kstreams/resources/uc3-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-service.yaml diff --git a/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml index 9979f540ae343a065d8ca483fa9c5934fc550a46..a6e427af267602a5a862b34270d44c299282ba55 100644 --- a/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml @@ -3,17 +3,23 @@ kind: benchmark metadata: name: uc4-flink spec: - appResource: - - "uc4-flink/flink-configuration-configmap.yaml" - - "uc4-flink/taskmanager-deployment.yaml" - - "uc4-flink/taskmanager-service.yaml" - - "uc4-flink/service-monitor.yaml" - - "uc4-flink/jobmanager-service.yaml" - - "uc4-flink/jobmanager-deployment.yaml" - #- "uc4-flink/jobmanager-rest-service.yaml" - loadGenResource: - - "uc4-kstreams/uc4-load-generator-deployment.yaml" - - "uc4-kstreams/uc4-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc4-flink" + files: + - "uc4-flink/flink-configuration-configmap.yaml" + - "uc4-flink/taskmanager-deployment.yaml" + - "uc4-flink/taskmanager-service.yaml" + - "uc4-flink/service-monitor.yaml" + - "uc4-flink/jobmanager-service.yaml" + - "uc4-flink/jobmanager-deployment.yaml" + #- "uc4-flink/jobmanager-rest-service.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc4-loadgen" + files: + - "uc4-kstreams/uc4-load-generator-deployment.yaml" + - "uc4-kstreams/uc4-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-operator.yaml index 61cdfeeea5298d05cca5f5a44cdb4bdf9f108b7c..828ab9321b85b6c186a89f54586c312bace0fd53 100644 --- a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-operator.yaml @@ -3,14 +3,20 @@ kind: benchmark metadata: name: uc4-kstreams spec: - appResource: - - "uc4-kstreams/uc4-kstreams-deployment.yaml" - - "uc4-kstreams/uc4-kstreams-service.yaml" - - "uc4-kstreams/uc4-jmx-configmap.yaml" - - "uc4-kstreams/uc4-service-monitor.yaml" - loadGenResource: - - "uc4-kstreams/uc4-load-generator-deployment.yaml" - - "uc4-kstreams/uc4-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "benchmark-resources-uc4-kstreams" + files: + - "uc4-kstreams/uc4-kstreams-deployment.yaml" + - "uc4-kstreams/uc4-kstreams-service.yaml" + - "uc4-kstreams/uc4-jmx-configmap.yaml" + - "uc4-kstreams/uc4-service-monitor.yaml" + loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc4-loadgen" + files: + - "uc4-kstreams/uc4-load-generator-deployment.yaml" + - "uc4-kstreams/uc4-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-standalone.yaml index ec7a67db4ea24547bc23d5c57e7b907ba489859c..ab112cdcb1adcc1cb8a1a4fd455af5d4aec888a2 100644 --- a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-standalone.yaml @@ -1,12 +1,18 @@ name: "uc4-kstreams" -appResource: - - "uc4-kstreams-deployment.yaml" - - "uc4-kstreams-service.yaml" - - "uc4-jmx-configmap.yaml" - - "uc4-service-monitor.yaml" -loadGenResource: - - "uc4-load-generator-deployment.yaml" - - "uc4-load-generator-service.yaml" +appResourceSets: + - configMap: + name: "benchmark-resources-uc4-kstreams" + files: + - "uc4-kstreams/uc4-kstreams-deployment.yaml" + - "uc4-kstreams/uc4-kstreams-service.yaml" + - "uc4-kstreams/uc4-jmx-configmap.yaml" + - "uc4-kstreams/uc4-service-monitor.yaml" +loadGenResourceSets: + - configMap: + name: "benchmark-resources-uc4-loadgen" + files: + - "uc4-kstreams/uc4-load-generator-deployment.yaml" + - "uc4-kstreams/uc4-load-generator-service.yaml" resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite-benchmarks/definitions/uc4-kstreams/resources/uc4-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc4-kstreams/resources/uc4-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc4-kstreams/resources/uc4-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc4-kstreams/resources/uc4-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-service.yaml diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml index 7a861276a651af520ccec853b65cb57009a45cc5..4425763ba4f6d4fd560151f4bd0910f05d50da1f 100644 --- a/theodolite/crd/crd-benchmark.yaml +++ b/theodolite/crd/crd-benchmark.yaml @@ -20,23 +20,11 @@ spec: properties: spec: type: object - required: ["appResource", "loadGenResource", "resourceTypes", "loadTypes", "kafkaConfig"] + required: ["appResourceSets", "loadGenResourceSets", "resourceTypes", "loadTypes", "kafkaConfig"] properties: name: description: This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten. type: string - appResource: - description: A list of file names that reference Kubernetes resources that are deployed on the cluster for the system under test (SUT). - type: array - minItems: 1 - items: - type: string - loadGenResource: - description: A list of file names that reference Kubernetes resources that are deployed on the cluster for the load generator. - type: array - minItems: 1 - items: - type: string resourceTypes: description: A list of resource types that can be scaled for this `benchmark` resource. For each resource type the concrete values are defined in the `execution` object. type: array @@ -50,7 +38,6 @@ spec: type: string patchers: description: List of patchers used to scale this resource type. - examples: test test test type: array minItems: 1 items: @@ -136,6 +123,72 @@ spec: description: Determines if this topic should only be deleted after each experiement. For removeOnly topics the name can be a RegEx describing the topic. type: boolean default: false + appResourceSets: + description: The appResourceSets specifies all Kubernetes resources required to start the sut. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet. + type: array + items: + type: object + oneOf: + - required: [configMap] + - required: [fileSystem] + properties: + configMap: + description: The configMap resourceSet loads the Kubernetes manifests from an Kubernetes configMap. + type: object + properties: + name: + description: The name of the configMap + type: string + files: + description: (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded. + type: array + items: + type: string + fileSystem: + description: The fileSystem resourceSet loads the Kubernetes manifests from the filesystem. + type: object + properties: + path: + description: The path to the folder which contains the Kubernetes manifests files. + type: string + files: + description: (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded. + type: array + items: + type: string + loadGenResourceSets: + description: The loadGenResourceSets specifies all Kubernetes resources required to start the load generator. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet. + type: array + items: + type: object + oneOf: + - required: [configMap] + - required: [fileSystem] + properties: + configMap: + description: The configMap resourceSet loads the Kubernetes manifests from an Kubernetes configMap. + type: object + properties: + name: + description: The name of the configMap + type: string + files: + description: (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded. + type: array + items: + type: string + fileSystem: + description: The fileSystem resourceSet loads the Kubernetes manifests from the filesystem. + type: object + properties: + path: + description: The path to the folder which contains the Kubernetes manifests files. + type: string + files: + description: (Optional) Specifies which files from the configMap should be loaded. If this field is not set, all files are loaded. + type: array + items: + type: string additionalPrinterColumns: - name: Age type: date diff --git a/theodolite/examples/operator/example-benchmark.yaml b/theodolite/examples/operator/example-benchmark.yaml index 0950b2bdc14c3f43c18c853f1c0e56154fde6452..c10c01bd87937a7741199c3e1d0ddb497ce2a036 100644 --- a/theodolite/examples/operator/example-benchmark.yaml +++ b/theodolite/examples/operator/example-benchmark.yaml @@ -3,11 +3,17 @@ kind: benchmark metadata: name: uc1-kstreams spec: - appResource: - - "uc1-kstreams-deployment.yaml" - loadGenResource: - - "uc1-load-generator-deployment.yaml" - - "uc1-load-generator-service.yaml" + appResourceSets: + - configMap: + name: "example-configmap" + files: + - "uc1-kstreams-deployment.yaml" + loadGenResourceSets: + - configMap: + name: "example-configmap" + files: + - uc1-load-generator-service.yaml + - uc1-load-generator-deployment.yaml resourceTypes: - typeName: "Instances" patchers: @@ -33,3 +39,26 @@ spec: replicationFactor: 1 - name: "theodolite-.*" removeOnly: True + appResourceSets: + # - fileSystem: + # path: ./../../../../../../config + # files: + # - "uc1-kstreams-deployment.yaml" + # - "aggregation-service.yaml" + # - "jmx-configmap.yaml" + # - "uc1-service-monitor.yaml" + - configMap: + name: "example-configmap" + files: + - "uc1-kstreams-deployment.yaml" + loadGenResourceSets: + # - fileSystem: + # path: ./../../../../../../config + # files: + # - uc1-load-generator-service.yaml + # - uc1-load-generator-deployment.yaml + - configMap: + name: "example-configmap" + files: + - uc1-load-generator-service.yaml + - uc1-load-generator-deployment.yaml diff --git a/theodolite/examples/operator/example-configmap.yaml b/theodolite/examples/operator/example-configmap.yaml new file mode 100644 index 0000000000000000000000000000000000000000..210ce32d3fc0f75b9ffce874d1fa0a1ea9bdc3cd --- /dev/null +++ b/theodolite/examples/operator/example-configmap.yaml @@ -0,0 +1,87 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: example-configmap +data: + uc1-kstreams-deployment.yaml: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: titan-ccp-aggregation + spec: + selector: + matchLabels: + app: titan-ccp-aggregation + replicas: 1 + template: + metadata: + labels: + app: titan-ccp-aggregation + spec: + terminationGracePeriodSeconds: 0 + containers: + - name: uc-application + image: ghcr.io/cau-se/theodolite-uc1-kstreams-app:latest + env: + - name: KAFKA_BOOTSTRAP_SERVERS + value: "theodolite-cp-kafka:9092" + - name: SCHEMA_REGISTRY_URL + value: "http://theodolite-cp-schema-registry:8081" + - name: JAVA_OPTS + value: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=5555" + - name: COMMIT_INTERVAL_MS # Set as default for the applications + value: "100" + resources: + limits: + memory: 4Gi + cpu: 1000m + uc1-load-generator-deployment.yaml: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: titan-ccp-load-generator + spec: + selector: + matchLabels: + app: titan-ccp-load-generator + replicas: 1 + template: + metadata: + labels: + app: titan-ccp-load-generator + spec: + terminationGracePeriodSeconds: 0 + containers: + - name: workload-generator + image: ghcr.io/cau-se/theodolite-uc1-workload-generator:latest + ports: + - containerPort: 5701 + name: coordination + env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KUBERNETES_DNS_NAME + value: "titan-ccp-load-generator.$(KUBERNETES_NAMESPACE).svc.cluster.local" + - name: KAFKA_BOOTSTRAP_SERVERS + value: "theodolite-cp-kafka:9092" + - name: SCHEMA_REGISTRY_URL + value: "http://theodolite-cp-schema-registry:8081" + uc1-load-generator-service.yaml: | + apiVersion: v1 + kind: Service + metadata: + name: titan-ccp-load-generator + labels: + app: titan-ccp-load-generator + spec: + type: ClusterIP + clusterIP: None + selector: + app: titan-ccp-load-generator + ports: + - name: coordination + port: 5701 + targetPort: 5701 + protocol: TCP \ No newline at end of file diff --git a/theodolite/examples/standalone/example-benchmark.yaml b/theodolite/examples/standalone/example-benchmark.yaml index e3b37a348c592e065937abf6c8ca99556804867b..9c00dd0fde10e7fb2a9424a243bdbf4d0ba86980 100644 --- a/theodolite/examples/standalone/example-benchmark.yaml +++ b/theodolite/examples/standalone/example-benchmark.yaml @@ -1,9 +1,15 @@ name: "uc1-kstreams" -appResource: - - "uc1-kstreams-deployment.yaml" -loadGenResource: - - "uc1-load-generator-deployment.yaml" - - "uc1-load-generator-service.yaml" +appResourceSets: + - configMap: + name: "example-configmap" + files: + - "uc1-kstreams-deployment.yaml" +loadGenResourceSets: + - configMap: + name: "example-configmap" + files: + - uc1-load-generator-service.yaml + - uc1-load-generator-deployment.yaml resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt new file mode 100644 index 0000000000000000000000000000000000000000..1f89549fb4eabb86fa1a766627abe3bf7c1b3cc6 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt @@ -0,0 +1,74 @@ +package theodolite.benchmark + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.KubernetesClientException +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.quarkus.runtime.annotations.RegisterForReflection +import mu.KotlinLogging +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromString +import theodolite.util.DeploymentFailedException +import theodolite.util.YamlParserFromString +import java.lang.IllegalArgumentException +import java.lang.IllegalStateException + +private val logger = KotlinLogging.logger {} + +@RegisterForReflection +@JsonDeserialize +class ConfigMapResourceSet: ResourceSet, KubernetesResource { + lateinit var name: String + lateinit var files: List<String> // load all files, iff files is not set + + @OptIn(ExperimentalStdlibApi::class) + override fun getResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, KubernetesResource>> { + val loader = K8sResourceLoaderFromString(client) + + logger.info {"use namespace: ${client.namespace} in configmap resource set" } + + var resources: Map<String, String> + + try { + resources = client + .configMaps() + .withName(name) + .get() + .data + .filter { it.key.endsWith(".yaml") } // consider only yaml files, e.g. ignore readme files + } catch (e: KubernetesClientException) { + throw DeploymentFailedException("can not find or read configmap: $name", e) + } catch (e: IllegalStateException) { + throw DeploymentFailedException("can not find configmap or data section is null $name", e) + } + + if (::files.isInitialized){ + resources = resources + .filter { files.contains(it.key) } + } + + return try { + resources + .map { Pair( + getKind(resource = it.value), + it) } + .map { + Pair( + it.second.key, + loader.loadK8sResource(it.first, it.second.value)) } + } catch (e: IllegalArgumentException) { + throw DeploymentFailedException("Can not creat resource set from specified configmap", e) + } + + } + + private fun getKind(resource: String): String { + val parser = YamlParserFromString() + val resourceAsMap = parser.parse(resource, HashMap<String, String>()::class.java) + + return try { + resourceAsMap?.get("kind") !! + } catch (e: NullPointerException) { + throw DeploymentFailedException( "Could not find field kind of Kubernetes resource: ${resourceAsMap?.get("name")}", e) + } + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt new file mode 100644 index 0000000000000000000000000000000000000000..92df1bec3cd6f21b1f830e73b466f70e37a9f4c8 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt @@ -0,0 +1,66 @@ +package theodolite.benchmark + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.DefaultKubernetesClient +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.quarkus.runtime.annotations.RegisterForReflection +import mu.KotlinLogging +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile +import theodolite.util.DeploymentFailedException +import theodolite.util.YamlParserFromFile +import java.io.File +import java.io.FileNotFoundException +import java.lang.IllegalArgumentException + +private val logger = KotlinLogging.logger {} + +@RegisterForReflection +@JsonDeserialize +class FileSystemResourceSet: ResourceSet, KubernetesResource { + lateinit var path: String + lateinit var files: List<String> + + override fun getResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, KubernetesResource>> { + + //if files is set ... + if(::files.isInitialized){ + return files + .map { loadSingleResource(resourceURL = it, client = client) } + } + + return try { + File(path) + .list() !! + .filter { it.endsWith(".yaml") } // consider only yaml files, e.g. ignore readme files + .map { + loadSingleResource(resourceURL = it, client = client) + } + } catch (e: NullPointerException) { + throw DeploymentFailedException("Could not load files located in $path", e) + } + } + + private fun loadSingleResource(resourceURL: String, client: NamespacedKubernetesClient): Pair<String, KubernetesResource> { + val parser = YamlParserFromFile() + val loader = K8sResourceLoaderFromFile(client) + val resourcePath = "$path/$resourceURL" + lateinit var kind: String + + try { + kind = parser.parse(resourcePath, HashMap<String, String>()::class.java)?.get("kind")!! + } catch (e: NullPointerException) { + throw DeploymentFailedException("Can not get Kind from resource $resourcePath", e) + } catch (e: FileNotFoundException){ + throw DeploymentFailedException("File $resourcePath not found", e) + + } + + return try { + val k8sResource = loader.loadK8sResource(kind, resourcePath) + Pair(resourceURL, k8sResource) + } catch (e: IllegalArgumentException) { + throw DeploymentFailedException("Could not load resource: $resourcePath", e) + } + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index b9a2fc7f18b92664b4d93b11755280a9e18b170d..cbdaab0d3158990ceff781045134638e8782989f 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -5,10 +5,11 @@ import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.client.DefaultKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging -import theodolite.k8s.K8sResourceLoader +import theodolite.k8s.resourceLoader.K8sResourceLoader import theodolite.patcher.PatcherFactory import theodolite.util.* + private val logger = KotlinLogging.logger {} private var DEFAULT_NAMESPACE = "default" @@ -34,32 +35,20 @@ private var DEFAULT_THEODOLITE_APP_RESOURCES = "./benchmark-resources" @RegisterForReflection class KubernetesBenchmark : KubernetesResource, Benchmark { lateinit var name: String - lateinit var appResource: List<String> - lateinit var loadGenResource: List<String> lateinit var resourceTypes: List<TypeName> lateinit var loadTypes: List<TypeName> lateinit var kafkaConfig: KafkaConfig + lateinit var appResourceSets: List<ResourceSets> + lateinit var loadGenResourceSets: List<ResourceSets> var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE - /** * Loads [KubernetesResource]s. - * It first loads them via the [YamlParser] to check for their concrete type and afterwards initializes them using + * It first loads them via the [YamlParserFromFile] to check for their concrete type and afterwards initializes them using * the [K8sResourceLoader] */ - private fun loadKubernetesResources(resources: List<String>): List<Pair<String, KubernetesResource>> { - val path = System.getenv("THEODOLITE_APP_RESOURCES") ?: DEFAULT_THEODOLITE_APP_RESOURCES - logger.info { "Using $path as resource path." } - - val parser = YamlParser() - val loader = K8sResourceLoader(DefaultKubernetesClient()) - return resources - .map { resource -> - val resourcePath = "$path/$resource" - val kind = parser.parse(resourcePath, HashMap<String, String>()::class.java)?.get("kind")!! - val k8sResource = loader.loadK8sResource(kind, resourcePath) - Pair(resource, k8sResource) - } + fun loadKubernetesResources(resourceSet: List<ResourceSets>): Collection<Pair<String, KubernetesResource>> { + return resourceSet.flatMap { it.loadResourceSet(DefaultKubernetesClient().inNamespace(namespace)) } } /** @@ -80,8 +69,8 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { ): BenchmarkDeployment { logger.info { "Using $namespace as namespace." } - val appResources = loadKubernetesResources(this.appResource) - val loadGenResources = loadKubernetesResources(this.loadGenResource) + val appResources = loadKubernetesResources(this.appResourceSets) + val loadGenResources = loadKubernetesResources(this.loadGenResourceSets) val patcherFactory = PatcherFactory() diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt new file mode 100644 index 0000000000000000000000000000000000000000..19fc85845ae99c7a5e4f7369db4b6cd383c3131b --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt @@ -0,0 +1,13 @@ +package theodolite.benchmark + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.quarkus.runtime.annotations.RegisterForReflection + +@RegisterForReflection +@JsonDeserialize +interface ResourceSet: KubernetesResource { + + fun getResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, KubernetesResource>> +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt new file mode 100644 index 0000000000000000000000000000000000000000..19c0808093f6729978f98940641031d8e425c349 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt @@ -0,0 +1,31 @@ +package theodolite.benchmark + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.quarkus.runtime.annotations.RegisterForReflection +import mu.KotlinLogging +import theodolite.util.DeploymentFailedException + +@JsonDeserialize +@RegisterForReflection +@JsonInclude(JsonInclude.Include.NON_NULL) +class ResourceSets: KubernetesResource { + @JsonProperty("configMap") + lateinit var configMap: ConfigMapResourceSet + + @JsonProperty("fileSystem") + lateinit var fileSystem: FileSystemResourceSet + + fun loadResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, KubernetesResource>> { + return if (::configMap.isInitialized) { + configMap.getResourceSet(client= client) + } else if (::fileSystem.isInitialized) { + fileSystem.getResourceSet(client= client ) + } else { + throw DeploymentFailedException("could not load resourceSet.") + } + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt index 1160132fdc4a7130a05861d72c5f688f0fb5af9b..1bbf3e01f461a19dbe588aedd41be63b84c86162 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteStandalone.kt @@ -3,9 +3,9 @@ package theodolite.execution import mu.KotlinLogging import theodolite.benchmark.BenchmarkExecution import theodolite.benchmark.KubernetesBenchmark +import theodolite.util.YamlParserFromFile import theodolite.util.EvaluationFailedException import theodolite.util.ExecutionFailedException -import theodolite.util.YamlParser import kotlin.concurrent.thread import kotlin.system.exitProcess @@ -28,7 +28,7 @@ private val logger = KotlinLogging.logger {} * @constructor Create empty Theodolite yaml executor */ class TheodoliteStandalone { - private val parser = YamlParser() + private val parser = YamlParserFromFile() fun start() { logger.info { "Theodolite started" } diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt index 9d7436526f18081c7130870956d8a5eea5fc8997..0b5d6040bdea1316f8fb55bcc3f204c5443f6eee 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt @@ -4,10 +4,13 @@ import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResourceList import io.fabric8.kubernetes.api.model.Namespaced import io.fabric8.kubernetes.client.CustomResource +import io.fabric8.kubernetes.client.KubernetesClientException import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.fabric8.kubernetes.client.dsl.MixedOperation import io.fabric8.kubernetes.client.dsl.Resource +import mu.KotlinLogging import java.lang.Thread.sleep +private val logger = KotlinLogging.logger {} abstract class AbstractStateHandler<T, L, D>( private val client: NamespacedKubernetesClient, @@ -20,11 +23,15 @@ abstract class AbstractStateHandler<T, L, D>( @Synchronized override fun setState(resourceName: String, f: (T) -> T?) { - this.crdClient - .list().items - .filter { it.metadata.name == resourceName } - .map { customResource -> f(customResource) } - .forEach { this.crdClient.updateStatus(it) } + try { + this.crdClient + .list().items + .filter { it.metadata.name == resourceName } + .map { customResource -> f(customResource) } + .forEach { this.crdClient.updateStatus(it) } + } catch (e: KubernetesClientException) { + logger.warn { "Status cannot be set for resource $resourceName" } + } } @Synchronized diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt index 3f8fe1495e88a08a99710b1b360fb8c392b0aacb..9058f1f314be9e71e882dff789e914bc4085c6f2 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt @@ -67,9 +67,11 @@ class TheodoliteController( * @see BenchmarkExecution */ private fun runExecution(execution: BenchmarkExecution, benchmark: KubernetesBenchmark) { - val modifier = ConfigOverrideModifier( + try { + val modifier = ConfigOverrideModifier( execution = execution, - resources = benchmark.appResource + benchmark.loadGenResource + resources = benchmark.loadKubernetesResources(benchmark.appResourceSets).map { it.first } + + benchmark.loadKubernetesResources(benchmark.loadGenResourceSets).map { it.first } ) modifier.setAdditionalLabels( labelValue = execution.name, @@ -87,7 +89,6 @@ class TheodoliteController( executionStateHandler.setExecutionState(execution.name, States.RUNNING) executionStateHandler.startDurationStateTimer(execution.name) - try { executor = TheodoliteExecutor(execution, benchmark) executor.run() when (executionStateHandler.getExecutionState(execution.name)) { diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt index cbce5749f39577a5e99bb773eff9ff8a3541ad8b..d078b52c4c72d71d4f9f773831ea1a0736be6c99 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt @@ -126,7 +126,7 @@ class TheodoliteOperator { ) } - private fun getBenchmarkClient(client: NamespacedKubernetesClient): MixedOperation< + fun getBenchmarkClient(client: NamespacedKubernetesClient): MixedOperation< BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>> { diff --git a/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt b/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt index dd416ccd90166fa570aad2f9ed8095e6a20dea02..797ed88389947d66aa626ba2ef3fdf6732f8369d 100644 --- a/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt +++ b/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt @@ -8,7 +8,7 @@ import mu.KotlinLogging private val logger = KotlinLogging.logger {} class CustomResourceWrapper( - private val crAsMap: Map<String, String>, + val crAsMap: Map<String, String>, private val context: CustomResourceDefinitionContext ) : KubernetesResource { /** diff --git a/theodolite/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt b/theodolite/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt deleted file mode 100644 index 3fa727bc92720059e9a65dcbd1fa90a3b88cfd58..0000000000000000000000000000000000000000 --- a/theodolite/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt +++ /dev/null @@ -1,152 +0,0 @@ -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.apps.Deployment -import io.fabric8.kubernetes.client.NamespacedKubernetesClient -import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext -import mu.KotlinLogging -import theodolite.util.DeploymentFailedException -import theodolite.util.YamlParser - -private val logger = KotlinLogging.logger {} - -/** - * Used to load different Kubernetes resources. - * Supports: Deployments, Services, ConfigMaps, and CustomResources. - * @param client KubernetesClient used to deploy or remove. - */ -class K8sResourceLoader(private val client: NamespacedKubernetesClient) { - - /** - * Parses a Service from a service yaml - * @param path of the yaml file - * @return Service from fabric8 - */ - private fun loadService(path: String): Service { - return loadGenericResource(path) { client.services().load(it).get() } - } - - - /** - * Parses a CustomResource from a yaml - * @param path of the yaml file - * @param context specific crd context for this custom resource - * @return CustomResourceWrapper from fabric8 - */ - private fun loadCustomResourceWrapper( - path: String, - context: CustomResourceDefinitionContext - ): CustomResourceWrapper { - return loadGenericResource(path) { - CustomResourceWrapper( - YamlParser().parse( - path, - HashMap<String, String>()::class.java - )!!, - context - ) - } - } - - private fun loadServiceMonitor(path: String): CustomResourceWrapper { - val context = K8sContextFactory().create( - api = "v1", - scope = "Namespaced", - group = "monitoring.coreos.com", - plural = "servicemonitors" - ) - return loadCustomResourceWrapper(path, context) - } - - private fun loadExecution(path: String): KubernetesResource { - val context = K8sContextFactory().create( - api = "v1", - scope = "Namespaced", - group = "theodolite.com", - plural = "executions" - ) - return loadCustomResourceWrapper(path, context) - } - - private fun loadBenchmark(path: String): KubernetesResource { - val context = K8sContextFactory().create( - api = "v1", - scope = "Namespaced", - group = "theodolite.com", - plural = "benchmarks" - ) - return loadCustomResourceWrapper(path, context) - } - - - /** - * Parses a Deployment from a Deployment yaml - * @param path of the yaml file - * @return Deployment from fabric8 - */ - private fun loadDeployment(path: String): Deployment { - return loadGenericResource(path) { client.apps().deployments().load(it).get() } - } - - /** - * Parses a ConfigMap from a ConfigMap yaml - * @param path of the yaml file - * @return ConfigMap from fabric8 - */ - private fun loadConfigmap(path: String): ConfigMap { - return loadGenericResource(path) { client.configMaps().load(it).get() } - } - - /** - * Parses a StatefulSet from a StatefulSet yaml - * @param path of the yaml file - * @return StatefulSet from fabric8 - */ - private fun loadStatefulSet(path: String): KubernetesResource { - return loadGenericResource(path) { client.apps().statefulSets().load(it).get() } - - } - - /** - * Generic helper function to load a resource. - * @param path of the resource - * @param f function that is applied to the resource. - * @throws IllegalArgumentException If the resource could not be loaded. - */ - private fun <T> loadGenericResource(path: String, f: (String) -> T): T { - var resource: T? = null - - try { - resource = f(path) - } catch (e: Exception) { - throw IllegalArgumentException("The Resource at path: $path could not be loaded", e) - } - if (resource == null) { - throw IllegalArgumentException("The Resource at path: $path could not be loaded") - } - return resource - } - - /** - * Factory function used to load different k8s resources from a path. - * Supported kinds are: Deployments, Services, ServiceMonitors, ConfigMaps and CustomResources. - * Uses CustomResource as default if Kind is not supported. - * @param kind of the resource. CustomResource as default. - * @param path of the resource to be loaded. - * @throws Exception if the resource could not be loaded. - */ - fun loadK8sResource(kind: String, path: String): KubernetesResource { - return when (kind) { - "Deployment" -> loadDeployment(path) - "Service" -> loadService(path) - "ServiceMonitor" -> loadServiceMonitor(path) - "ConfigMap" -> loadConfigmap(path) - "StatefulSet" -> loadStatefulSet(path) - "Execution" -> loadExecution(path) - "Benchmark" -> loadBenchmark(path) - else -> throw IllegalArgumentException("error while loading resource with kind: $kind") - } - } -} diff --git a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/AbstractK8sLoader.kt b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/AbstractK8sLoader.kt new file mode 100644 index 0000000000000000000000000000000000000000..862de14e2a7a4721e15215b0a1389e14f943fe24 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/AbstractK8sLoader.kt @@ -0,0 +1,73 @@ +package theodolite.k8s.resourceLoader + +import io.fabric8.kubernetes.api.model.KubernetesResource +import mu.KotlinLogging +import theodolite.k8s.K8sContextFactory + +private val logger = KotlinLogging.logger {} + +abstract class AbstractK8sLoader: K8sResourceLoader { + + fun loadK8sResource(kind: String, resourceString: String): KubernetesResource { + return when (kind.replaceFirst(kind[0],kind[0].toUpperCase())) { + "Deployment" -> loadDeployment(resourceString) + "Service" -> loadService(resourceString) + "ServiceMonitor" -> loadServiceMonitor(resourceString) + "ConfigMap" -> loadConfigmap(resourceString) + "StatefulSet" -> loadStatefulSet(resourceString) + "Execution" -> loadExecution(resourceString) + "Benchmark" -> loadBenchmark(resourceString) + else -> { + logger.error { "Error during loading of unspecified resource Kind $kind" } + throw java.lang.IllegalArgumentException("error while loading resource with kind: $kind") + } + } + } + + fun <T> loadGenericResource(resourceString: String, f: (String) -> T): T { + var resource: T? = null + + try { + resource = f(resourceString) + } catch (e: Exception) { + logger.warn { e } + } + + if (resource == null) { + throw IllegalArgumentException("The Resource: $resourceString could not be loaded") + } + return resource + } + + + + override fun loadServiceMonitor(resource: String): KubernetesResource { + val context = K8sContextFactory().create( + api = "v1", + scope = "Namespaced", + group = "monitoring.coreos.com", + plural = "servicemonitors" + ) + return loadCustomResourceWrapper(resource, context) + } + + override fun loadExecution(resource: String): KubernetesResource { + val context = K8sContextFactory().create( + api = "v1", + scope = "Namespaced", + group = "theodolite.com", + plural = "executions" + ) + return loadCustomResourceWrapper(resource, context) + } + + override fun loadBenchmark(resource: String): KubernetesResource { + val context = K8sContextFactory().create( + api = "v1", + scope = "Namespaced", + group = "theodolite.com", + plural = "benchmarks" + ) + return loadCustomResourceWrapper(resource, context) + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoader.kt b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoader.kt new file mode 100644 index 0000000000000000000000000000000000000000..c123ab2958132cb43ad188136f738b561e91310b --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoader.kt @@ -0,0 +1,15 @@ +package theodolite.k8s.resourceLoader + +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext + +interface K8sResourceLoader { + fun loadDeployment(resource: String): KubernetesResource + fun loadService(resource: String): KubernetesResource + fun loadStatefulSet(resource: String): KubernetesResource + fun loadExecution(resource: String): KubernetesResource + fun loadBenchmark(resource: String): KubernetesResource + fun loadConfigmap(resource: String): KubernetesResource + fun loadServiceMonitor(resource: String): KubernetesResource + fun loadCustomResourceWrapper(resource: String, context: CustomResourceDefinitionContext): KubernetesResource +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoaderFromFile.kt b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoaderFromFile.kt new file mode 100644 index 0000000000000000000000000000000000000000..08f34e1d67c9821c9f9a07a49f4ba8683a072611 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoaderFromFile.kt @@ -0,0 +1,75 @@ +package theodolite.k8s.resourceLoader + +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.apps.Deployment +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext +import theodolite.k8s.CustomResourceWrapper +import theodolite.util.YamlParserFromFile + +/** + * Used to load different Kubernetes resources. + * Supports: Deployments, Services, ConfigMaps, and CustomResources. + * @param client KubernetesClient used to deploy or remove. + */ +class K8sResourceLoaderFromFile(private val client: NamespacedKubernetesClient): AbstractK8sLoader(), + K8sResourceLoader { + + /** + * Parses a Service from a service yaml + * @param resource of the yaml file + * @return Service from fabric8 + */ + override fun loadService(resource: String): Service { + return loadGenericResource(resource) { x: String -> client.services().load(x).get() } + } + + + /** + * Parses a CustomResource from a yaml + * @param path of the yaml file + * @param context specific crd context for this custom resource + * @return CustomResourceWrapper from fabric8 + */ + override fun loadCustomResourceWrapper(resource: String, context: CustomResourceDefinitionContext): CustomResourceWrapper { + return loadGenericResource(resource) { + CustomResourceWrapper( + YamlParserFromFile().parse( + resource, + HashMap<String, String>()::class.java + )!!, + context + ) + } + } + + /** + * Parses a Deployment from a Deployment yaml + * @param resource of the yaml file + * @return Deployment from fabric8 + */ + override fun loadDeployment(resource: String): Deployment { + return loadGenericResource(resource) { x: String -> client.apps().deployments().load(x).get() } + } + + /** + * Parses a ConfigMap from a ConfigMap yaml + * @param resource of the yaml file + * @return ConfigMap from fabric8 + */ + override fun loadConfigmap(resource: String): ConfigMap { + return loadGenericResource(resource) { x: String -> client.configMaps().load(x).get() } + } + + /** + * Parses a StatefulSet from a StatefulSet yaml + * @param resource of the yaml file + * @return StatefulSet from fabric8 + */ + override fun loadStatefulSet(resource: String): KubernetesResource { + return loadGenericResource(resource) { x: String -> client.apps().statefulSets().load(x).get() } + + } +} diff --git a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoaderFromString.kt b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoaderFromString.kt new file mode 100644 index 0000000000000000000000000000000000000000..e9611aaa82870dfb676820029cf42c5aab63d672 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoaderFromString.kt @@ -0,0 +1,60 @@ +package theodolite.k8s.resourceLoader + +import io.fabric8.kubernetes.api.model.ConfigMap +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext +import theodolite.k8s.CustomResourceWrapper +import theodolite.util.YamlParserFromString +import java.io.ByteArrayInputStream + +class K8sResourceLoaderFromString(private val client: NamespacedKubernetesClient): AbstractK8sLoader(), + K8sResourceLoader { + + @OptIn(ExperimentalStdlibApi::class) + override fun loadService(resource: String): KubernetesResource { + return loadGenericResource(resource) { x: String -> + val stream = ByteArrayInputStream(x.encodeToByteArray()) + client.services().load(stream).get() } + } + + @OptIn(ExperimentalStdlibApi::class) + override fun loadDeployment(resource: String): Deployment { + return loadGenericResource(resource) { x: String -> + val stream = ByteArrayInputStream(x.encodeToByteArray()) + client.apps().deployments().load(stream).get() } + } + + @OptIn(ExperimentalStdlibApi::class) + override fun loadConfigmap(resource: String): ConfigMap { + return loadGenericResource(resource) { x: String -> + val stream = ByteArrayInputStream(x.encodeToByteArray()) + client.configMaps().load(stream).get() } + } + + @OptIn(ExperimentalStdlibApi::class) + override fun loadStatefulSet(resource: String): KubernetesResource { + return loadGenericResource(resource) { x: String -> + val stream = ByteArrayInputStream(x.encodeToByteArray()) + client.apps().statefulSets().load(stream).get() } + } + + /** + * Parses a CustomResource from a yaml + * @param resource of the yaml file + * @param context specific crd context for this custom resource + * @return CustomResourceWrapper from fabric8 + */ + override fun loadCustomResourceWrapper(resource: String, context: CustomResourceDefinitionContext): CustomResourceWrapper { + return loadGenericResource(resource) { + CustomResourceWrapper( + YamlParserFromString().parse( + resource, + HashMap<String, String>()::class.java + )!!, + context + ) + } + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt b/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt index cdf115a0755e8794075884bf952db3b8d76f1f50..ebad5de74a6b819dbf7887dfad91faac37ed5074 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt @@ -26,7 +26,7 @@ class PatcherFactory { */ fun createPatcher( patcherDefinition: PatcherDefinition, - k8sResources: List<Pair<String, KubernetesResource>> + k8sResources: Collection<Pair<String, KubernetesResource>> ): Patcher { val resource = k8sResources.filter { it.first == patcherDefinition.resource } diff --git a/theodolite/src/main/kotlin/theodolite/util/DeploymentFailedException.kt b/theodolite/src/main/kotlin/theodolite/util/DeploymentFailedException.kt index 6fbb5e768c4ef65a7b50345818aecd9050afd0b7..9f4caedf3db1e09dca7924bf0035c6ace0b835d7 100644 --- a/theodolite/src/main/kotlin/theodolite/util/DeploymentFailedException.kt +++ b/theodolite/src/main/kotlin/theodolite/util/DeploymentFailedException.kt @@ -1,4 +1,4 @@ package theodolite.util -open class DeploymentFailedException(message: String, e: Exception? = null) : TheodoliteException(message,e) \ No newline at end of file +open class DeploymentFailedException(message: String, e: Exception? = null) : TheodoliteException(message,e) diff --git a/theodolite/src/main/kotlin/theodolite/util/YamlParser.kt b/theodolite/src/main/kotlin/theodolite/util/YamlParserFromFile.kt similarity index 92% rename from theodolite/src/main/kotlin/theodolite/util/YamlParser.kt rename to theodolite/src/main/kotlin/theodolite/util/YamlParserFromFile.kt index ce69894e4145372aef07286ae315d11631a4df3f..ae36349e628621bb7ad287d8cf557fbefa3ff5c5 100644 --- a/theodolite/src/main/kotlin/theodolite/util/YamlParser.kt +++ b/theodolite/src/main/kotlin/theodolite/util/YamlParserFromFile.kt @@ -9,7 +9,7 @@ import java.io.InputStream /** * The YamlParser parses a YAML file */ -class YamlParser : Parser { +class YamlParserFromFile : Parser { override fun <T> parse(path: String, E: Class<T>): T? { val input: InputStream = FileInputStream(File(path)) val parser = Yaml(Constructor(E)) diff --git a/theodolite/src/main/kotlin/theodolite/util/YamlParserFromString.kt b/theodolite/src/main/kotlin/theodolite/util/YamlParserFromString.kt new file mode 100644 index 0000000000000000000000000000000000000000..61db189ee99fa5fe36113b0fdecf589ad1114852 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/util/YamlParserFromString.kt @@ -0,0 +1,17 @@ +package theodolite.util + +import org.yaml.snakeyaml.Yaml +import org.yaml.snakeyaml.constructor.Constructor +import java.io.File +import java.io.FileInputStream +import java.io.InputStream + +/** + * The YamlParser parses a YAML string + */ +class YamlParserFromString : Parser { + override fun <T> parse(fileString: String, E: Class<T>): T? { + val parser = Yaml(Constructor(E)) + return parser.loadAs(fileString, E) + } +} diff --git a/theodolite/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt index e88192dd7fe4393494a4fb76bd74d1123bd75f1d..46758583172c3fcd6417e17ff5bab85f8659734b 100644 --- a/theodolite/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt +++ b/theodolite/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt @@ -5,7 +5,7 @@ import io.fabric8.kubernetes.client.DefaultKubernetesClient import io.quarkus.test.junit.QuarkusTest import io.smallrye.common.constraint.Assert.assertTrue import org.junit.jupiter.api.Test -import theodolite.k8s.K8sResourceLoader +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile import theodolite.patcher.PatcherFactory import theodolite.util.PatcherDefinition @@ -22,7 +22,7 @@ import theodolite.util.PatcherDefinition @QuarkusTest class ResourceLimitPatcherTest { val testPath = "./src/test/resources/" - val loader = K8sResourceLoader(DefaultKubernetesClient().inNamespace("")) + val loader = K8sResourceLoaderFromFile(DefaultKubernetesClient().inNamespace("")) val patcherFactory = PatcherFactory() fun applyTest(fileName: String) { diff --git a/theodolite/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt index 2af6c632567bf47e150a74808ab009bd0bc0598a..8794d4dc2d67b8af78f4fa409c727f882922d0b8 100644 --- a/theodolite/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt +++ b/theodolite/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt @@ -5,7 +5,7 @@ import io.fabric8.kubernetes.client.DefaultKubernetesClient import io.quarkus.test.junit.QuarkusTest import io.smallrye.common.constraint.Assert.assertTrue import org.junit.jupiter.api.Test -import theodolite.k8s.K8sResourceLoader +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile import theodolite.patcher.PatcherFactory import theodolite.util.PatcherDefinition @@ -22,7 +22,7 @@ import theodolite.util.PatcherDefinition @QuarkusTest class ResourceRequestPatcherTest { val testPath = "./src/test/resources/" - val loader = K8sResourceLoader(DefaultKubernetesClient().inNamespace("")) + val loader = K8sResourceLoaderFromFile(DefaultKubernetesClient().inNamespace("")) val patcherFactory = PatcherFactory() fun applyTest(fileName: String) { diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt b/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..2cc8f931418e28ae8841b592f93df8d88440cf3c --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt @@ -0,0 +1,226 @@ +package theodolite.benchmark + +import com.google.gson.Gson +import io.fabric8.kubernetes.api.model.* +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder +import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder +import io.fabric8.kubernetes.client.server.mock.KubernetesServer +import io.quarkus.test.junit.QuarkusTest +import io.smallrye.common.constraint.Assert.assertTrue +import junit.framework.Assert.assertEquals +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import theodolite.k8s.CustomResourceWrapper +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile +import theodolite.util.DeploymentFailedException + +private val testResourcePath = "./src/test/resources/k8s-resource-files/" + +@QuarkusTest +class ConfigMapResourceSetTest { + private val server = KubernetesServer(false, true) + + @BeforeEach + fun setUp() { + server.before() + } + + @AfterEach + fun tearDown() { + server.after() + } + + fun deployAndGetResource(resource: String): Collection<Pair<String, KubernetesResource>> { + val configMap1 = ConfigMapBuilder() + .withNewMetadata().withName("test-configmap").endMetadata() + .addToData("test-resource.yaml",resource) + .build() + + server.client.configMaps().createOrReplace(configMap1) + + val resourceSet = ConfigMapResourceSet() + resourceSet.name = "test-configmap" + + return resourceSet.getResourceSet(server.client) + } + + + @Test + fun testLoadDeployment() { + val resourceBuilder = DeploymentBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-deployment" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource.toMutableSet().first().second is Deployment) + assertTrue(createdResource.toMutableSet().first().second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadStateFulSet() { + val resourceBuilder = StatefulSetBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-resource" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource.toMutableSet().first().second is StatefulSet) + assertTrue(createdResource.toMutableSet().first().second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadService() { + val resourceBuilder = ServiceBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-resource" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource.toMutableSet().first().second is Service) + assertTrue(createdResource.toMutableSet().first().second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadConfigMap() { + val resourceBuilder = ConfigMapBuilder() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-resource" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource.toMutableSet().first().second is ConfigMap) + assertTrue(createdResource.toMutableSet().first().second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadExecution() { + val loader = K8sResourceLoaderFromFile(server.client) + val resource = loader.loadK8sResource("Execution", testResourcePath + "test-execution.yaml") as CustomResourceWrapper + val createdResource = deployAndGetResource(resource = Gson().toJson(resource.crAsMap)) + + assertEquals(1, createdResource.size) + assertTrue(createdResource.toMutableSet().first().second is CustomResourceWrapper) + + val loadedResource = createdResource.toMutableSet().first().second + if (loadedResource is CustomResourceWrapper){ + assertTrue(loadedResource.getName() == "example-execution") + } + } + + @Test + fun testLoadBenchmark() { + val loader = K8sResourceLoaderFromFile(server.client) + val resource = loader.loadK8sResource("Benchmark", testResourcePath + "test-benchmark.yaml") as CustomResourceWrapper + val createdResource = deployAndGetResource(resource = Gson().toJson(resource.crAsMap)) + + assertEquals(1, createdResource.size) + assertTrue(createdResource.toMutableSet().first().second is CustomResourceWrapper) + + val loadedResource = createdResource.toMutableSet().first().second + if (loadedResource is CustomResourceWrapper){ + assertTrue(loadedResource.getName() == "example-benchmark") + } + } + + @Test + fun testLoadServiceMonitor() { + val loader = K8sResourceLoaderFromFile(server.client) + val resource = loader.loadK8sResource("ServiceMonitor", testResourcePath + "test-service-monitor.yaml") as CustomResourceWrapper + val createdResource = deployAndGetResource(resource = Gson().toJson(resource.crAsMap)) + + assertEquals(1, createdResource.size) + assertTrue(createdResource.toMutableSet().first().second is CustomResourceWrapper) + + val loadedResource = createdResource.toMutableSet().first().second + if (loadedResource is CustomResourceWrapper){ + assertTrue(loadedResource.getName() == "test-service-monitor") + } + } + + @Test + fun testMultipleFiles(){ + val resourceBuilder = DeploymentBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-deployment" + + val resourceBuilder1 = ConfigMapBuilder() + resourceBuilder1.withNewMetadata().endMetadata() + val resource1 = resourceBuilder1.build() + resource1.metadata.name = "test-configmap" + + val configMap1 = ConfigMapBuilder() + .withNewMetadata().withName("test-configmap").endMetadata() + .addToData("test-deployment.yaml",Gson().toJson(resource)) + .addToData("test-configmap.yaml",Gson().toJson(resource1)) + .build() + + server.client.configMaps().createOrReplace(configMap1) + + val resourceSet = ConfigMapResourceSet() + resourceSet.name = "test-configmap" + + val createdResourcesSet = resourceSet.getResourceSet(server.client) + + assertEquals(2,createdResourcesSet.size ) + assert(createdResourcesSet.toMutableList()[0].second is Deployment) + assert(createdResourcesSet.toMutableList()[1].second is ConfigMap) + } + + @Test + fun testFileIsSet(){ + val resourceBuilder = DeploymentBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-deployment" + + val resourceBuilder1 = ConfigMapBuilder() + resourceBuilder1.withNewMetadata().endMetadata() + val resource1 = resourceBuilder1.build() + resource1.metadata.name = "test-configmap" + + val configMap1 = ConfigMapBuilder() + .withNewMetadata().withName("test-configmap").endMetadata() + .addToData("test-deployment.yaml",Gson().toJson(resource)) + .addToData("test-configmap.yaml",Gson().toJson(resource1)) + .build() + + server.client.configMaps().createOrReplace(configMap1) + + val resourceSet = ConfigMapResourceSet() + resourceSet.name = "test-configmap" + resourceSet.files = listOf("test-deployment.yaml") + + val createdResourcesSet = resourceSet.getResourceSet(server.client) + + assertEquals(1,createdResourcesSet.size ) + assert(createdResourcesSet.toMutableSet().first().second is Deployment) + } + + + @Test() + fun testConfigMapNotExist() { + val resourceSet = ConfigMapResourceSet() + resourceSet.name = "test-configmap1" + lateinit var ex: Exception + try { + resourceSet.getResourceSet(server.client) + } catch (e: Exception) { + ex = e + } + assertTrue(ex is DeploymentFailedException) + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt b/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..59ad2be3248f67442ce352788f8b94b26f3b6b90 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt @@ -0,0 +1,115 @@ +package theodolite.benchmark + +import io.fabric8.kubernetes.api.model.ConfigMap +import io.fabric8.kubernetes.api.model.Service +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.client.server.mock.KubernetesServer +import io.smallrye.common.constraint.Assert.assertTrue +import junit.framework.Assert.assertEquals +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import theodolite.k8s.CustomResourceWrapper +import theodolite.util.DeploymentFailedException +import java.lang.IllegalStateException + +private val testResourcePath = "./src/test/resources/k8s-resource-files/" + +class FileSystemResourceSetTest { + + private val server = KubernetesServer(false, true) + + @BeforeEach + fun setUp() { + server.before() + } + + @AfterEach + fun tearDown() { + server.after() + } + + @Test + fun testLoadDeployment() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-deployment.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client).toMutableSet().first().second is Deployment) + } + + @Test + fun testLoadService() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-service.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client).toMutableSet().first().second is Service) + } + + @Test + fun testLoadStatefulSet() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-statefulset.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client).toMutableSet().first().second is StatefulSet) + } + + @Test + fun testLoadConfigMap() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-configmap.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client).toMutableSet().first().second is ConfigMap) + } + + @Test + fun testLoadServiceMonitor() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-service-monitor.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client).toMutableSet().first().second is CustomResourceWrapper) + } + + @Test + fun testLoadBenchmark() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-benchmark.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client).toMutableSet().first().second is CustomResourceWrapper) + } + + @Test + fun testLoadExecution() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-execution.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client).toMutableSet().first().second is CustomResourceWrapper) + } + + @Test + fun testFilesNotSet() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + assertEquals(9,resourceSet.getResourceSet(server.client).size) + } + + @Test + fun testWrongPath() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = "/abc/not-exist" + lateinit var ex: Exception + try { + resourceSet.getResourceSet(server.client) + } catch (e: Exception) { + println(e) + ex = e + } + assertTrue(ex is DeploymentFailedException) } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt index f3fd06a16e38439a2a694b415edc4d8b332ffd4d..24192282a7407daf60390660a5858e15640207f3 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt @@ -24,8 +24,9 @@ class BenchmarkCRDummy(name: String) { benchmarkCR.kind = "Benchmark" benchmarkCR.apiVersion = "v1" - benchmark.appResource = emptyList() - benchmark.loadGenResource = emptyList() + benchmark.appResourceSets = emptyList() + benchmark.loadGenResourceSets = emptyList() + benchmark.resourceTypes = emptyList() benchmark.loadTypes = emptyList() benchmark.kafkaConfig = kafkaConfig diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt index 7350f564a71e2f0cbf640b782f5dbf19cbdc7ecb..73a8b9b54813be51937bc17d873ca67dc5ae8724 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt @@ -2,6 +2,7 @@ package theodolite.execution.operator import com.google.gson.Gson import com.google.gson.GsonBuilder +import io.fabric8.kubernetes.api.model.Service import io.fabric8.kubernetes.client.CustomResourceList import io.fabric8.kubernetes.client.server.mock.KubernetesServer import io.quarkus.test.junit.QuarkusTest diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt index 5598f48a2d291db4eab8563dd3325534f49b2eb6..6c94d9734b3d5f6d1cb4901d2b3bc9a473d90e79 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt @@ -10,7 +10,7 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import theodolite.k8s.K8sManager -import theodolite.k8s.K8sResourceLoader +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile import theodolite.model.crd.States import java.lang.Thread.sleep @@ -42,10 +42,10 @@ class ExecutionEventHandlerTest { this.factory = operator.getExecutionEventHandler(this.controller, server.client) this.stateHandler = TheodoliteOperator().getExecutionStateHandler(client = server.client) - this.executionVersion1 = K8sResourceLoader(server.client) + this.executionVersion1 = K8sResourceLoaderFromFile(server.client) .loadK8sResource("Execution", testResourcePath + "test-execution.yaml") - this.executionVersion2 = K8sResourceLoader(server.client) + this.executionVersion2 = K8sResourceLoaderFromFile(server.client) .loadK8sResource("Execution", testResourcePath + "test-execution-update.yaml") this.stateHandler = operator.getExecutionStateHandler(server.client) diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt index 24cb6c90d8ea222c90a398e12c7a50a2f6058a93..b435b47fddcb58d6444e1fc31304bd355a9e7783 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt @@ -8,7 +8,7 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import theodolite.k8s.K8sManager -import theodolite.k8s.K8sResourceLoader +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile import theodolite.model.crd.States import java.time.Duration @@ -19,7 +19,7 @@ class StateHandlerTest { @BeforeEach fun setUp() { server.before() - val executionResource = K8sResourceLoader(server.client) + val executionResource = K8sResourceLoaderFromFile(server.client) .loadK8sResource("Execution", testResourcePath + "test-execution.yaml") K8sManager(server.client).deploy(executionResource) diff --git a/theodolite/src/test/kotlin/theodolite/k8s/K8sManagerTest.kt b/theodolite/src/test/kotlin/theodolite/k8s/K8sManagerTest.kt index dc2bf016994d79b1021bebdc751102e291d60682..7c69618de03f730f5b6f1cb83c5df544e2cd120c 100644 --- a/theodolite/src/test/kotlin/theodolite/k8s/K8sManagerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/k8s/K8sManagerTest.kt @@ -15,6 +15,7 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile private val logger = KotlinLogging.logger {} @@ -125,7 +126,7 @@ class K8sManagerTest { @DisplayName("Test handling of custom resources") fun handleCustomResourcesTest() { val manager = K8sManager(server.client) - val servicemonitor = K8sResourceLoader(server.client) + val servicemonitor = K8sResourceLoaderFromFile(server.client) .loadK8sResource("ServiceMonitor", testResourcePath + "test-service-monitor.yaml") val serviceMonitorContext = K8sContextFactory().create( diff --git a/theodolite/src/test/kotlin/theodolite/k8s/K8sResourceLoaderTest.kt b/theodolite/src/test/kotlin/theodolite/k8s/K8sResourceLoaderTest.kt index 7c2aa50007274ff9b4d49f1c0cc05ae45a37d323..4a41dac8b27b9d4ddcfb9915f759b14ea4eaba4a 100644 --- a/theodolite/src/test/kotlin/theodolite/k8s/K8sResourceLoaderTest.kt +++ b/theodolite/src/test/kotlin/theodolite/k8s/K8sResourceLoaderTest.kt @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile @QuarkusTest class K8sResourceLoaderTest { @@ -31,7 +32,7 @@ class K8sResourceLoaderTest { @Test @DisplayName("Test loading of Deployments") fun loadDeploymentTest() { - val loader = K8sResourceLoader(server.client) + val loader = K8sResourceLoaderFromFile(server.client) val resource = loader.loadK8sResource("Deployment", testResourcePath + "test-deployment.yaml") assertTrue(resource is Deployment) @@ -41,7 +42,7 @@ class K8sResourceLoaderTest { @Test @DisplayName("Test loading of StatefulSet") fun loadStatefulSetTest() { - val loader = K8sResourceLoader(server.client) + val loader = K8sResourceLoaderFromFile(server.client) val resource = loader.loadK8sResource("StatefulSet", testResourcePath + "test-statefulset.yaml") assertTrue(resource is StatefulSet) @@ -51,7 +52,7 @@ class K8sResourceLoaderTest { @Test @DisplayName("Test loading of Service") fun loadServiceTest() { - val loader = K8sResourceLoader(server.client) + val loader = K8sResourceLoaderFromFile(server.client) val resource = loader.loadK8sResource("Service", testResourcePath + "test-service.yaml") assertTrue(resource is Service) @@ -61,7 +62,7 @@ class K8sResourceLoaderTest { @Test @DisplayName("Test loading of ConfigMap") fun loadConfigMapTest() { - val loader = K8sResourceLoader(server.client) + val loader = K8sResourceLoaderFromFile(server.client) val resource = loader.loadK8sResource("ConfigMap", testResourcePath + "test-configmap.yaml") assertTrue(resource is ConfigMap) @@ -71,7 +72,7 @@ class K8sResourceLoaderTest { @Test @DisplayName("Test loading of ServiceMonitors") fun loadServiceMonitorTest() { - val loader = K8sResourceLoader(server.client) + val loader = K8sResourceLoaderFromFile(server.client) val resource = loader.loadK8sResource("ServiceMonitor", testResourcePath + "test-service-monitor.yaml") assertTrue(resource is CustomResourceWrapper) @@ -84,7 +85,7 @@ class K8sResourceLoaderTest { @Test @DisplayName("Test loading of Executions") fun loadExecutionTest() { - val loader = K8sResourceLoader(server.client) + val loader = K8sResourceLoaderFromFile(server.client) val resource = loader.loadK8sResource("Execution", testResourcePath + "test-execution.yaml") assertTrue(resource is CustomResourceWrapper) @@ -97,7 +98,7 @@ class K8sResourceLoaderTest { @Test @DisplayName("Test loading of Benchmarks") fun loadBenchmarkTest() { - val loader = K8sResourceLoader(server.client) + val loader = K8sResourceLoaderFromFile(server.client) val resource = loader.loadK8sResource("Benchmark", testResourcePath + "test-benchmark.yaml") assertTrue(resource is CustomResourceWrapper) diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ConfigOverrideModifierTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/ConfigOverrideModifierTest.kt index 739fadd3f02bfd1e60fd67e7afc695bf99e68d31..1db1122e1caa5a783159ecaba849b99963e3c2a9 100644 --- a/theodolite/src/test/kotlin/theodolite/patcher/ConfigOverrideModifierTest.kt +++ b/theodolite/src/test/kotlin/theodolite/patcher/ConfigOverrideModifierTest.kt @@ -27,11 +27,10 @@ class ConfigOverrideModifierTest { @Test fun setAdditionalLabelsTest() { - this.benchmark.appResource = listOf("test-resource.yaml") val modifier = ConfigOverrideModifier( execution = this.execution, - resources = this.benchmark.appResource + resources = listOf("test-resource.yaml") ) modifier.setAdditionalLabels( diff --git a/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml b/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1407a9952b7454053d204454841d51cfb4d7dbf4 --- /dev/null +++ b/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml @@ -0,0 +1,28 @@ +apiVersion: theodolite.com/v1 +kind: Execution +metadata: + name: example-execution +spec: + name: test + benchmark: "uc1-kstreams" + load: + loadType: "NumSensors" + loadValues: [25000, 50000, 75000, 100000, 125000, 150000] + resources: + resourceType: "Instances" + resourceValues: [1, 2, 3, 4, 5] + slos: + - sloType: "lag trend" + threshold: 2000 + prometheusUrl: "http://prometheus-operated:9090" + externalSloUrl: "http://localhost:80/evaluate-slope" + offset: 0 + warmup: 60 # in seconds + execution: + strategy: "LinearSearch" + duration: 300 # in seconds + repetitions: 1 + loadGenerationDelay: 30 # in seconds + restrictions: + - "LowerBound" + configOverrides: []