Skip to content

Commit 0e7d2d9

Browse files
feat(api): add NetworkPolicyProvisioning field to ProxyConfig for EP-1998
Introduce ManagementState type with Managed and Unmanaged values, and add NetworkPolicyProvisioning field to ProxyConfig. When set to Managed (default), the operator will automatically create and maintain a NetworkPolicy allowing ESO pods to reach the configured proxy server. When set to Unmanaged, administrators manage proxy egress NetworkPolicies themselves. The field is defined at spec.appConfig.proxy.networkPolicyProvisioning on ExternalSecretsConfig. CRD YAMLs for both ExternalSecretsConfig and ExternalSecretsManager are updated. Six API test cases cover valid values, default injection, invalid value rejection, and mutability. Ref: openshift/enhancements#1998 Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2a65cb8 commit 0e7d2d9

11 files changed

Lines changed: 225 additions & 10 deletions

api/v1alpha1/external_secrets_config_types.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ type ControllerConfig struct {
137137
//
138138
// Each entry allows specifying a name for the generated NetworkPolicy object,
139139
// along with its full Kubernetes NetworkPolicy definition.
140+
// The operator prepends "eso-user-" to the provided name when creating the Kubernetes object.
140141
//
141142
// If this field is not provided, external-secrets components will be isolated
142143
// with deny-all network policies, which will prevent proper operation.
@@ -299,8 +300,9 @@ const (
299300
// NetworkPolicy represents a custom network policy configuration for operator-managed components.
300301
// It includes a name for identification and the network policy rules to be enforced.
301302
type NetworkPolicy struct {
302-
// name is a unique identifier for this network policy configuration.
303-
// This name will be used as part of the generated NetworkPolicy resource name.
303+
// Name is the logical identifier for this network policy entry.
304+
// The operator prepends "eso-user-" to this value when creating the Kubernetes
305+
// NetworkPolicy object (e.g. "allow-egress" becomes "eso-user-allow-egress").
304306
// +kubebuilder:validation:MinLength:=1
305307
// +kubebuilder:validation:MaxLength:=253
306308
// +required

api/v1alpha1/meta.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,29 @@ type ProxyConfig struct {
111111
// +kubebuilder:validation:MaxLength:=4096
112112
// +optional
113113
NoProxy string `json:"noProxy,omitempty"`
114+
115+
// NetworkPolicyProvisioning defines the management strategy for the proxy egress rule.
116+
// When set to Managed, the operator automatically provisions and maintains
117+
// a NetworkPolicy allowing traffic to the configured proxy.
118+
// If no proxy is configured, no NetworkPolicy will be created
119+
// regardless of this setting.
120+
// +kubebuilder:validation:Enum=Managed;Unmanaged
121+
// +kubebuilder:default=Managed
122+
// +optional
123+
NetworkPolicyProvisioning ManagementState `json:"networkPolicyProvisioning,omitempty"`
114124
}
115125

126+
// ManagementState controls whether the operator manages the resource lifecycle.
127+
type ManagementState string
128+
129+
const (
130+
// ManagementStateManaged indicates the Operator is responsible for the resource lifecycle.
131+
ManagementStateManaged ManagementState = "Managed"
132+
133+
// ManagementStateUnmanaged indicates the User is responsible for the resource lifecycle.
134+
ManagementStateUnmanaged ManagementState = "Unmanaged"
135+
)
136+
116137
// Mode indicates the operational state of the optional features.
117138
type Mode string
118139

api/v1alpha1/tests/externalsecretsconfig.operator.openshift.io/externalsecretsconfig.testsuite.yaml

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,96 @@ tests:
14451445
injectAnnotations: "false"
14461446
certificateDuration: "8760h"
14471447
certificateRenewBefore: "30m"
1448+
- name: Should accept networkPolicyProvisioning set to Managed (default)
1449+
resourceName: cluster
1450+
initial: |
1451+
apiVersion: operator.openshift.io/v1alpha1
1452+
kind: ExternalSecretsConfig
1453+
spec:
1454+
appConfig:
1455+
proxy:
1456+
httpProxy: "http://proxy.example.com:3128"
1457+
networkPolicyProvisioning: Managed
1458+
expected: |
1459+
apiVersion: operator.openshift.io/v1alpha1
1460+
kind: ExternalSecretsConfig
1461+
spec:
1462+
appConfig:
1463+
logLevel: 1
1464+
proxy:
1465+
httpProxy: "http://proxy.example.com:3128"
1466+
networkPolicyProvisioning: Managed
1467+
- name: Should accept networkPolicyProvisioning set to Unmanaged
1468+
resourceName: cluster
1469+
initial: |
1470+
apiVersion: operator.openshift.io/v1alpha1
1471+
kind: ExternalSecretsConfig
1472+
spec:
1473+
appConfig:
1474+
proxy:
1475+
httpProxy: "http://proxy.example.com:3128"
1476+
networkPolicyProvisioning: Unmanaged
1477+
expected: |
1478+
apiVersion: operator.openshift.io/v1alpha1
1479+
kind: ExternalSecretsConfig
1480+
spec:
1481+
appConfig:
1482+
logLevel: 1
1483+
proxy:
1484+
httpProxy: "http://proxy.example.com:3128"
1485+
networkPolicyProvisioning: Unmanaged
1486+
- name: Should default networkPolicyProvisioning to Managed when proxy is set without the field
1487+
resourceName: cluster
1488+
initial: |
1489+
apiVersion: operator.openshift.io/v1alpha1
1490+
kind: ExternalSecretsConfig
1491+
spec:
1492+
appConfig:
1493+
proxy:
1494+
httpProxy: "http://proxy.example.com:3128"
1495+
expected: |
1496+
apiVersion: operator.openshift.io/v1alpha1
1497+
kind: ExternalSecretsConfig
1498+
spec:
1499+
appConfig:
1500+
logLevel: 1
1501+
proxy:
1502+
httpProxy: "http://proxy.example.com:3128"
1503+
networkPolicyProvisioning: Managed
1504+
- name: Should fail with invalid value for networkPolicyProvisioning
1505+
resourceName: cluster
1506+
initial: |
1507+
apiVersion: operator.openshift.io/v1alpha1
1508+
kind: ExternalSecretsConfig
1509+
spec:
1510+
appConfig:
1511+
proxy:
1512+
httpProxy: "http://proxy.example.com:3128"
1513+
networkPolicyProvisioning: Enabled
1514+
expectedError: "spec.appConfig.proxy.networkPolicyProvisioning: Unsupported value: \"Enabled\": supported values: \"Managed\", \"Unmanaged\""
1515+
- name: Should accept proxy config with all fields including networkPolicyProvisioning
1516+
resourceName: cluster
1517+
initial: |
1518+
apiVersion: operator.openshift.io/v1alpha1
1519+
kind: ExternalSecretsConfig
1520+
spec:
1521+
appConfig:
1522+
proxy:
1523+
httpProxy: "http://proxy.example.com:3128"
1524+
httpsProxy: "https://proxy.example.com:3129"
1525+
noProxy: "localhost,127.0.0.1,.cluster.local"
1526+
networkPolicyProvisioning: Unmanaged
1527+
expected: |
1528+
apiVersion: operator.openshift.io/v1alpha1
1529+
kind: ExternalSecretsConfig
1530+
spec:
1531+
appConfig:
1532+
logLevel: 1
1533+
proxy:
1534+
httpProxy: "http://proxy.example.com:3128"
1535+
httpsProxy: "https://proxy.example.com:3129"
1536+
noProxy: "localhost,127.0.0.1,.cluster.local"
1537+
networkPolicyProvisioning: Unmanaged
14481538
onUpdate:
14491539
- name: Should be able to update labels in controller config
14501540
resourceName: cluster
@@ -1726,3 +1816,30 @@ tests:
17261816
- to:
17271817
- ipBlock:
17281818
cidr: 172.16.0.0/12
1819+
- name: Should be able to update networkPolicyProvisioning from Managed to Unmanaged
1820+
resourceName: cluster
1821+
initial: |
1822+
apiVersion: operator.openshift.io/v1alpha1
1823+
kind: ExternalSecretsConfig
1824+
spec:
1825+
appConfig:
1826+
proxy:
1827+
httpProxy: "http://proxy.example.com:3128"
1828+
networkPolicyProvisioning: Managed
1829+
updated: |
1830+
apiVersion: operator.openshift.io/v1alpha1
1831+
kind: ExternalSecretsConfig
1832+
spec:
1833+
appConfig:
1834+
proxy:
1835+
httpProxy: "http://proxy.example.com:3128"
1836+
networkPolicyProvisioning: Unmanaged
1837+
expected: |
1838+
apiVersion: operator.openshift.io/v1alpha1
1839+
kind: ExternalSecretsConfig
1840+
spec:
1841+
appConfig:
1842+
logLevel: 1
1843+
proxy:
1844+
httpProxy: "http://proxy.example.com:3128"
1845+
networkPolicyProvisioning: Unmanaged

api/v1alpha1/tests/externalsecretsmanager.operator.openshift.io/externalsecretsmanager.testsuite.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ tests:
8888
proxy:
8989
httpProxy: "http://proxy.example.com:8080"
9090
httpsProxy: "https://proxy.example.com:8443"
91+
networkPolicyProvisioning: Managed
9192
noProxy: "localhost,127.0.0.1,.local"
9293
- name: Should fail to create with invalid singleton name
9394
resourceName: invalid-name
@@ -182,6 +183,7 @@ tests:
182183
logLevel: 1
183184
proxy:
184185
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"
186+
networkPolicyProvisioning: Managed
185187
- name: Should accept HTTPS proxy URL at maximum length boundary
186188
resourceName: cluster
187189
initial: |
@@ -200,6 +202,7 @@ tests:
200202
logLevel: 1
201203
proxy:
202204
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"
205+
networkPolicyProvisioning: Managed
203206
- name: Should accept empty proxy configuration
204207
resourceName: cluster
205208
initial: |
@@ -220,6 +223,7 @@ tests:
220223
proxy:
221224
httpProxy: ""
222225
httpsProxy: ""
226+
networkPolicyProvisioning: Managed
223227
noProxy: ""
224228
onUpdate:
225229
- name: Should be able to add global config after creation
@@ -337,6 +341,7 @@ tests:
337341
proxy:
338342
httpProxy: "http://proxy.company.com:3128"
339343
httpsProxy: "https://proxy.company.com:3128"
344+
networkPolicyProvisioning: Managed
340345
noProxy: "localhost,127.0.0.1,.company.com"
341346
- name: Should be able to update node selector and tolerations
342347
resourceName: cluster

bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ metadata:
220220
categories: Security
221221
console.openshift.io/disable-operand-delete: "true"
222222
containerImage: openshift.io/external-secrets-operator:latest
223-
createdAt: "2026-03-06T13:50:37Z"
223+
createdAt: "2026-05-18T08:51:19Z"
224224
features.operators.openshift.io/cnf: "false"
225225
features.operators.openshift.io/cni: "false"
226226
features.operators.openshift.io/csi: "false"

bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,18 @@ spec:
10341034
maxLength: 2048
10351035
minLength: 0
10361036
type: string
1037+
networkPolicyProvisioning:
1038+
default: Managed
1039+
description: |-
1040+
NetworkPolicyProvisioning defines the management strategy for the proxy egress rule.
1041+
When set to Managed, the operator automatically provisions and maintains
1042+
a NetworkPolicy allowing traffic to the configured proxy.
1043+
If no proxy is configured, no NetworkPolicy will be created
1044+
regardless of this setting.
1045+
enum:
1046+
- Managed
1047+
- Unmanaged
1048+
type: string
10371049
noProxy:
10381050
description: |-
10391051
noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used.
@@ -1515,6 +1527,7 @@ spec:
15151527
15161528
Each entry allows specifying a name for the generated NetworkPolicy object,
15171529
along with its full Kubernetes NetworkPolicy definition.
1530+
The operator prepends "eso-user-" to the provided name when creating the Kubernetes object.
15181531
15191532
If this field is not provided, external-secrets components will be isolated
15201533
with deny-all network policies, which will prevent proper operation.
@@ -1730,8 +1743,9 @@ spec:
17301743
x-kubernetes-list-type: atomic
17311744
name:
17321745
description: |-
1733-
name is a unique identifier for this network policy configuration.
1734-
This name will be used as part of the generated NetworkPolicy resource name.
1746+
Name is the logical identifier for this network policy entry.
1747+
The operator prepends "eso-user-" to this value when creating the Kubernetes
1748+
NetworkPolicy object (e.g. "allow-egress" becomes "eso-user-allow-egress").
17351749
maxLength: 253
17361750
minLength: 1
17371751
type: string

bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,18 @@ spec:
10311031
maxLength: 2048
10321032
minLength: 0
10331033
type: string
1034+
networkPolicyProvisioning:
1035+
default: Managed
1036+
description: |-
1037+
NetworkPolicyProvisioning defines the management strategy for the proxy egress rule.
1038+
When set to Managed, the operator automatically provisions and maintains
1039+
a NetworkPolicy allowing traffic to the configured proxy.
1040+
If no proxy is configured, no NetworkPolicy will be created
1041+
regardless of this setting.
1042+
enum:
1043+
- Managed
1044+
- Unmanaged
1045+
type: string
10341046
noProxy:
10351047
description: |-
10361048
noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used.

config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,18 @@ spec:
10341034
maxLength: 2048
10351035
minLength: 0
10361036
type: string
1037+
networkPolicyProvisioning:
1038+
default: Managed
1039+
description: |-
1040+
NetworkPolicyProvisioning defines the management strategy for the proxy egress rule.
1041+
When set to Managed, the operator automatically provisions and maintains
1042+
a NetworkPolicy allowing traffic to the configured proxy.
1043+
If no proxy is configured, no NetworkPolicy will be created
1044+
regardless of this setting.
1045+
enum:
1046+
- Managed
1047+
- Unmanaged
1048+
type: string
10371049
noProxy:
10381050
description: |-
10391051
noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used.
@@ -1515,6 +1527,7 @@ spec:
15151527
15161528
Each entry allows specifying a name for the generated NetworkPolicy object,
15171529
along with its full Kubernetes NetworkPolicy definition.
1530+
The operator prepends "eso-user-" to the provided name when creating the Kubernetes object.
15181531
15191532
If this field is not provided, external-secrets components will be isolated
15201533
with deny-all network policies, which will prevent proper operation.
@@ -1730,8 +1743,9 @@ spec:
17301743
x-kubernetes-list-type: atomic
17311744
name:
17321745
description: |-
1733-
name is a unique identifier for this network policy configuration.
1734-
This name will be used as part of the generated NetworkPolicy resource name.
1746+
Name is the logical identifier for this network policy entry.
1747+
The operator prepends "eso-user-" to this value when creating the Kubernetes
1748+
NetworkPolicy object (e.g. "allow-egress" becomes "eso-user-allow-egress").
17351749
maxLength: 253
17361750
minLength: 1
17371751
type: string

config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,18 @@ spec:
10311031
maxLength: 2048
10321032
minLength: 0
10331033
type: string
1034+
networkPolicyProvisioning:
1035+
default: Managed
1036+
description: |-
1037+
NetworkPolicyProvisioning defines the management strategy for the proxy egress rule.
1038+
When set to Managed, the operator automatically provisions and maintains
1039+
a NetworkPolicy allowing traffic to the configured proxy.
1040+
If no proxy is configured, no NetworkPolicy will be created
1041+
regardless of this setting.
1042+
enum:
1043+
- Managed
1044+
- Unmanaged
1045+
type: string
10341046
noProxy:
10351047
description: |-
10361048
noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used.

0 commit comments

Comments
 (0)