From 673897815fdd1f4d0f623b66ac4069ffc34ec3c9 Mon Sep 17 00:00:00 2001 From: Sahil Lenka <76817449+Sahil-u07@users.noreply.github.com> Date: Thu, 20 Aug 2026 20:11:24 +0530 Subject: [PATCH] add back the manifestwork template the managed cluster scenarios render (#1540) the managed cluster scenarios have been loading manifestwork.j2 at runtime since the plugin was moved into scenario_plugins, but the file itself never made it into the new layout. every scenario call crashed with a TemplateNotFound error before the manifestwork was created. the template was found in the git history of the old kraken layout and restored, with the invalid namespace dropped from the ClusterRole (ClusterRoles are cluster-scoped, a namespace on one fails to apply and breaks the rbac setup for the job). added a test that checks the file is present and that it renders into a valid ManifestWork document with the variables the scenarios pass in. Signed-off-by: Sahil Lenka Co-authored-by: Paige Patton <64206430+paigerube14@users.noreply.github.com> --- .../managed_cluster/manifestwork.j2 | 67 +++++++++++++++++++ tests/test_managed_cluster_scenario_plugin.py | 67 +++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 krkn/scenario_plugins/managed_cluster/manifestwork.j2 diff --git a/krkn/scenario_plugins/managed_cluster/manifestwork.j2 b/krkn/scenario_plugins/managed_cluster/manifestwork.j2 new file mode 100644 index 00000000..a1b27866 --- /dev/null +++ b/krkn/scenario_plugins/managed_cluster/manifestwork.j2 @@ -0,0 +1,67 @@ +apiVersion: work.open-cluster-management.io/v1 +kind: ManifestWork +metadata: + namespace: {{managedcluster_name}} + name: managedcluster-scenarios-template +spec: + workload: + manifests: + - apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: scale-deploy + rules: + - apiGroups: ["apps"] + resources: ["deployments/scale"] + verbs: ["patch"] + - apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get"] + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: scale-deploy-to-sa + namespace: open-cluster-management + subjects: + - kind: ServiceAccount + name: internal-kubectl + namespace: open-cluster-management + roleRef: + kind: ClusterRole + name: scale-deploy + apiGroup: rbac.authorization.k8s.io + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: scale-deploy-to-sa + namespace: open-cluster-management-agent + subjects: + - kind: ServiceAccount + name: internal-kubectl + namespace: open-cluster-management + roleRef: + kind: ClusterRole + name: scale-deploy + apiGroup: rbac.authorization.k8s.io + - apiVersion: v1 + kind: ServiceAccount + metadata: + name: internal-kubectl + namespace: open-cluster-management + - apiVersion: batch/v1 + kind: Job + metadata: + name: managedcluster-scenarios-template + namespace: open-cluster-management + spec: + template: + spec: + serviceAccountName: internal-kubectl + containers: + - name: kubectl + image: quay.io/sighup/kubectl-kustomize:1.21.6_3.9.1 + command: ["/bin/sh", "-c"] + args: + - {{args}} + restartPolicy: Never + backoffLimit: 0 diff --git a/tests/test_managed_cluster_scenario_plugin.py b/tests/test_managed_cluster_scenario_plugin.py index 2f5a5d25..424e868a 100644 --- a/tests/test_managed_cluster_scenario_plugin.py +++ b/tests/test_managed_cluster_scenario_plugin.py @@ -404,5 +404,72 @@ class TestCommonFunctions(unittest.TestCase): ) +class TestManifestWorkTemplate(unittest.TestCase): + """ + Test suite for the manifestwork template used by the managed cluster scenarios + """ + + def test_template_file_exists(self): + """ + Test the manifestwork template file is present in the plugin directory + """ + import os + + template_path = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "krkn", + "scenario_plugins", + "managed_cluster", + "manifestwork.j2", + ) + self.assertTrue(os.path.isfile(template_path)) + + def test_template_renders_valid_manifestwork(self): + """ + Test the template renders into a valid ManifestWork document with + the variables the scenarios pass in, including multiline args + """ + import os + + import yaml + from jinja2 import Environment, FileSystemLoader + + template_dir = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "krkn", + "scenario_plugins", + "managed_cluster", + ) + env = Environment( + loader=FileSystemLoader(os.path.abspath(template_dir)), + autoescape=False, + ) + template = env.get_template("manifestwork.j2") + body = yaml.safe_load( + template.render( + managedcluster_name="test-cluster", + args="""kubectl scale deployment.apps/klusterlet --replicas 3 && + kubectl scale deployment.apps/klusterlet-registration-agent --replicas 0 -n open-cluster-management-agent""", + ) + ) + + self.assertEqual(body["kind"], "ManifestWork") + self.assertEqual(body["metadata"]["namespace"], "test-cluster") + self.assertEqual(body["apiVersion"], "work.open-cluster-management.io/v1") + manifests = body["spec"]["workload"]["manifests"] + self.assertEqual(len(manifests), 5) + cluster_role = manifests[0] + self.assertEqual(cluster_role["kind"], "ClusterRole") + self.assertNotIn("namespace", cluster_role["metadata"]) + job = manifests[4] + self.assertEqual(job["kind"], "Job") + self.assertEqual( + job["spec"]["template"]["spec"]["containers"][0]["args"][0], + "kubectl scale deployment.apps/klusterlet --replicas 3 && " + "kubectl scale deployment.apps/klusterlet-registration-agent " + "--replicas 0 -n open-cluster-management-agent", + ) + + if __name__ == "__main__": unittest.main()