From 7c68895c77361ad110fd6ac479203e9c4f442c7b Mon Sep 17 00:00:00 2001 From: Swarup Ghosh Date: Thu, 19 Feb 2026 18:12:26 +0530 Subject: [PATCH] oape: generate API types and tests from EP #1834 Adds NetworkPolicy API type improvements and comprehensive integration tests for the ExternalSecretsConfig networkPolicies field from EP #1834. Changes: - Fix godoc comments on ComponentName constants (trailing periods) - Add DNS subdomain validation pattern for NetworkPolicy name field - Improve Egress field documentation for clarity - Fix Egress JSON tag (remove omitempty for Required field) - Fix listType marker spacing - Add 15 new integration test cases covering: - NetworkPolicy creation for CoreController and BitwardenSDKServer - Multiple networkPolicies in a single config - Allow-all egress and deny-all egress configurations - DNS name validation (uppercase, underscores, leading/trailing hyphens) - Empty networkPolicies list handling - Name length validation - Invalid componentName validation - NetworkPolicy addition after creation (onUpdate) - Immutability of name and componentName fields (onUpdate) - Regenerated CRD manifests with updated validation Co-Authored-By: Claude Opus 4.6 --- api/v1alpha1/external_secrets_config_types.go | 23 +- .../externalsecretsconfig.testsuite.yaml | 381 +++++++++++++++++- ...r.openshift.io_externalsecretsconfigs.yaml | 15 +- 3 files changed, 400 insertions(+), 19 deletions(-) diff --git a/api/v1alpha1/external_secrets_config_types.go b/api/v1alpha1/external_secrets_config_types.go index f06a7df79..c8b5b3a3c 100644 --- a/api/v1alpha1/external_secrets_config_types.go +++ b/api/v1alpha1/external_secrets_config_types.go @@ -216,10 +216,10 @@ type CertProvidersConfig struct { type ComponentName string const ( - // CoreController represents the external-secrets component + // ExternalSecretsCoreController represents the external-secrets core controller component. CoreController ComponentName = "ExternalSecretsCoreController" - // BitwardenSDKServer represents the bitwarden-sdk-server component + // BitwardenSDKServer represents the bitwarden-sdk-server component. BitwardenSDKServer ComponentName = "BitwardenSDKServer" ) @@ -228,8 +228,11 @@ const ( type NetworkPolicy struct { // name is a unique identifier for this network policy configuration. // This name will be used as part of the generated NetworkPolicy resource name. + // The value must be a valid DNS subdomain name consisting of lowercase alphanumeric characters or '-', + // starting and ending with an alphanumeric character. // +kubebuilder:validation:MinLength:=1 // +kubebuilder:validation:MaxLength:=253 + // +kubebuilder:validation:Pattern:=`^[a-z0-9]([a-z0-9-]*[a-z0-9])?$` // +kubebuilder:validation:Required Name string `json:"name"` @@ -238,14 +241,12 @@ type NetworkPolicy struct { // +kubebuilder:validation:Required ComponentName ComponentName `json:"componentName"` - // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic - // is allowed if there are no NetworkPolicies selecting the pod (and cluster policy - // otherwise allows the traffic), OR if the traffic matches at least one egress rule - // across all the NetworkPolicy objects whose podSelector matches the pod. If - // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves - // solely to ensure that the pods it selects are isolated by default). - // The operator will automatically handle ingress rules based on the current running ports. + // egress is a list of egress rules to be applied to the selected component pods. + // The operator generates a Kubernetes NetworkPolicy targeting the component specified by componentName, + // using the egress rules provided here. If this list is empty, the generated NetworkPolicy will deny + // all outgoing traffic for the component (default-deny egress). + // The operator will automatically handle ingress rules based on the component's required ports. // +kubebuilder:validation:Required - //+listType=atomic - Egress []networkingv1.NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"` + // +listType=atomic + Egress []networkingv1.NetworkPolicyEgressRule `json:"egress"` } diff --git a/api/v1alpha1/tests/externalsecretsconfig.operator.openshift.io/externalsecretsconfig.testsuite.yaml b/api/v1alpha1/tests/externalsecretsconfig.operator.openshift.io/externalsecretsconfig.testsuite.yaml index 720d7fc23..3e5da3ccd 100644 --- a/api/v1alpha1/tests/externalsecretsconfig.operator.openshift.io/externalsecretsconfig.testsuite.yaml +++ b/api/v1alpha1/tests/externalsecretsconfig.operator.openshift.io/externalsecretsconfig.testsuite.yaml @@ -493,6 +493,283 @@ tests: webhookConfig: certificateCheckInterval: "15m" operatingNamespace: "test-ns" + - name: Should be able to create ExternalSecretsConfig with networkPolicies for CoreController + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-external-secrets-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-external-secrets-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + - name: Should be able to create ExternalSecretsConfig with networkPolicies for BitwardenSDKServer + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-bitwarden-egress + componentName: BitwardenSDKServer + egress: + - ports: + - protocol: TCP + port: 6443 + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-bitwarden-egress + componentName: BitwardenSDKServer + egress: + - ports: + - protocol: TCP + port: 6443 + - name: Should be able to create ExternalSecretsConfig with multiple networkPolicies + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + - name: allow-bitwarden-egress + componentName: BitwardenSDKServer + egress: + - ports: + - protocol: TCP + port: 6443 + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + - name: allow-bitwarden-egress + componentName: BitwardenSDKServer + egress: + - ports: + - protocol: TCP + port: 6443 + - name: Should be able to create ExternalSecretsConfig with networkPolicies allowing all egress + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-all-egress + componentName: ExternalSecretsCoreController + egress: + - {} + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-all-egress + componentName: ExternalSecretsCoreController + egress: + - {} + - name: Should fail with invalid componentName in networkPolicies + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-egress + componentName: InvalidComponent + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "spec.controllerConfig.networkPolicies[0].componentName: Unsupported value" + - name: Should fail with empty name in networkPolicies + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: "" + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "spec.controllerConfig.networkPolicies[0].name: Invalid value" + - name: Should fail with networkPolicy name too long + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: "this-network-policy-name-is-extremely-long-and-exceeds-the-kubernetes-maximum-name-length-limit-of-two-hundred-fifty-three-characters-which-is-quite-a-lot-of-characters-but-we-need-to-test-this-validation-constraint-properly-to-ensure-it-works-as-expected-in-all-scenarios" + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "spec.controllerConfig.networkPolicies[0].name: Too long" + - name: Should fail with networkPolicy name containing uppercase characters + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: "Allow-Egress" + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "spec.controllerConfig.networkPolicies[0].name: Invalid value" + - name: Should fail with networkPolicy name containing underscores + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: "allow_egress" + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "spec.controllerConfig.networkPolicies[0].name: Invalid value" + - name: Should fail with networkPolicy name starting with hyphen + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: "-allow-egress" + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "spec.controllerConfig.networkPolicies[0].name: Invalid value" + - name: Should fail with networkPolicy name ending with hyphen + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: "allow-egress-" + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "spec.controllerConfig.networkPolicies[0].name: Invalid value" + - name: Should be able to create ExternalSecretsConfig with networkPolicy with empty egress list for deny-all + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: deny-all-egress + componentName: ExternalSecretsCoreController + egress: [] + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: deny-all-egress + componentName: ExternalSecretsCoreController + egress: [] + - name: Should be able to create ExternalSecretsConfig with valid DNS subdomain networkPolicy name + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-controller-egress-to-api-server + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-controller-egress-to-api-server + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + - name: Should be able to create ExternalSecretsConfig with empty networkPolicies list + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: [] + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: [] onUpdate: - name: Should be able to update labels in controller config resourceName: cluster @@ -596,4 +873,106 @@ tests: bitwardenSecretManagerProvider: mode: Enabled secretRef: - name: "bitwarden-certs" \ No newline at end of file + name: "bitwarden-certs" + - name: Should be able to add networkPolicies after creation + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: {} + updated: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + - name: Should not be able to change name and componentName of existing networkPolicies + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + updated: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: renamed-policy + componentName: BitwardenSDKServer + egress: + - ports: + - protocol: TCP + port: 6443 + expectedError: "name and componentName fields in networkPolicies are immutable" + - name: Should be able to update egress rules in existing networkPolicy + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + updated: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + - ports: + - protocol: TCP + port: 443 + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + controllerConfig: + networkPolicies: + - name: allow-core-egress + componentName: ExternalSecretsCoreController + egress: + - ports: + - protocol: TCP + port: 6443 + - ports: + - protocol: TCP + port: 443 \ No newline at end of file diff --git a/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml b/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml index ae6890cdc..0f962a004 100644 --- a/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml +++ b/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml @@ -1297,13 +1297,11 @@ spec: type: string egress: description: |- - egress is a list of egress rules to be applied to the selected pods. Outgoing traffic - is allowed if there are no NetworkPolicies selecting the pod (and cluster policy - otherwise allows the traffic), OR if the traffic matches at least one egress rule - across all the NetworkPolicy objects whose podSelector matches the pod. If - this field is empty then this NetworkPolicy limits all outgoing traffic (and serves - solely to ensure that the pods it selects are isolated by default). - The operator will automatically handle ingress rules based on the current running ports. + egress is a list of egress rules to be applied to the selected component pods. + The operator generates a Kubernetes NetworkPolicy targeting the component specified by componentName, + using the egress rules provided here. If this list is empty, the generated NetworkPolicy will deny + all outgoing traffic for the component (default-deny egress). + The operator will automatically handle ingress rules based on the component's required ports. items: description: |- NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods @@ -1497,8 +1495,11 @@ spec: description: |- name is a unique identifier for this network policy configuration. This name will be used as part of the generated NetworkPolicy resource name. + The value must be a valid DNS subdomain name consisting of lowercase alphanumeric characters or '-', + starting and ending with an alphanumeric character. maxLength: 253 minLength: 1 + pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ type: string required: - componentName