From 455c418c18b2c445c096c3e67be7c451536146fa Mon Sep 17 00:00:00 2001 From: Simon Ehrenstein <stu200776@mail.uni-kiel.de> Date: Tue, 14 Jun 2022 15:06:18 +0200 Subject: [PATCH] Allow deletion of K8s resources in actions --- docs/api-reference/crds.md | 608 +++++++++++++++--- .../uc1-beam-samza-benchmark-operator.yaml | 12 +- .../uc2-beam-samza-benchmark-operator.yaml | 12 +- .../uc3-beam-samza-benchmark-operator.yaml | 12 +- .../uc4-beam-samza-benchmark-operator.yaml | 12 +- theodolite/crd/crd-benchmark.yaml | 357 +++++++--- .../rocks/theodolite/kubernetes/Action.kt | 42 +- .../theodolite/kubernetes/DeleteCommand.kt | 49 ++ .../theodolite/kubernetes/ExecCommand.kt | 41 ++ .../rocks/theodolite/kubernetes/K8sManager.kt | 2 +- .../operator/BenchmarkStateChecker.kt | 10 +- .../kubernetes/ActionCommandTest.kt | 24 +- .../operator/BenchmarkStateCheckerTest.kt | 6 +- 13 files changed, 935 insertions(+), 252 deletions(-) create mode 100644 theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt create mode 100644 theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt diff --git a/docs/api-reference/crds.md b/docs/api-reference/crds.md index f0962d474..87c4e9046 100644 --- a/docs/api-reference/crds.md +++ b/docs/api-reference/crds.md @@ -230,17 +230,87 @@ The loadGenResourceSets specifies all Kubernetes resources required to start the </tr> </thead> <tbody><tr> - <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexec">exec</a></b></td> + <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexdelete">delete</a></b></td> <td>object</td> <td> - Specifies command to be executed.<br/> + Specifies deletion of a resource.<br/> </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexselector">selector</a></b></td> + <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexec">exec</a></b></td> <td>object</td> <td> - The selector specifies which resource should be selected for the execution of the command.<br/> + Specifies a command that gets executed within a Container of a Pod<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadGenerator.afterActions[index].delete +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindex)</sup></sup> + + + +Specifies deletion of a resource. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexdeleteselector">selector</a></b></td> + <td>object</td> + <td> + Defines how to select the resource to delete.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadGenerator.afterActions[index].delete.selector +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexdelete)</sup></sup> + + + +Defines how to select the resource to delete. + +<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> + Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>kind</b></td> + <td>string</td> + <td> + Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>nameRegex</b></td> + <td>string</td> + <td> + Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/> + <br/> + <i>Default</i>: *<br/> </td> <td>false</td> </tr></tbody> @@ -252,7 +322,7 @@ The loadGenResourceSets specifies all Kubernetes resources required to start the -Specifies command to be executed. +Specifies a command that gets executed within a Container of a Pod <table> <thead> @@ -269,20 +339,27 @@ Specifies command to be executed. <td> The command to be executed as string array.<br/> </td> - <td>false</td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexecselector">selector</a></b></td> + <td>object</td> + <td> + The selector specifies which resource should be selected for the execution of the command.<br/> + </td> + <td>true</td> </tr><tr> <td><b>timeoutSeconds</b></td> <td>integer</td> <td> Specifies the timeout (in seconds) for the specified command.<br/> </td> - <td>false</td> + <td>true</td> </tr></tbody> </table> -### benchmark.spec.loadGenerator.afterActions[index].selector -<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindex)</sup></sup> +### benchmark.spec.loadGenerator.afterActions[index].exec.selector +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexexec)</sup></sup> @@ -307,7 +384,7 @@ The selector specifies which resource should be selected for the execution of th </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexselectorpod">pod</a></b></td> + <td><b><a href="#benchmarkspecloadgeneratorafteractionsindexexecselectorpod">pod</a></b></td> <td>object</td> <td> Specifies the pod.<br/> @@ -317,8 +394,8 @@ The selector specifies which resource should be selected for the execution of th </table> -### benchmark.spec.loadGenerator.afterActions[index].selector.pod -<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexselector)</sup></sup> +### benchmark.spec.loadGenerator.afterActions[index].exec.selector.pod +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorafteractionsindexexecselector)</sup></sup> @@ -363,17 +440,87 @@ Specifies the pod. </tr> </thead> <tbody><tr> - <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexec">exec</a></b></td> + <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexdelete">delete</a></b></td> <td>object</td> <td> - Specifies command to be executed.<br/> + Specifies deletion of a resource.<br/> </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexselector">selector</a></b></td> + <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexec">exec</a></b></td> <td>object</td> <td> - The selector specifies which resource should be selected for the execution of the command.<br/> + Specifies a command that gets executed within a Container of a Pod<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadGenerator.beforeActions[index].delete +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindex)</sup></sup> + + + +Specifies deletion of a resource. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexdeleteselector">selector</a></b></td> + <td>object</td> + <td> + Defines how to select the resource to delete.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.loadGenerator.beforeActions[index].delete.selector +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexdelete)</sup></sup> + + + +Defines how to select the resource to delete. + +<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> + Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>kind</b></td> + <td>string</td> + <td> + Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>nameRegex</b></td> + <td>string</td> + <td> + Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/> + <br/> + <i>Default</i>: *<br/> </td> <td>false</td> </tr></tbody> @@ -385,7 +532,7 @@ Specifies the pod. -Specifies command to be executed. +Specifies a command that gets executed within a Container of a Pod <table> <thead> @@ -402,20 +549,27 @@ Specifies command to be executed. <td> The command to be executed as string array.<br/> </td> - <td>false</td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexecselector">selector</a></b></td> + <td>object</td> + <td> + The selector specifies which resource should be selected for the execution of the command.<br/> + </td> + <td>true</td> </tr><tr> <td><b>timeoutSeconds</b></td> <td>integer</td> <td> Specifies the timeout (in seconds) for the specified command.<br/> </td> - <td>false</td> + <td>true</td> </tr></tbody> </table> -### benchmark.spec.loadGenerator.beforeActions[index].selector -<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindex)</sup></sup> +### benchmark.spec.loadGenerator.beforeActions[index].exec.selector +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexexec)</sup></sup> @@ -440,7 +594,7 @@ The selector specifies which resource should be selected for the execution of th </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexselectorpod">pod</a></b></td> + <td><b><a href="#benchmarkspecloadgeneratorbeforeactionsindexexecselectorpod">pod</a></b></td> <td>object</td> <td> Specifies the pod.<br/> @@ -450,8 +604,8 @@ The selector specifies which resource should be selected for the execution of th </table> -### benchmark.spec.loadGenerator.beforeActions[index].selector.pod -<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexselector)</sup></sup> +### benchmark.spec.loadGenerator.beforeActions[index].exec.selector.pod +<sup><sup>[↩ Parent](#benchmarkspecloadgeneratorbeforeactionsindexexecselector)</sup></sup> @@ -820,7 +974,7 @@ The appResourceSets specifies all Kubernetes resources required to start the sut <td><b><a href="#benchmarkspecsutafteractionsindex">afterActions</a></b></td> <td>[]object</td> <td> - <br/> + SUT after actions are executed after the teardown of the SUT.<br/> <br/> <i>Default</i>: []<br/> </td> @@ -864,17 +1018,87 @@ The appResourceSets specifies all Kubernetes resources required to start the sut </tr> </thead> <tbody><tr> - <td><b><a href="#benchmarkspecsutafteractionsindexexec">exec</a></b></td> + <td><b><a href="#benchmarkspecsutafteractionsindexdelete">delete</a></b></td> <td>object</td> <td> - Specifies command to be executed.<br/> + Specifies deletion of a resource.<br/> </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecsutafteractionsindexselector">selector</a></b></td> + <td><b><a href="#benchmarkspecsutafteractionsindexexec">exec</a></b></td> <td>object</td> <td> - The selector specifies which resource should be selected for the execution of the command.<br/> + Specifies a command that gets executed within a Container of a Pod<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.sut.afterActions[index].delete +<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindex)</sup></sup> + + + +Specifies deletion of a resource. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecsutafteractionsindexdeleteselector">selector</a></b></td> + <td>object</td> + <td> + Defines how to select the resource to delete.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.sut.afterActions[index].delete.selector +<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexdelete)</sup></sup> + + + +Defines how to select the resource to delete. + +<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> + Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>kind</b></td> + <td>string</td> + <td> + Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>nameRegex</b></td> + <td>string</td> + <td> + Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/> + <br/> + <i>Default</i>: *<br/> </td> <td>false</td> </tr></tbody> @@ -886,7 +1110,7 @@ The appResourceSets specifies all Kubernetes resources required to start the sut -Specifies command to be executed. +Specifies a command that gets executed within a Container of a Pod <table> <thead> @@ -903,20 +1127,27 @@ Specifies command to be executed. <td> The command to be executed as string array.<br/> </td> - <td>false</td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecsutafteractionsindexexecselector">selector</a></b></td> + <td>object</td> + <td> + The selector specifies which resource should be selected for the execution of the command.<br/> + </td> + <td>true</td> </tr><tr> <td><b>timeoutSeconds</b></td> <td>integer</td> <td> Specifies the timeout (in seconds) for the specified command.<br/> </td> - <td>false</td> + <td>true</td> </tr></tbody> </table> -### benchmark.spec.sut.afterActions[index].selector -<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindex)</sup></sup> +### benchmark.spec.sut.afterActions[index].exec.selector +<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexexec)</sup></sup> @@ -941,7 +1172,7 @@ The selector specifies which resource should be selected for the execution of th </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecsutafteractionsindexselectorpod">pod</a></b></td> + <td><b><a href="#benchmarkspecsutafteractionsindexexecselectorpod">pod</a></b></td> <td>object</td> <td> Specifies the pod.<br/> @@ -951,8 +1182,8 @@ The selector specifies which resource should be selected for the execution of th </table> -### benchmark.spec.sut.afterActions[index].selector.pod -<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexselector)</sup></sup> +### benchmark.spec.sut.afterActions[index].exec.selector.pod +<sup><sup>[↩ Parent](#benchmarkspecsutafteractionsindexexecselector)</sup></sup> @@ -997,17 +1228,87 @@ Specifies the pod. </tr> </thead> <tbody><tr> - <td><b><a href="#benchmarkspecsutbeforeactionsindexexec">exec</a></b></td> + <td><b><a href="#benchmarkspecsutbeforeactionsindexdelete">delete</a></b></td> <td>object</td> <td> - Specifies command to be executed.<br/> + Specifies deletion of a resource.<br/> </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecsutbeforeactionsindexselector">selector</a></b></td> + <td><b><a href="#benchmarkspecsutbeforeactionsindexexec">exec</a></b></td> <td>object</td> <td> - The selector specifies which resource should be selected for the execution of the command.<br/> + Specifies a command that gets executed within a Container of a Pod<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.sut.beforeActions[index].delete +<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindex)</sup></sup> + + + +Specifies deletion of a resource. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecsutbeforeactionsindexdeleteselector">selector</a></b></td> + <td>object</td> + <td> + Defines how to select the resource to delete.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.sut.beforeActions[index].delete.selector +<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexdelete)</sup></sup> + + + +Defines how to select the resource to delete. + +<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> + Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>kind</b></td> + <td>string</td> + <td> + Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>nameRegex</b></td> + <td>string</td> + <td> + Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/> + <br/> + <i>Default</i>: *<br/> </td> <td>false</td> </tr></tbody> @@ -1019,7 +1320,7 @@ Specifies the pod. -Specifies command to be executed. +Specifies a command that gets executed within a Container of a Pod <table> <thead> @@ -1036,20 +1337,27 @@ Specifies command to be executed. <td> The command to be executed as string array.<br/> </td> - <td>false</td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecsutbeforeactionsindexexecselector">selector</a></b></td> + <td>object</td> + <td> + The selector specifies which resource should be selected for the execution of the command.<br/> + </td> + <td>true</td> </tr><tr> <td><b>timeoutSeconds</b></td> <td>integer</td> <td> Specifies the timeout (in seconds) for the specified command.<br/> </td> - <td>false</td> + <td>true</td> </tr></tbody> </table> -### benchmark.spec.sut.beforeActions[index].selector -<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindex)</sup></sup> +### benchmark.spec.sut.beforeActions[index].exec.selector +<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexexec)</sup></sup> @@ -1074,7 +1382,7 @@ The selector specifies which resource should be selected for the execution of th </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecsutbeforeactionsindexselectorpod">pod</a></b></td> + <td><b><a href="#benchmarkspecsutbeforeactionsindexexecselectorpod">pod</a></b></td> <td>object</td> <td> Specifies the pod.<br/> @@ -1084,8 +1392,8 @@ The selector specifies which resource should be selected for the execution of th </table> -### benchmark.spec.sut.beforeActions[index].selector.pod -<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexselector)</sup></sup> +### benchmark.spec.sut.beforeActions[index].exec.selector.pod +<sup><sup>[↩ Parent](#benchmarkspecsutbeforeactionsindexexecselector)</sup></sup> @@ -1279,17 +1587,87 @@ The fileSystem resourceSet loads the Kubernetes manifests from the filesystem. </tr> </thead> <tbody><tr> - <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexec">exec</a></b></td> + <td><b><a href="#benchmarkspecinfrastructureafteractionsindexdelete">delete</a></b></td> <td>object</td> <td> - Specifies command to be executed.<br/> + Specifies deletion of a resource.<br/> </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecinfrastructureafteractionsindexselector">selector</a></b></td> + <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexec">exec</a></b></td> <td>object</td> <td> - The selector specifies which resource should be selected for the execution of the command.<br/> + Specifies a command that gets executed within a Container of a Pod<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.infrastructure.afterActions[index].delete +<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindex)</sup></sup> + + + +Specifies deletion of a resource. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecinfrastructureafteractionsindexdeleteselector">selector</a></b></td> + <td>object</td> + <td> + Defines how to select the resource to delete.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.infrastructure.afterActions[index].delete.selector +<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexdelete)</sup></sup> + + + +Defines how to select the resource to delete. + +<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> + Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>kind</b></td> + <td>string</td> + <td> + Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>nameRegex</b></td> + <td>string</td> + <td> + Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/> + <br/> + <i>Default</i>: *<br/> </td> <td>false</td> </tr></tbody> @@ -1301,7 +1679,7 @@ The fileSystem resourceSet loads the Kubernetes manifests from the filesystem. -Specifies command to be executed. +Specifies a command that gets executed within a Container of a Pod <table> <thead> @@ -1318,20 +1696,27 @@ Specifies command to be executed. <td> The command to be executed as string array.<br/> </td> - <td>false</td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexecselector">selector</a></b></td> + <td>object</td> + <td> + The selector specifies which resource should be selected for the execution of the command.<br/> + </td> + <td>true</td> </tr><tr> <td><b>timeoutSeconds</b></td> <td>integer</td> <td> Specifies the timeout (in seconds) for the specified command.<br/> </td> - <td>false</td> + <td>true</td> </tr></tbody> </table> -### benchmark.spec.infrastructure.afterActions[index].selector -<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindex)</sup></sup> +### benchmark.spec.infrastructure.afterActions[index].exec.selector +<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexexec)</sup></sup> @@ -1356,7 +1741,7 @@ The selector specifies which resource should be selected for the execution of th </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecinfrastructureafteractionsindexselectorpod">pod</a></b></td> + <td><b><a href="#benchmarkspecinfrastructureafteractionsindexexecselectorpod">pod</a></b></td> <td>object</td> <td> Specifies the pod.<br/> @@ -1366,8 +1751,8 @@ The selector specifies which resource should be selected for the execution of th </table> -### benchmark.spec.infrastructure.afterActions[index].selector.pod -<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexselector)</sup></sup> +### benchmark.spec.infrastructure.afterActions[index].exec.selector.pod +<sup><sup>[↩ Parent](#benchmarkspecinfrastructureafteractionsindexexecselector)</sup></sup> @@ -1412,17 +1797,87 @@ Specifies the pod. </tr> </thead> <tbody><tr> - <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexec">exec</a></b></td> + <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexdelete">delete</a></b></td> <td>object</td> <td> - Specifies command to be executed.<br/> + Specifies deletion of a resource.<br/> </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexselector">selector</a></b></td> + <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexec">exec</a></b></td> <td>object</td> <td> - The selector specifies which resource should be selected for the execution of the command.<br/> + Specifies a command that gets executed within a Container of a Pod<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + +### benchmark.spec.infrastructure.beforeActions[index].delete +<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindex)</sup></sup> + + + +Specifies deletion of a resource. + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexdeleteselector">selector</a></b></td> + <td>object</td> + <td> + Defines how to select the resource to delete.<br/> + </td> + <td>true</td> + </tr></tbody> +</table> + + +### benchmark.spec.infrastructure.beforeActions[index].delete.selector +<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexdelete)</sup></sup> + + + +Defines how to select the resource to delete. + +<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> + Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>kind</b></td> + <td>string</td> + <td> + Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'.<br/> + </td> + <td>true</td> + </tr><tr> + <td><b>nameRegex</b></td> + <td>string</td> + <td> + Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted.<br/> + <br/> + <i>Default</i>: *<br/> </td> <td>false</td> </tr></tbody> @@ -1434,7 +1889,7 @@ Specifies the pod. -Specifies command to be executed. +Specifies a command that gets executed within a Container of a Pod <table> <thead> @@ -1451,20 +1906,27 @@ Specifies command to be executed. <td> The command to be executed as string array.<br/> </td> - <td>false</td> + <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexecselector">selector</a></b></td> + <td>object</td> + <td> + The selector specifies which resource should be selected for the execution of the command.<br/> + </td> + <td>true</td> </tr><tr> <td><b>timeoutSeconds</b></td> <td>integer</td> <td> Specifies the timeout (in seconds) for the specified command.<br/> </td> - <td>false</td> + <td>true</td> </tr></tbody> </table> -### benchmark.spec.infrastructure.beforeActions[index].selector -<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindex)</sup></sup> +### benchmark.spec.infrastructure.beforeActions[index].exec.selector +<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexexec)</sup></sup> @@ -1489,7 +1951,7 @@ The selector specifies which resource should be selected for the execution of th </td> <td>false</td> </tr><tr> - <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexselectorpod">pod</a></b></td> + <td><b><a href="#benchmarkspecinfrastructurebeforeactionsindexexecselectorpod">pod</a></b></td> <td>object</td> <td> Specifies the pod.<br/> @@ -1499,8 +1961,8 @@ The selector specifies which resource should be selected for the execution of th </table> -### benchmark.spec.infrastructure.beforeActions[index].selector.pod -<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexselector)</sup></sup> +### benchmark.spec.infrastructure.beforeActions[index].exec.selector.pod +<sup><sup>[↩ Parent](#benchmarkspecinfrastructurebeforeactionsindexexecselector)</sup></sup> diff --git a/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml index ce07d7565..d3ee8f524 100644 --- a/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc1-beam-samza/uc1-beam-samza-benchmark-operator.yaml @@ -12,12 +12,12 @@ spec: - "beam-samza-service.yaml" - "service-monitor.yaml" afterActions: - - selector: # delete zookeeper nodes to reset zookeeper - pod: - matchLabels: - app: "zookeeper-client" - container: "zookeeper-client" - exec: + - exec: + selector: # delete zookeeper nodes to reset zookeeper + pod: + matchLabels: + app: "zookeeper-client" + container: "zookeeper-client" command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc1-application-1"] timeoutSeconds: 60 loadGenerator: diff --git a/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml index 215b92343..619e87b60 100644 --- a/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc2-beam-samza/uc2-beam-samza-benchmark-operator.yaml @@ -12,12 +12,12 @@ spec: - "beam-samza-service.yaml" - "service-monitor.yaml" afterActions: - - selector: # delete zookeeper nodes to reset zookeeper - pod: - matchLabels: - app: "zookeeper-client" - container: "zookeeper-client" - exec: + - exec: + selector: # delete zookeeper nodes to reset zookeeper + pod: + matchLabels: + app: "zookeeper-client" + container: "zookeeper-client" command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc2-application-1"] timeoutSeconds: 60 loadGenerator: diff --git a/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml index a7ff35582..2dd5fcdf3 100644 --- a/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc3-beam-samza/uc3-beam-samza-benchmark-operator.yaml @@ -12,12 +12,12 @@ spec: - "beam-samza-service.yaml" - "service-monitor.yaml" afterActions: - - selector: # delete zookeeper nodes to reset zookeeper - pod: - matchLabels: - app: "zookeeper-client" - container: "zookeeper-client" - exec: + - exec: + selector: # delete zookeeper nodes to reset zookeeper + pod: + matchLabels: + app: "zookeeper-client" + container: "zookeeper-client" command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc3-application-1"] timeoutSeconds: 60 loadGenerator: diff --git a/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml index f9950e588..8835db1d3 100644 --- a/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc4-beam-samza/uc4-beam-samza-benchmark-operator.yaml @@ -12,12 +12,12 @@ spec: - "beam-samza-service.yaml" - "service-monitor.yaml" afterActions: - - selector: # delete zookeeper nodes to reset zookeeper - pod: - matchLabels: - app: "zookeeper-client" - container: "zookeeper-client" - exec: + - exec: + selector: # delete zookeeper nodes to reset zookeeper + pod: + matchLabels: + app: "zookeeper-client" + container: "zookeeper-client" command: ["bash", "-c", "bin/zkCli.sh -server $ZOOKEEPER_SERVER deleteall /app-theodolite-uc4-application-1"] timeoutSeconds: 60 loadGenerator: diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml index d73ec0105..cfc9d3bd6 100644 --- a/theodolite/crd/crd-benchmark.yaml +++ b/theodolite/crd/crd-benchmark.yaml @@ -74,29 +74,33 @@ spec: description: Infrastructure before actions are executed before the infrastructure is set up. items: type: object + anyOf: + - required: [ exec ] + - required: [ delete ] properties: - selector: + exec: type: object - description: The selector specifies which resource should be selected for the execution of the command. + description: Specifies a command that gets executed within a Container of a Pod + required: [ selector, command, timeoutSeconds ] properties: - pod: + selector: type: object - description: Specifies the pod. + description: The selector specifies which resource should be selected for the execution of the command. properties: - matchLabels: + pod: type: object - description: The matchLabels of the desired pod. - additionalProperties: true - x-kubernetes-map-type: "granular" - default: { } - container: - description: Specifies the container. - default: "" - type: string - exec: - type: object - description: Specifies command to be executed. - properties: + description: Specifies the pod. + properties: + matchLabels: + type: object + description: The matchLabels of the desired pod. + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + description: Specifies the container. + default: "" + type: string command: type: array description: The command to be executed as string array. @@ -105,35 +109,59 @@ spec: timeoutSeconds: description: Specifies the timeout (in seconds) for the specified command. type: integer + delete: + type: object + description: Specifies deletion of a resource. + required: [ selector ] + properties: + selector: + type: object + description: Defines how to select the resource to delete. + required: [ apiVersion, kind ] + properties: + apiVersion: + type: string + description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'. + kind: + type: string + description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'. + nameRegex: + type: string + description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted. + default: "*" afterActions: type: array - default: [] + default: [ ] description: Infrastructure after actions are executed after the teardown of the infrastructure. items: type: object + anyOf: + - required: [ exec ] + - required: [ delete ] properties: - selector: + exec: type: object - description: The selector specifies which resource should be selected for the execution of the command. + description: Specifies a command that gets executed within a Container of a Pod + required: [ selector, command, timeoutSeconds ] properties: - pod: + selector: type: object - description: Specifies the pod. + description: The selector specifies which resource should be selected for the execution of the command. properties: - matchLabels: + pod: type: object - description: The matchLabels of the desired pod. - additionalProperties: true - x-kubernetes-map-type: "granular" - default: { } - container: - description: Specifies the container. - default: "" - type: string - exec: - type: object - description: Specifies command to be executed. - properties: + description: Specifies the pod. + properties: + matchLabels: + type: object + description: The matchLabels of the desired pod. + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + description: Specifies the container. + default: "" + type: string command: type: array description: The command to be executed as string array. @@ -142,6 +170,26 @@ spec: timeoutSeconds: description: Specifies the timeout (in seconds) for the specified command. type: integer + delete: + type: object + description: Specifies deletion of a resource. + required: [ selector ] + properties: + selector: + type: object + description: Defines how to select the resource to delete. + required: [ apiVersion, kind ] + properties: + apiVersion: + type: string + description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'. + kind: + type: string + description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'. + nameRegex: + type: string + description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted. + default: "*" sut: 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: object @@ -181,33 +229,37 @@ spec: type: string beforeActions: type: array - default: [] + default: [ ] description: SUT before actions are executed before the SUT is started. items: type: object + anyOf: + - required: [ exec ] + - required: [ delete ] properties: - selector: + exec: type: object - description: The selector specifies which resource should be selected for the execution of the command. + description: Specifies a command that gets executed within a Container of a Pod + required: [ selector, command, timeoutSeconds ] properties: - pod: + selector: type: object - description: Specifies the pod. + description: The selector specifies which resource should be selected for the execution of the command. properties: - matchLabels: + pod: type: object - description: The matchLabels of the desired pod. - additionalProperties: true - x-kubernetes-map-type: "granular" - default: { } - container: - description: Specifies the container. - default: "" - type: string - exec: - type: object - description: Specifies command to be executed. - properties: + description: Specifies the pod. + properties: + matchLabels: + type: object + description: The matchLabels of the desired pod. + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + description: Specifies the container. + default: "" + type: string command: type: array description: The command to be executed as string array. @@ -216,34 +268,59 @@ spec: timeoutSeconds: description: Specifies the timeout (in seconds) for the specified command. type: integer + delete: + type: object + description: Specifies deletion of a resource. + required: [ selector ] + properties: + selector: + type: object + description: Defines how to select the resource to delete. + required: [ apiVersion, kind ] + properties: + apiVersion: + type: string + description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'. + kind: + type: string + description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'. + nameRegex: + type: string + description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted. + default: "*" afterActions: type: array - default: [] + default: [ ] + description: SUT after actions are executed after the teardown of the SUT. items: type: object + anyOf: + - required: [ exec ] + - required: [ delete ] properties: - selector: + exec: type: object - description: The selector specifies which resource should be selected for the execution of the command. + description: Specifies a command that gets executed within a Container of a Pod + required: [ selector, command, timeoutSeconds ] properties: - pod: + selector: type: object - description: Specifies the pod. + description: The selector specifies which resource should be selected for the execution of the command. properties: - matchLabels: + pod: type: object - description: The matchLabels of the desired pod. - additionalProperties: true - x-kubernetes-map-type: "granular" - default: { } - container: - description: Specifies the container. - default: "" - type: string - exec: - type: object - description: Specifies command to be executed. - properties: + description: Specifies the pod. + properties: + matchLabels: + type: object + description: The matchLabels of the desired pod. + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + description: Specifies the container. + default: "" + type: string command: type: array description: The command to be executed as string array. @@ -252,6 +329,26 @@ spec: timeoutSeconds: description: Specifies the timeout (in seconds) for the specified command. type: integer + delete: + type: object + description: Specifies deletion of a resource. + required: [ selector ] + properties: + selector: + type: object + description: Defines how to select the resource to delete. + required: [ apiVersion, kind ] + properties: + apiVersion: + type: string + description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'. + kind: + type: string + description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'. + nameRegex: + type: string + description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted. + default: "*" loadGenerator: 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: object @@ -295,29 +392,33 @@ spec: description: Load generator before actions are executed before the load generator is started. items: type: object + anyOf: + - required: [ exec ] + - required: [ delete ] properties: - selector: + exec: type: object - description: The selector specifies which resource should be selected for the execution of the command. + description: Specifies a command that gets executed within a Container of a Pod + required: [ selector, command, timeoutSeconds ] properties: - pod: + selector: type: object - description: Specifies the pod. + description: The selector specifies which resource should be selected for the execution of the command. properties: - matchLabels: + pod: type: object - description: The matchLabels of the desired pod. - additionalProperties: true - x-kubernetes-map-type: "granular" - default: { } - container: - description: Specifies the container. - default: "" - type: string - exec: - type: object - description: Specifies command to be executed. - properties: + description: Specifies the pod. + properties: + matchLabels: + type: object + description: The matchLabels of the desired pod. + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + description: Specifies the container. + default: "" + type: string command: type: array description: The command to be executed as string array. @@ -326,35 +427,59 @@ spec: timeoutSeconds: description: Specifies the timeout (in seconds) for the specified command. type: integer + delete: + type: object + description: Specifies deletion of a resource. + required: [ selector ] + properties: + selector: + type: object + description: Defines how to select the resource to delete. + required: [ apiVersion, kind ] + properties: + apiVersion: + type: string + description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'. + kind: + type: string + description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'. + nameRegex: + type: string + description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted. + default: "*" afterActions: type: array - default: [] + default: [ ] description: Load generator after actions are executed after the teardown of the load generator. items: type: object + anyOf: + - required: [ exec ] + - required: [ delete ] properties: - selector: + exec: type: object - description: The selector specifies which resource should be selected for the execution of the command. + description: Specifies a command that gets executed within a Container of a Pod + required: [ selector, command, timeoutSeconds ] properties: - pod: + selector: type: object - description: Specifies the pod. + description: The selector specifies which resource should be selected for the execution of the command. properties: - matchLabels: + pod: type: object - description: The matchLabels of the desired pod. - additionalProperties: true - x-kubernetes-map-type: "granular" - default: { } - container: - description: Specifies the container. - default: "" - type: string - exec: - type: object - description: Specifies command to be executed. - properties: + description: Specifies the pod. + properties: + matchLabels: + type: object + description: The matchLabels of the desired pod. + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + description: Specifies the container. + default: "" + type: string command: type: array description: The command to be executed as string array. @@ -363,6 +488,26 @@ spec: timeoutSeconds: description: Specifies the timeout (in seconds) for the specified command. type: integer + delete: + type: object + description: Specifies deletion of a resource. + required: [ selector ] + properties: + selector: + type: object + description: Defines how to select the resource to delete. + required: [ apiVersion, kind ] + properties: + apiVersion: + type: string + description: Specifies the api/version of the resource that should be deleted, e.g. 'kafka.strimzi.io/v1beta2'. + kind: + type: string + description: Specifies the Kind of the resource that should be deleted, e.g. 'KafkaTopic'. + nameRegex: + type: string + description: Specifies a regular expression that is matched with the metadata.name property of all resources with given api/version and Kind that should be deleted. + default: "*" 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 diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt index 2ecf48632..bdabb7196 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Action.kt @@ -1,47 +1,31 @@ package rocks.theodolite.kubernetes import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection - @JsonDeserialize @RegisterForReflection @JsonInclude(JsonInclude.Include.NON_NULL) class Action { - lateinit var selector: ActionSelector - lateinit var exec: Command + @JsonProperty("exec") + @JsonInclude(JsonInclude.Include.NON_NULL) + var execCommand: ExecCommand? = null + @JsonProperty("delete") + @JsonInclude(JsonInclude.Include.NON_NULL) + var deleteCommand: DeleteCommand? = null fun exec(client: NamespacedKubernetesClient) { - val exitCode = ActionCommand(client = client) - .exec( - matchLabels = selector.pod.matchLabels, - container = selector.container, - timeout = exec.timeoutSeconds, - command = exec.command - ) - if (exitCode != 0){ - throw ActionCommandFailedException("Error while executing action, finished with exit code $exitCode") + return if (execCommand != null) { + execCommand?.exec(client= client) !! + } else if (deleteCommand != null) { + deleteCommand?.exec(client= client ) !! + } else { + throw DeploymentFailedException("Could not execute action. The action type must either be 'exec' or 'delete'.") } } -} -@JsonDeserialize -@RegisterForReflection -class ActionSelector { - lateinit var pod: PodSelector - var container: String = "" } -@JsonDeserialize -@RegisterForReflection -class PodSelector { - lateinit var matchLabels: Map<String, String> -} -@JsonDeserialize -@RegisterForReflection -class Command { - lateinit var command: Array<String> - var timeoutSeconds: Long = Configuration.TIMEOUT_SECONDS -} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt new file mode 100644 index 000000000..ef4409e5b --- /dev/null +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/DeleteCommand.kt @@ -0,0 +1,49 @@ +package rocks.theodolite.kubernetes + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import io.fabric8.kubernetes.client.KubernetesClientException +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.quarkus.runtime.annotations.RegisterForReflection +import mu.KotlinLogging + +private val logger = KotlinLogging.logger {} + +@JsonDeserialize +@RegisterForReflection +@JsonInclude(JsonInclude.Include.NON_NULL) +class DeleteCommand { + + lateinit var selector: DeleteActionSelector + + fun exec(client: NamespacedKubernetesClient) { + logger.info { "Deleting all resources with apiVersion ${selector.apiVersion} and Kind ${selector.kind} matching regular expression ${selector.nameRegex}" } + val regExp = selector.nameRegex.toRegex() + val k8sManager = K8sManager(client) + client + .genericKubernetesResources(selector.apiVersion, selector.kind) + .inNamespace(client.namespace) + .list() + .items + .filter { regExp.matches(it.metadata.name) } + .forEach{ + logger.info { "Deleting resource ${it.metadata.name} of Kind ${it.kind} and api/version ${it.apiVersion}." } + try { + k8sManager.remove(it) + } catch (e: KubernetesClientException) { + logger.error { "An error occured when deleting resource ${it.metadata.name} of Kind ${it.kind} and api/version ${it.apiVersion}. Error: ${e.message}"} + } + } + } +} + +@JsonDeserialize +@RegisterForReflection +class DeleteActionSelector { + @JsonInclude(JsonInclude.Include.NON_NULL) + lateinit var apiVersion: String + @JsonInclude(JsonInclude.Include.NON_NULL) + lateinit var kind: String + @JsonInclude(JsonInclude.Include.NON_NULL) + lateinit var nameRegex: String +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt new file mode 100644 index 000000000..b8ce10efc --- /dev/null +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/ExecCommand.kt @@ -0,0 +1,41 @@ +package rocks.theodolite.kubernetes + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.quarkus.runtime.annotations.RegisterForReflection + +@JsonDeserialize +@RegisterForReflection +@JsonInclude(JsonInclude.Include.NON_NULL) +class ExecCommand { + lateinit var selector: ExecActionSelector + lateinit var command: Array<String> + var timeoutSeconds: Long = Configuration.TIMEOUT_SECONDS + fun exec(client: NamespacedKubernetesClient) { + val exitCode = ActionCommand(client = client) + .exec( + matchLabels = selector.pod.matchLabels, + container = selector.container, + timeout = timeoutSeconds, + command = command + ) + if (exitCode != 0){ + throw ActionCommandFailedException("Error while executing action, finished with exit code $exitCode") + } + } +} + +@JsonDeserialize +@RegisterForReflection +class ExecActionSelector { + @JsonInclude(JsonInclude.Include.NON_NULL) + lateinit var pod: PodSelector + @JsonInclude(JsonInclude.Include.NON_NULL) + var container: String = "" +} +@JsonDeserialize +@RegisterForReflection +class PodSelector { + lateinit var matchLabels: Map<String, String> +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt index 1da763a35..7856451ed 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/K8sManager.kt @@ -25,7 +25,7 @@ class K8sManager(private val client: NamespacedKubernetesClient) { /** * Removes different k8s resources using the client. - * @throws IllegalArgumentException if KubernetesResource not supported. + * @throws KubernetesClientException if an error occurs in the underlying NamespacedKubernetesClient when deleting the resource. */ fun remove(resource: HasMetadata, blockUntilDeleted: Boolean = true) { client.resource(resource).delete() diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt index 90229d953..c2c7db6cd 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt @@ -5,8 +5,8 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.fabric8.kubernetes.client.dsl.MixedOperation import io.fabric8.kubernetes.client.dsl.Resource +import rocks.theodolite.kubernetes.ExecActionSelector import rocks.theodolite.kubernetes.Action -import rocks.theodolite.kubernetes.ActionSelector import rocks.theodolite.kubernetes.model.KubernetesBenchmark import rocks.theodolite.kubernetes.ResourceSets import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD @@ -14,6 +14,7 @@ import rocks.theodolite.kubernetes.model.crd.BenchmarkState import rocks.theodolite.kubernetes.model.crd.KubernetesBenchmarkList import rocks.theodolite.kubernetes.loadKubernetesResources + class BenchmarkStateChecker( private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>, private val benchmarkStateHandler: BenchmarkStateHandler, @@ -92,7 +93,7 @@ class BenchmarkStateChecker( */ private fun checkIfActionPossible(resourcesSets: List<ResourceSets>, actions: List<Action>): Boolean { return !actions.map { - checkIfResourceIsDeployed(it.selector) || checkIfResourceIsInfrastructure(resourcesSets, it.selector) + it.deleteCommand != null || checkIfResourceIsDeployed(it.execCommand!!.selector) || checkIfResourceIsInfrastructure(resourcesSets, it.execCommand!!.selector) }.contains(false) } @@ -102,7 +103,7 @@ class BenchmarkStateChecker( * @param selector the actionSelector to check * @return true if the required resources are found, else false */ - fun checkIfResourceIsDeployed(selector: ActionSelector): Boolean { + fun checkIfResourceIsDeployed(selector: ExecActionSelector): Boolean { val pods = this.client .pods() .withLabels(selector.pod.matchLabels) @@ -129,8 +130,9 @@ class BenchmarkStateChecker( * @param selector the actionSelector to check * @return true if the required resources are found, else false */ - fun checkIfResourceIsInfrastructure(resourcesSets: List<ResourceSets>, selector: ActionSelector): Boolean { + fun checkIfResourceIsInfrastructure(resourcesSets: List<ResourceSets>, selector: ExecActionSelector): Boolean { val resources = loadKubernetesResources(resourcesSets, this.client) + if (resources.isEmpty()) { return false } diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt index afc86fc26..008bc302f 100644 --- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt +++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/ActionCommandTest.kt @@ -99,12 +99,12 @@ class ActionCommandTest { @Test fun testActionSuccess() { val action = Action() - action.selector = ActionSelector() - action.selector.pod = PodSelector() - action.selector.pod.matchLabels = mapOf("app" to "pod") - action.exec = Command() - action.exec.command = arrayOf("ls") - action.exec.timeoutSeconds = 10L + action.execCommand = ExecCommand() + action.execCommand!!.selector = ExecActionSelector() + action.execCommand!!.selector.pod = PodSelector() + action.execCommand!!.selector.pod.matchLabels = mutableMapOf("app" to "pod") + action.execCommand!!.command = arrayOf("ls") + action.execCommand!!.timeoutSeconds = 10L action.exec(server.client) assertEquals( @@ -115,12 +115,12 @@ class ActionCommandTest { @Test fun testActionFailed() { val action = Action() - action.selector = ActionSelector() - action.selector.pod = PodSelector() - action.selector.pod.matchLabels = mapOf("app" to "pod") - action.exec = Command() - action.exec.command = arrayOf("error-command") - action.exec.timeoutSeconds = 10L + action.execCommand = ExecCommand() + action.execCommand!!.selector = ExecActionSelector() + action.execCommand!!.selector.pod = PodSelector() + action.execCommand!!.selector.pod.matchLabels = mapOf("app" to "pod") + action.execCommand!!.command = arrayOf("error-command") + action.execCommand!!.timeoutSeconds = 10L assertThrows<ActionCommandFailedException> { run { action.exec(server.client) } } } diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateCheckerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateCheckerTest.kt index d90092221..465233a5d 100644 --- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateCheckerTest.kt +++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateCheckerTest.kt @@ -13,11 +13,11 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.Assertions.* -import rocks.theodolite.kubernetes.ActionSelector import rocks.theodolite.kubernetes.model.crd.BenchmarkState import rocks.theodolite.kubernetes.model.KubernetesBenchmark import rocks.theodolite.kubernetes.model.crd.BenchmarkCRDummy import rocks.theodolite.kubernetes.ConfigMapResourceSet +import rocks.theodolite.kubernetes.ExecActionSelector import rocks.theodolite.kubernetes.PodSelector import rocks.theodolite.kubernetes.ResourceSets @@ -110,9 +110,9 @@ internal class BenchmarkStateCheckerTest { .build() } - private fun getActionSelector(label: Pair<String, String>): ActionSelector { + private fun getActionSelector(label: Pair<String, String>): ExecActionSelector { val podSelector = PodSelector() - val actionSelector = ActionSelector() + val actionSelector = ExecActionSelector() actionSelector.pod = podSelector // pod with matching labels are deployed -- GitLab