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