diff --git a/kagenti-operator/config/rbac/role.yaml b/kagenti-operator/config/rbac/role.yaml index 50fefe6d..6c25be22 100644 --- a/kagenti-operator/config/rbac/role.yaml +++ b/kagenti-operator/config/rbac/role.yaml @@ -28,10 +28,10 @@ rules: - "" resources: - namespaces - - services verbs: - get - list + - patch - watch - apiGroups: - "" @@ -51,6 +51,14 @@ rules: - create - get - update +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch - apiGroups: - agent.kagenti.dev resources: diff --git a/kagenti-operator/docs/api-reference.md b/kagenti-operator/docs/api-reference.md index 9f8d9807..72d4253b 100644 --- a/kagenti-operator/docs/api-reference.md +++ b/kagenti-operator/docs/api-reference.md @@ -476,7 +476,13 @@ The AgentRuntime controller applies the following labels and annotations to the | `Ready` | True | `Configured` | Labels and config-hash applied to the target workload | | `Ready` | False | `ConfigHashError` | Failed to compute the config hash | | `Ready` | False | `ConfigApplyError` | Failed to apply labels/annotations to the workload | +| `IstioMeshEnrolled` | True | `NamespaceLabeled` | Namespace labeled with `istio-discovery=enabled` and `istio.io/dataplane-mode=ambient` for Istio ambient mesh enrollment | +| `IstioMeshEnrolled` | False | `OptedOut` | Namespace has `kagenti.io/istio-mesh=disabled` annotation; Istio mesh labels not applied | +| `IstioMeshEnrolled` | False | `PatchFailed` | Failed to patch namespace labels (e.g., RBAC misconfiguration). Non-fatal; reconcile continues. | | `SkillsDiscovered` | True | `SkillsFound` | Linked skills discovered from `kagenti.io/skills` annotation on the target workload | +| `SkillsMounted` | True | `SkillsApplied` | OCI skill ImageVolumes applied to the target workload | +| `SkillsMounted` | False | `FeatureGateDisabled` | Skills defined but `skillImageVolumes` feature gate is disabled | +| `SkillsMounted` | False | `UnsupportedWorkloadKind` | Skills defined but the target workload kind (e.g., Sandbox) does not support skill ImageVolumes | ### Admission Validation diff --git a/kagenti-operator/docs/architecture.md b/kagenti-operator/docs/architecture.md index 4b3096ad..a7d32274 100644 --- a/kagenti-operator/docs/architecture.md +++ b/kagenti-operator/docs/architecture.md @@ -324,6 +324,7 @@ Source: `internal/controller/agentruntime_controller.go` | `agent.kagenti.dev` | `agentruntimes/finalizers` | update | Add/remove `kagenti.io/cleanup` finalizer for graceful deletion | | `apps` | `deployments`, `statefulsets` | get, list, watch, update, patch | Resolve targetRef, apply labels (`kagenti.io/type`, `managed-by`) and config-hash annotation | | `""` (core) | `configmaps` | get, list, watch | Read cluster defaults (`kagenti-platform-config`), feature gates (`kagenti-feature-gates`), and namespace defaults | +| `""` (core) | `namespaces` | get, list, watch, patch | Read and label namespaces for Istio ambient mesh enrollment | | `""` (core) | `pods` | get, list, watch | Count configured pods and verify ownership chains | | `""` (core) | `events` | create, patch | Record reconciliation events (TargetNotFound, ConfigWarning, Configured) | diff --git a/kagenti-operator/internal/controller/agentruntime_controller.go b/kagenti-operator/internal/controller/agentruntime_controller.go index 27a146e8..7ec629c7 100644 --- a/kagenti-operator/internal/controller/agentruntime_controller.go +++ b/kagenti-operator/internal/controller/agentruntime_controller.go @@ -184,6 +184,27 @@ func (r *AgentRuntimeReconciler) Reconcile(ctx context.Context, req ctrl.Request } } + // 4.6. Ensure namespace has Istio ambient mesh labels for ztunnel mTLS. + istioLabeled, istioErr := r.ensureIstioMeshLabels(ctx, rt.Namespace) + switch { + case istioErr != nil: + logger.Error(istioErr, "Failed to ensure Istio mesh labels") + r.setCondition(rt, ConditionTypeIstioMeshEnrolled, metav1.ConditionFalse, "PatchFailed", istioErr.Error()) + if r.Recorder != nil { + r.Recorder.Event(rt, corev1.EventTypeWarning, "IstioMeshLabelError", istioErr.Error()) + } + case istioLabeled: + r.setCondition(rt, ConditionTypeIstioMeshEnrolled, metav1.ConditionTrue, "NamespaceLabeled", + fmt.Sprintf("Namespace %s enrolled in Istio ambient mesh", rt.Namespace)) + if r.Recorder != nil { + r.Recorder.Event(rt, corev1.EventTypeNormal, "IstioMeshEnrolled", + fmt.Sprintf("Namespace %s labeled for Istio ambient mesh", rt.Namespace)) + } + default: + r.setCondition(rt, ConditionTypeIstioMeshEnrolled, metav1.ConditionFalse, "OptedOut", + fmt.Sprintf("Namespace %s opted out of Istio mesh enrollment", rt.Namespace)) + } + // 5. Compute config hash from merged configuration (cluster → namespace → CR) configResult, err := ComputeConfigHash(ctx, r.Client, rt.Namespace, &rt.Spec) if err != nil { diff --git a/kagenti-operator/internal/controller/agentruntime_istio.go b/kagenti-operator/internal/controller/agentruntime_istio.go new file mode 100644 index 00000000..b35d3062 --- /dev/null +++ b/kagenti-operator/internal/controller/agentruntime_istio.go @@ -0,0 +1,71 @@ +/* +Copyright 2026. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +const ( + ConditionTypeIstioMeshEnrolled = "IstioMeshEnrolled" + + AnnotationIstioMeshOptOut = "kagenti.io/istio-mesh" + + LabelIstioDiscovery = "istio-discovery" + LabelIstioDataplaneMode = "istio.io/dataplane-mode" +) + +// +kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;patch + +// ensureIstioMeshLabels patches the namespace with Istio ambient mesh labels +// unless the namespace has opted out via the kagenti.io/istio-mesh annotation. +// Returns true if labels were applied (or already present), false if opted out. +func (r *AgentRuntimeReconciler) ensureIstioMeshLabels(ctx context.Context, namespace string) (bool, error) { + logger := log.FromContext(ctx) + + ns := &corev1.Namespace{} + if err := r.Get(ctx, client.ObjectKey{Name: namespace}, ns); err != nil { + return false, err + } + + if ns.Annotations[AnnotationIstioMeshOptOut] == "disabled" { + logger.V(1).Info("Namespace opted out of Istio mesh enrollment", "namespace", namespace) + return false, nil + } + + if ns.Labels[LabelIstioDiscovery] == "enabled" && ns.Labels[LabelIstioDataplaneMode] == "ambient" { + return true, nil + } + + patch := client.MergeFrom(ns.DeepCopy()) + if ns.Labels == nil { + ns.Labels = make(map[string]string) + } + ns.Labels[LabelIstioDiscovery] = "enabled" + ns.Labels[LabelIstioDataplaneMode] = "ambient" + + if err := r.Patch(ctx, ns, patch); err != nil { + return false, err + } + + logger.V(1).Info("Labeled namespace for Istio ambient mesh", "namespace", namespace) + return true, nil +} diff --git a/kagenti-operator/internal/controller/agentruntime_istio_test.go b/kagenti-operator/internal/controller/agentruntime_istio_test.go new file mode 100644 index 00000000..20c223a8 --- /dev/null +++ b/kagenti-operator/internal/controller/agentruntime_istio_test.go @@ -0,0 +1,131 @@ +/* +Copyright 2026. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("ensureIstioMeshLabels", func() { + var ( + reconciler *AgentRuntimeReconciler + nsCounter int + ) + + newTestNamespace := func(labels map[string]string, annotations map[string]string) *corev1.Namespace { + nsCounter++ + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("istio-test-%d", nsCounter), + Labels: labels, + Annotations: annotations, + }, + } + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed()) + return ns + } + + BeforeEach(func() { + reconciler = &AgentRuntimeReconciler{ + Client: k8sClient, + } + }) + + It("should add Istio labels to a bare namespace", func() { + ns := newTestNamespace(nil, nil) + + labeled, err := reconciler.ensureIstioMeshLabels(ctx, ns.Name) + Expect(err).NotTo(HaveOccurred()) + Expect(labeled).To(BeTrue()) + + updated := &corev1.Namespace{} + Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), updated)).To(Succeed()) + Expect(updated.Labels[LabelIstioDiscovery]).To(Equal("enabled")) + Expect(updated.Labels[LabelIstioDataplaneMode]).To(Equal("ambient")) + }) + + It("should be idempotent on already-labeled namespace", func() { + ns := newTestNamespace(map[string]string{ + LabelIstioDiscovery: "enabled", + LabelIstioDataplaneMode: "ambient", + }, nil) + + labeled, err := reconciler.ensureIstioMeshLabels(ctx, ns.Name) + Expect(err).NotTo(HaveOccurred()) + Expect(labeled).To(BeTrue()) + + updated := &corev1.Namespace{} + Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), updated)).To(Succeed()) + Expect(updated.Labels[LabelIstioDiscovery]).To(Equal("enabled")) + Expect(updated.Labels[LabelIstioDataplaneMode]).To(Equal("ambient")) + }) + + It("should skip namespace with opt-out annotation", func() { + ns := newTestNamespace(nil, map[string]string{ + AnnotationIstioMeshOptOut: "disabled", + }) + + labeled, err := reconciler.ensureIstioMeshLabels(ctx, ns.Name) + Expect(err).NotTo(HaveOccurred()) + Expect(labeled).To(BeFalse()) + + updated := &corev1.Namespace{} + Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), updated)).To(Succeed()) + Expect(updated.Labels).NotTo(HaveKey(LabelIstioDiscovery)) + Expect(updated.Labels).NotTo(HaveKey(LabelIstioDataplaneMode)) + }) + + It("should preserve existing labels", func() { + ns := newTestNamespace(map[string]string{ + "team": "platform", + "env": "test", + }, nil) + + labeled, err := reconciler.ensureIstioMeshLabels(ctx, ns.Name) + Expect(err).NotTo(HaveOccurred()) + Expect(labeled).To(BeTrue()) + + updated := &corev1.Namespace{} + Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), updated)).To(Succeed()) + Expect(updated.Labels["team"]).To(Equal("platform")) + Expect(updated.Labels["env"]).To(Equal("test")) + Expect(updated.Labels[LabelIstioDiscovery]).To(Equal("enabled")) + Expect(updated.Labels[LabelIstioDataplaneMode]).To(Equal("ambient")) + }) + + It("should label namespace when annotation value is not 'disabled'", func() { + ns := newTestNamespace(nil, map[string]string{ + AnnotationIstioMeshOptOut: "enabled", + }) + + labeled, err := reconciler.ensureIstioMeshLabels(ctx, ns.Name) + Expect(err).NotTo(HaveOccurred()) + Expect(labeled).To(BeTrue()) + + updated := &corev1.Namespace{} + Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), updated)).To(Succeed()) + Expect(updated.Labels[LabelIstioDiscovery]).To(Equal("enabled")) + Expect(updated.Labels[LabelIstioDataplaneMode]).To(Equal("ambient")) + }) +}) diff --git a/kagenti-operator/test/e2e/e2e_test.go b/kagenti-operator/test/e2e/e2e_test.go index 7e380e0c..9c615457 100644 --- a/kagenti-operator/test/e2e/e2e_test.go +++ b/kagenti-operator/test/e2e/e2e_test.go @@ -2437,3 +2437,205 @@ rules: }) }) }) + +var _ = Describe("Istio Mesh Enrollment E2E", Ordered, func() { + const controllerNamespace = "kagenti-operator-system" + + BeforeAll(func() { + Expect(utils.DeployController(controllerNamespace, projectImage)).To(Succeed(), "Failed to deploy controller") + + By("waiting for controller-manager to be ready") + Eventually(func(g Gomega) { + cmd := exec.Command("kubectl", "get", "pods", "-l", "control-plane=controller-manager", + "-n", controllerNamespace, + "-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .status.phase }}{{ end }}{{ end }}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).To(ContainSubstring("Running")) + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + + By("waiting for webhook endpoint to be ready") + Eventually(func(g Gomega) { + cmd := exec.Command("kubectl", "get", "endpoints", + "kagenti-operator-webhook-service", "-n", controllerNamespace, + "-o", "jsonpath={.subsets[0].addresses[0].ip}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).NotTo(BeEmpty(), "webhook endpoint not yet populated") + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + + By("creating test namespace") + cmd := exec.Command("kubectl", "create", "ns", istioMeshTestNamespace) + _, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("creating opt-out test namespace") + cmd = exec.Command("kubectl", "create", "ns", istioMeshOptOutTestNamespace) + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("annotating opt-out namespace") + cmd = exec.Command("kubectl", "annotate", "ns", istioMeshOptOutTestNamespace, + "kagenti.io/istio-mesh=disabled") + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("ensuring kagenti-system namespace exists") + cmd = exec.Command("kubectl", "create", "ns", "kagenti-system") + _, _ = utils.Run(cmd) + + By("creating cluster defaults ConfigMap") + _, err = utils.KubectlApplyStdin(runtimeClusterDefaultsConfigMapFixture(), "kagenti-system") + Expect(err).NotTo(HaveOccurred()) + + By("deploying workload") + _, err = utils.KubectlApplyStdin(istioMeshDeploymentFixture(), istioMeshTestNamespace) + Expect(err).NotTo(HaveOccurred()) + + By("creating AgentRuntime (retry until webhook is ready)") + Eventually(func(g Gomega) { + _, applyErr := utils.KubectlApplyStdin(istioMeshAgentRuntimeFixture(), istioMeshTestNamespace) + g.Expect(applyErr).NotTo(HaveOccurred()) + }, 3*time.Minute, 5*time.Second).Should(Succeed()) + + By("deploying opt-out workload") + _, err = utils.KubectlApplyStdin(istioMeshOptOutDeploymentFixture(), istioMeshOptOutTestNamespace) + Expect(err).NotTo(HaveOccurred()) + + By("creating opt-out AgentRuntime (retry until webhook is ready)") + Eventually(func(g Gomega) { + _, applyErr := utils.KubectlApplyStdin(istioMeshOptOutAgentRuntimeFixture(), istioMeshOptOutTestNamespace) + g.Expect(applyErr).NotTo(HaveOccurred()) + }, 3*time.Minute, 5*time.Second).Should(Succeed()) + }) + + AfterAll(func() { + By("deleting test namespaces") + cmd := exec.Command("kubectl", "delete", "ns", istioMeshTestNamespace, "--ignore-not-found") + _, _ = utils.Run(cmd) + + cmd = exec.Command("kubectl", "delete", "ns", istioMeshOptOutTestNamespace, "--ignore-not-found") + _, _ = utils.Run(cmd) + + By("cleaning up cluster defaults ConfigMap") + cmd = exec.Command("kubectl", "delete", "configmap", "kagenti-platform-config", + "-n", "kagenti-system", "--ignore-not-found") + _, _ = utils.Run(cmd) + + utils.UndeployController() + }) + + It("should auto-label namespace with Istio mesh labels", func() { + Eventually(func(g Gomega) { + cmd := exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", "jsonpath={.metadata.labels.istio-discovery}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(strings.TrimSpace(output)).To(Equal("enabled")) + + cmd = exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", `jsonpath={.metadata.labels.istio\.io/dataplane-mode}`) + output, err = utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(strings.TrimSpace(output)).To(Equal("ambient")) + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + }) + + It("should set IstioMeshEnrolled condition to True", func() { + Eventually(func(g Gomega) { + output, err := utils.KubectlGetJsonpath("agentruntime", "istio-mesh-test-runtime", + istioMeshTestNamespace, + `{.status.conditions[?(@.type=="IstioMeshEnrolled")].status}`) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).To(Equal("True")) + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + }) + + It("should respect opt-out annotation and not label namespace", func() { + Eventually(func(g Gomega) { + output, err := utils.KubectlGetJsonpath("agentruntime", "istio-mesh-optout-runtime", + istioMeshOptOutTestNamespace, + `{.status.conditions[?(@.type=="IstioMeshEnrolled")].reason}`) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).To(Equal("OptedOut")) + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + + cmd := exec.Command("kubectl", "get", "ns", istioMeshOptOutTestNamespace, + "-o", "jsonpath={.metadata.labels.istio-discovery}") + output, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + Expect(strings.TrimSpace(output)).To(BeEmpty()) + }) + + It("should preserve labels after AgentRuntime deletion", func() { + By("verifying namespace is labeled") + Eventually(func(g Gomega) { + cmd := exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", "jsonpath={.metadata.labels.istio-discovery}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(strings.TrimSpace(output)).To(Equal("enabled")) + }, 1*time.Minute, 2*time.Second).Should(Succeed()) + + By("deleting AgentRuntime") + cmd := exec.Command("kubectl", "delete", "agentruntime", "istio-mesh-test-runtime", + "-n", istioMeshTestNamespace) + _, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("verifying labels persist on namespace") + cmd = exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", "jsonpath={.metadata.labels.istio-discovery}") + output, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + Expect(strings.TrimSpace(output)).To(Equal("enabled")) + + cmd = exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", `jsonpath={.metadata.labels.istio\.io/dataplane-mode}`) + output, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + Expect(strings.TrimSpace(output)).To(Equal("ambient")) + }) + + It("should recover from label drift", func() { + By("re-creating AgentRuntime after previous test deleted it") + _, err := utils.KubectlApplyStdin(istioMeshAgentRuntimeFixture(), istioMeshTestNamespace) + Expect(err).NotTo(HaveOccurred()) + + By("waiting for labels to be applied") + Eventually(func(g Gomega) { + cmd := exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", "jsonpath={.metadata.labels.istio-discovery}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(strings.TrimSpace(output)).To(Equal("enabled")) + }, 1*time.Minute, 2*time.Second).Should(Succeed()) + + By("removing Istio labels manually") + cmd := exec.Command("kubectl", "label", "ns", istioMeshTestNamespace, + "istio-discovery-", "istio.io/dataplane-mode-") + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("triggering reconcile via annotation change") + cmd = exec.Command("kubectl", "annotate", "agentruntime", "istio-mesh-test-runtime", + "-n", istioMeshTestNamespace, "trigger-reconcile=drift-test", "--overwrite") + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("verifying labels are re-applied") + Eventually(func(g Gomega) { + cmd := exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", "jsonpath={.metadata.labels.istio-discovery}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(strings.TrimSpace(output)).To(Equal("enabled")) + + cmd = exec.Command("kubectl", "get", "ns", istioMeshTestNamespace, + "-o", `jsonpath={.metadata.labels.istio\.io/dataplane-mode}`) + output, err = utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(strings.TrimSpace(output)).To(Equal("ambient")) + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + }) +}) diff --git a/kagenti-operator/test/e2e/fixtures.go b/kagenti-operator/test/e2e/fixtures.go index 9ce35247..2cda240a 100644 --- a/kagenti-operator/test/e2e/fixtures.go +++ b/kagenti-operator/test/e2e/fixtures.go @@ -1546,3 +1546,110 @@ spec: kagenti-enabled: "true" ` } + +// --- Istio Mesh Enrollment E2E Fixtures --- + +const istioMeshTestNamespace = "e2e-istio-mesh-test" +const istioMeshOptOutTestNamespace = "e2e-istio-mesh-optout-test" + +func istioMeshDeploymentFixture() string { + return `apiVersion: apps/v1 +kind: Deployment +metadata: + name: istio-mesh-agent + namespace: ` + istioMeshTestNamespace + ` + labels: + app.kubernetes.io/name: istio-mesh-agent + protocol.kagenti.io/a2a: "" +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: istio-mesh-agent + template: + metadata: + labels: + app.kubernetes.io/name: istio-mesh-agent + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: pause + image: registry.k8s.io/pause:3.9 + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL +` +} + +func istioMeshAgentRuntimeFixture() string { + return `apiVersion: agent.kagenti.dev/v1alpha1 +kind: AgentRuntime +metadata: + name: istio-mesh-test-runtime + namespace: ` + istioMeshTestNamespace + ` +spec: + type: agent + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: istio-mesh-agent +` +} + +func istioMeshOptOutDeploymentFixture() string { + return `apiVersion: apps/v1 +kind: Deployment +metadata: + name: istio-mesh-optout-agent + namespace: ` + istioMeshOptOutTestNamespace + ` + labels: + app.kubernetes.io/name: istio-mesh-optout-agent + protocol.kagenti.io/a2a: "" +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: istio-mesh-optout-agent + template: + metadata: + labels: + app.kubernetes.io/name: istio-mesh-optout-agent + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: pause + image: registry.k8s.io/pause:3.9 + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL +` +} + +func istioMeshOptOutAgentRuntimeFixture() string { + return `apiVersion: agent.kagenti.dev/v1alpha1 +kind: AgentRuntime +metadata: + name: istio-mesh-optout-runtime + namespace: ` + istioMeshOptOutTestNamespace + ` +spec: + type: agent + targetRef: + apiVersion: apps/v1 + kind: Deployment + name: istio-mesh-optout-agent +` +}