diff --git a/api/v1alpha1/meta.go b/api/v1alpha1/meta.go index 68a882d64..2980a39ce 100644 --- a/api/v1alpha1/meta.go +++ b/api/v1alpha1/meta.go @@ -111,8 +111,29 @@ type ProxyConfig struct { // +kubebuilder:validation:MaxLength:=4096 // +optional NoProxy string `json:"noProxy,omitempty"` + + // NetworkPolicyProvisioning defines the management strategy for the proxy egress rule. + // When set to Managed, the operator automatically provisions and maintains + // a NetworkPolicy allowing traffic to the configured proxy. + // If no proxy is configured, no NetworkPolicy will be created + // regardless of this setting. + // +kubebuilder:validation:Enum=Managed;Unmanaged + // +kubebuilder:default=Managed + // +optional + NetworkPolicyProvisioning ManagementState `json:"networkPolicyProvisioning,omitempty"` } +// ManagementState controls whether the operator manages the resource lifecycle. +type ManagementState string + +const ( + // ManagementStateManaged indicates the Operator is responsible for the resource lifecycle. + ManagementStateManaged ManagementState = "Managed" + + // ManagementStateUnmanaged indicates the User is responsible for the resource lifecycle. + ManagementStateUnmanaged ManagementState = "Unmanaged" +) + // Mode indicates the operational state of the optional features. type Mode string 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 6e20a96df..ca22244bb 100644 --- a/api/v1alpha1/tests/externalsecretsconfig.operator.openshift.io/externalsecretsconfig.testsuite.yaml +++ b/api/v1alpha1/tests/externalsecretsconfig.operator.openshift.io/externalsecretsconfig.testsuite.yaml @@ -1445,6 +1445,96 @@ tests: injectAnnotations: "false" certificateDuration: "8760h" certificateRenewBefore: "30m" + - name: Should accept networkPolicyProvisioning set to Managed (default) + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Managed + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + logLevel: 1 + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Managed + - name: Should accept networkPolicyProvisioning set to Unmanaged + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Unmanaged + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + logLevel: 1 + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Unmanaged + - name: Should default networkPolicyProvisioning to Managed when proxy is set without the field + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + proxy: + httpProxy: "http://proxy.example.com:3128" + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + logLevel: 1 + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Managed + - name: Should fail with invalid value for networkPolicyProvisioning + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Enabled + expectedError: "spec.appConfig.proxy.networkPolicyProvisioning: Unsupported value: \"Enabled\": supported values: \"Managed\", \"Unmanaged\"" + - name: Should accept proxy config with all fields including networkPolicyProvisioning + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + proxy: + httpProxy: "http://proxy.example.com:3128" + httpsProxy: "https://proxy.example.com:3129" + noProxy: "localhost,127.0.0.1,.cluster.local" + networkPolicyProvisioning: Unmanaged + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + logLevel: 1 + proxy: + httpProxy: "http://proxy.example.com:3128" + httpsProxy: "https://proxy.example.com:3129" + noProxy: "localhost,127.0.0.1,.cluster.local" + networkPolicyProvisioning: Unmanaged onUpdate: - name: Should be able to update labels in controller config resourceName: cluster @@ -1726,3 +1816,30 @@ tests: - to: - ipBlock: cidr: 172.16.0.0/12 + - name: Should be able to update networkPolicyProvisioning from Managed to Unmanaged + resourceName: cluster + initial: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Managed + updated: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Unmanaged + expected: | + apiVersion: operator.openshift.io/v1alpha1 + kind: ExternalSecretsConfig + spec: + appConfig: + logLevel: 1 + proxy: + httpProxy: "http://proxy.example.com:3128" + networkPolicyProvisioning: Unmanaged diff --git a/api/v1alpha1/tests/externalsecretsmanager.operator.openshift.io/externalsecretsmanager.testsuite.yaml b/api/v1alpha1/tests/externalsecretsmanager.operator.openshift.io/externalsecretsmanager.testsuite.yaml index 2f88c646a..cc4a78561 100644 --- a/api/v1alpha1/tests/externalsecretsmanager.operator.openshift.io/externalsecretsmanager.testsuite.yaml +++ b/api/v1alpha1/tests/externalsecretsmanager.operator.openshift.io/externalsecretsmanager.testsuite.yaml @@ -88,6 +88,7 @@ tests: proxy: httpProxy: "http://proxy.example.com:8080" httpsProxy: "https://proxy.example.com:8443" + networkPolicyProvisioning: Managed noProxy: "localhost,127.0.0.1,.local" - name: Should fail to create with invalid singleton name resourceName: invalid-name @@ -182,6 +183,7 @@ tests: logLevel: 1 proxy: httpProxy: "http://proxy-url-at-exactly-two-thousand-and-forty-eight-characters-to-test-the-boundary-condition-where-we-want-to-ensure-that-urls-at-the-maximum-allowed-length-are-accepted-properly-by-the-validation-system-while-urls-that-exceed-this-limit-are-rejected-appropriately-which-is-important-for-maintaining-proper-validation-boundaries-in-production-systems-where-configuration-parameters-must-be-validated-correctly-to-prevent-system-failures-or-unexpected-behavior-that-could-impact-application-functionality-and-user-experience-in-various-deployment-environments-including-development-staging-and-production-kubernetes-clusters-running-across-different-cloud-providers-and-on-premises-infrastructure-where-proxy-configurations-are-commonly-used-for-network-security-and-compliance-requirements-that-organizations-need-to-meet-for-their-business-operations-and-regulatory-obligations-in-different-geographical-regions-around-the-world-where-various-network-policies-and-security-measures-are-implemented-to-protect-sensitive-data-and-ensure-proper-access-control-for-applications-and-services-that-handle-confidential-information-and-business-critical-processes-that-must-operate-reliably-and-securely-at-all-times-without-interruption-or-performance-degradation-that-could-affect-end-users-and-customers-who-depend-on-these-systems-for-their-daily-activities-and-business-needs-which-makes-proper-validation-of-configuration-parameters-like-proxy-urls-essential-for-maintaining-system-stability-and-security-in-production-environments-where-any-configuration-error-could-have-significant-consequences-for-business-continuity-and-customer-satisfaction-which-is-why-we-implement-comprehensive-boundary-testing-to-ensure-that-all-validation-rules-work-correctly-at-their-specified-limits-and-provide-clear-error-messages-when-those-limits-are-exceeded-by-user-configurations.example.com:8080" + networkPolicyProvisioning: Managed - name: Should accept HTTPS proxy URL at maximum length boundary resourceName: cluster initial: | @@ -200,6 +202,7 @@ tests: logLevel: 1 proxy: httpsProxy: "https://secure-proxy-url-at-exactly-two-thousand-and-forty-eight-characters-to-test-the-boundary-condition-where-we-want-to-ensure-that-urls-at-the-maximum-allowed-length-are-accepted-properly-by-the-validation-system-while-urls-that-exceed-this-limit-are-rejected-appropriately-which-is-important-for-maintaining-proper-validation-boundaries-in-production-systems-where-configuration-parameters-must-be-validated-correctly-to-prevent-system-failures-or-unexpected-behavior-that-could-impact-application-functionality-and-user-experience-in-various-deployment-environments-including-development-staging-and-production-kubernetes-clusters-running-across-different-cloud-providers-and-on-premises-infrastructure-where-proxy-configurations-are-commonly-used-for-network-security-and-compliance-requirements-that-organizations-need-to-meet-for-their-business-operations-and-regulatory-obligations-in-different-geographical-regions-around-the-world-where-various-network-policies-and-security-measures-are-implemented-to-protect-sensitive-data-and-ensure-proper-access-control-for-applications-and-services-that-handle-confidential-information-and-business-critical-processes-that-must-operate-reliably-and-securely-at-all-times-without-interruption-or-performance-degradation-that-could-affect-end-users-and-customers-who-depend-on-these-systems-for-their-daily-activities-and-business-needs-which-makes-proper-validation-of-configuration-parameters-like-proxy-urls-essential-for-maintaining-system-stability-and-security-in-production-environments-where-any-configuration-error-could-have-significant-consequences-for-business-continuity-and-customer-satisfaction-which-is-why-we-implement-comprehensive-boundary-testing-to-ensure-that-all-validation-rules-work-correctly-at-their-specified-limits-and-provide-clear-error-messages-when-those-limits-are-exceeded.example.com:8443" + networkPolicyProvisioning: Managed - name: Should accept empty proxy configuration resourceName: cluster initial: | @@ -220,6 +223,7 @@ tests: proxy: httpProxy: "" httpsProxy: "" + networkPolicyProvisioning: Managed noProxy: "" onUpdate: - name: Should be able to add global config after creation @@ -337,6 +341,7 @@ tests: proxy: httpProxy: "http://proxy.company.com:3128" httpsProxy: "https://proxy.company.com:3128" + networkPolicyProvisioning: Managed noProxy: "localhost,127.0.0.1,.company.com" - name: Should be able to update node selector and tolerations resourceName: cluster diff --git a/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml b/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml index a87455abc..12bcabe19 100644 --- a/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml +++ b/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml @@ -220,7 +220,7 @@ metadata: categories: Security console.openshift.io/disable-operand-delete: "true" containerImage: openshift.io/external-secrets-operator:latest - createdAt: "2026-03-06T13:50:37Z" + createdAt: "2026-05-15T11:51:51Z" features.operators.openshift.io/cnf: "false" features.operators.openshift.io/cni: "false" features.operators.openshift.io/csi: "false" diff --git a/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml b/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml index f27616944..f2dbb80be 100644 --- a/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml +++ b/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml @@ -1034,6 +1034,18 @@ spec: maxLength: 2048 minLength: 0 type: string + networkPolicyProvisioning: + default: Managed + description: |- + NetworkPolicyProvisioning defines the management strategy for the proxy egress rule. + When set to Managed, the operator automatically provisions and maintains + a NetworkPolicy allowing traffic to the configured proxy. + If no proxy is configured, no NetworkPolicy will be created + regardless of this setting. + enum: + - Managed + - Unmanaged + type: string noProxy: description: |- noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. diff --git a/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml b/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml index fd26d0632..333156254 100644 --- a/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml +++ b/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml @@ -1031,6 +1031,18 @@ spec: maxLength: 2048 minLength: 0 type: string + networkPolicyProvisioning: + default: Managed + description: |- + NetworkPolicyProvisioning defines the management strategy for the proxy egress rule. + When set to Managed, the operator automatically provisions and maintains + a NetworkPolicy allowing traffic to the configured proxy. + If no proxy is configured, no NetworkPolicy will be created + regardless of this setting. + enum: + - Managed + - Unmanaged + type: string noProxy: description: |- noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. diff --git a/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml b/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml index 274ac9416..c615195d1 100644 --- a/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml +++ b/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml @@ -1034,6 +1034,18 @@ spec: maxLength: 2048 minLength: 0 type: string + networkPolicyProvisioning: + default: Managed + description: |- + NetworkPolicyProvisioning defines the management strategy for the proxy egress rule. + When set to Managed, the operator automatically provisions and maintains + a NetworkPolicy allowing traffic to the configured proxy. + If no proxy is configured, no NetworkPolicy will be created + regardless of this setting. + enum: + - Managed + - Unmanaged + type: string noProxy: description: |- noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. diff --git a/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml b/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml index c508693b4..cee5f265d 100644 --- a/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml +++ b/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml @@ -1031,6 +1031,18 @@ spec: maxLength: 2048 minLength: 0 type: string + networkPolicyProvisioning: + default: Managed + description: |- + NetworkPolicyProvisioning defines the management strategy for the proxy egress rule. + When set to Managed, the operator automatically provisions and maintains + a NetworkPolicy allowing traffic to the configured proxy. + If no proxy is configured, no NetworkPolicy will be created + regardless of this setting. + enum: + - Managed + - Unmanaged + type: string noProxy: description: |- noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. diff --git a/docs/api_reference.md b/docs/api_reference.md index 9a5c023ae..8061f4a2c 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -414,6 +414,23 @@ _Appears in:_ | `labels` _object (keys:string, values:string)_ | labels to apply to all resources created by the operator.
This field can have a maximum of 20 entries. | | MaxProperties: 20
MinProperties: 0
| +#### ManagementState + +_Underlying type:_ _string_ + +ManagementState controls whether the operator manages the resource lifecycle. + + + +_Appears in:_ +- [ProxyConfig](#proxyconfig) + +| Field | Description | +| --- | --- | +| `Managed` | ManagementStateManaged indicates the Operator is responsible for the resource lifecycle.
| +| `Unmanaged` | ManagementStateUnmanaged indicates the User is responsible for the resource lifecycle.
| + + #### Mode _Underlying type:_ _string_ @@ -498,6 +515,7 @@ _Appears in:_ | `httpProxy` _string_ | httpProxy is the URL of the proxy for HTTP requests.
This field can have a maximum of 2048 characters. | | MaxLength: 2048
MinLength: 0
| | `httpsProxy` _string_ | httpsProxy is the URL of the proxy for HTTPS requests.
This field can have a maximum of 2048 characters. | | MaxLength: 2048
MinLength: 0
| | `noProxy` _string_ | noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used.
This field can have a maximum of 4096 characters. | | MaxLength: 4096
MinLength: 0
| +| `networkPolicyProvisioning` _[ManagementState](#managementstate)_ | NetworkPolicyProvisioning defines the management strategy for the proxy egress rule.
When set to Managed, the operator automatically provisions and maintains
a NetworkPolicy allowing traffic to the configured proxy.
If no proxy is configured, no NetworkPolicy will be created
regardless of this setting. | Managed | Enum: [Managed Unmanaged]
| #### SecretReference diff --git a/hack/govulncheck.sh b/hack/govulncheck.sh index 1b138be2b..d185409f6 100755 --- a/hack/govulncheck.sh +++ b/hack/govulncheck.sh @@ -24,7 +24,7 @@ set -o errexit ## Below vulnerabilities are in the go packages, which impacts the operator code and requires the fix to be available downstream. # - https://pkg.go.dev/vuln/GO-2026-4601 - Incorrect parsing of IPv6 host literals in net/url # - https://pkg.go.dev/vuln/GO-2026-4602 - FileInfo can escape from a Root in os -KNOWN_VULNS_PATTERN="GO-2025-3521|GO-2025-3547|GO-2026-4601|GO-2026-4602" +KNOWN_VULNS_PATTERN="GO-2025-3521|GO-2025-3547|GO-2026-4971|GO-2026-4918" GOVULNCHECK_BIN="${1:-}" OUTPUT_DIR="${2:-}"