From 26346d08e5bcfabecc12065f6a749faa91fad475 Mon Sep 17 00:00:00 2001 From: Simon Gerber Date: Tue, 11 Nov 2025 13:20:34 +0100 Subject: [PATCH] Add support for configuring arbitrary policy labels on namespace egress policies This commit introduces a new field `policy_labels` for entries in `egress_ip_ranges`. In contrast to field `bgp_policy_labels`, providing labels in the new field doesn't modify the behavior of the policy generation. --- component/egress-gateway-policies.jsonnet | 1 + .../egress-gateway-self-service.jsonnet | 1 + component/espejote-templates/egress-gateway.libsonnet | 3 ++- docs/modules/ROOT/pages/references/parameters.adoc | 10 +++++++++- tests/egress-gateway.yml | 2 ++ .../cilium/cilium/20_namespace_egress_ip_policies.yaml | 2 ++ .../cilium/cilium/40_egress_ip_managed_resource.yaml | 7 ++++++- 7 files changed, 23 insertions(+), 3 deletions(-) diff --git a/component/egress-gateway-policies.jsonnet b/component/egress-gateway-policies.jsonnet index 866227f3c..9ad0a0041 100644 --- a/component/egress-gateway-policies.jsonnet +++ b/component/egress-gateway-policies.jsonnet @@ -34,6 +34,7 @@ local egress_ip_policies = std.flattenArrays([ EgressGatewayPolicy, destination_cidrs=dest_cidrs, bgp_policy_labels=std.get(cfg, 'bgp_policy_labels', {}), + policy_labels=std.get(cfg, 'policy_labels', {}), ) for namespace in std.objectFields(ns_egress_ips) if ns_egress_ips[namespace] != null diff --git a/component/espejote-templates/egress-gateway-self-service.jsonnet b/component/espejote-templates/egress-gateway-self-service.jsonnet index 8732722f5..5e3b1427d 100644 --- a/component/espejote-templates/egress-gateway-self-service.jsonnet +++ b/component/espejote-templates/egress-gateway-self-service.jsonnet @@ -54,6 +54,7 @@ local reconcileNamespace(namespace) = egw.IsovalentEgressGatewayPolicy, destination_cidrs=std.get(range, 'destination_cidrs', []), bgp_policy_labels=std.get(range, 'bgp_policy_labels', {}), + policy_labels=std.get(range, 'policy_labels', {}), ) { metadata+: { labels+: egw.espejoteLabel, diff --git a/component/espejote-templates/egress-gateway.libsonnet b/component/espejote-templates/egress-gateway.libsonnet index ff3f0196a..db8488ff0 100644 --- a/component/espejote-templates/egress-gateway.libsonnet +++ b/component/espejote-templates/egress-gateway.libsonnet @@ -44,6 +44,7 @@ local NamespaceEgressPolicy = policy_resource_fn, destination_cidrs=null, bgp_policy_labels={}, + policy_labels={}, ) // Helper which computes the interface index of the egress IP. // Assumes that the IPs in egress_range are assigned to dummy interfaces @@ -122,7 +123,7 @@ local NamespaceEgressPolicy = [if std.length(shadow_ips) > 0 then 'cilium.syn.tools/shadow-ips']: std.manifestJsonMinified(shadow_ips), }, - labels+: bgp_policy_labels, + labels+: policy_labels + bgp_policy_labels, }, spec: { destinationCIDRs: dest_cidrs, diff --git a/docs/modules/ROOT/pages/references/parameters.adoc b/docs/modules/ROOT/pages/references/parameters.adoc index cc1fcc631..e325b73de 100644 --- a/docs/modules/ROOT/pages/references/parameters.adoc +++ b/docs/modules/ROOT/pages/references/parameters.adoc @@ -381,7 +381,7 @@ default:: `{}` This parameter allows users to configure `CiliumEgressGatewayPolicy` (or `IsovalentEgressGatewayPolicy`) resources which assign a single egress IP to a namespace according to the design selected in https://kb.vshn.ch/oc4/explanations/decisions/cloudscale-cilium-egressip.html[Floating egress IPs with Cilium on cloudscale]. Each entry in the parameter is intended to describe a group of dummy interfaces that can be used in `CiliumEgressGatewayPolicy` (or `IsovalentEgressGatewayPolicy`) resources. -The component expects that each value is an object with fields `egress_cidr`, `egress_range`, `node_selector`, `namespace_egress_ips`, `shadow_ranges`, `destination_cidrs`, and `bgp_policy_labels`. +The component expects that each value is an object with fields `egress_cidr`, `egress_range`, `node_selector`, `namespace_egress_ips`, `shadow_ranges`, `destination_cidrs`, `bgp_policy_labels`, and `policy_labels`. Fields `egress_cidr` and `egress_range` are mutually exclusive. The component raises an error for entries which set neither or both. @@ -428,6 +428,14 @@ Please note that policies which use EGW IPAM will ignore static routes on the ac If the field is omitted or empty, the component configures the egress group with the interface name and doesn't set `maxGatewayNodes`. ==== +[NOTE] +==== +Field `policy_labels` is optional. + +The component adds all labels in `policy_labels` as labels on the generated egress policies. +If you specify labels in this parameter and in `bgp_policy_labels` and you specify the same label key in both fields, the label value provided in `bgp_policy_labels` will win. +==== + ==== Prerequisites The component expects that the key for each entry matches the prefix of the dummy interface names that are assigned the shadow IPs which map to the egress IP range defined in `egress_range`. diff --git a/tests/egress-gateway.yml b/tests/egress-gateway.yml index 15693454e..2a41bae77 100644 --- a/tests/egress-gateway.yml +++ b/tests/egress-gateway.yml @@ -47,6 +47,8 @@ parameters: infra-87c9: 198.51.100.32 - 198.51.100.63 infra-eba2: 198.51.100.64 - 198.51.100.95 destination_cidrs: [] + policy_labels: + cilium.syn.tools/test: additional-policy-label egress_b: null egress_c: egress_cidr: 192.0.2.64/27 diff --git a/tests/golden/egress-gateway/cilium/cilium/20_namespace_egress_ip_policies.yaml b/tests/golden/egress-gateway/cilium/cilium/20_namespace_egress_ip_policies.yaml index f9d490381..e5fc575d4 100644 --- a/tests/golden/egress-gateway/cilium/cilium/20_namespace_egress_ip_policies.yaml +++ b/tests/golden/egress-gateway/cilium/cilium/20_namespace_egress_ip_policies.yaml @@ -12,6 +12,7 @@ metadata: cilium.syn.tools/shadow-ips: '["198.51.100.29","198.51.100.61","198.51.100.93"]' cilium.syn.tools/source-namespace: bar labels: + cilium.syn.tools/test: additional-policy-label name: bar name: bar spec: @@ -70,6 +71,7 @@ metadata: cilium.syn.tools/shadow-ips: '["198.51.100.0","198.51.100.32","198.51.100.64"]' cilium.syn.tools/source-namespace: foo labels: + cilium.syn.tools/test: additional-policy-label name: foo name: foo spec: diff --git a/tests/golden/egress-gateway/cilium/cilium/40_egress_ip_managed_resource.yaml b/tests/golden/egress-gateway/cilium/cilium/40_egress_ip_managed_resource.yaml index d7e4b2f57..ce086a0b8 100644 --- a/tests/golden/egress-gateway/cilium/cilium/40_egress_ip_managed_resource.yaml +++ b/tests/golden/egress-gateway/cilium/cilium/40_egress_ip_managed_resource.yaml @@ -81,6 +81,9 @@ spec: "node_selector": { "node-role.kubernetes.io/infra": "" }, + "policy_labels": { + "cilium.syn.tools/test": "additional-policy-label" + }, "shadow_ranges": { "infra-8344": "198.51.100.0 - 198.51.100.31", "infra-87c9": "198.51.100.32 - 198.51.100.63", @@ -195,6 +198,7 @@ spec: policy_resource_fn, destination_cidrs=null, bgp_policy_labels={}, + policy_labels={}, ) // Helper which computes the interface index of the egress IP. // Assumes that the IPs in egress_range are assigned to dummy interfaces @@ -273,7 +277,7 @@ spec: [if std.length(shadow_ips) > 0 then 'cilium.syn.tools/shadow-ips']: std.manifestJsonMinified(shadow_ips), }, - labels+: bgp_policy_labels, + labels+: policy_labels + bgp_policy_labels, }, spec: { destinationCIDRs: dest_cidrs, @@ -635,6 +639,7 @@ spec: egw.IsovalentEgressGatewayPolicy, destination_cidrs=std.get(range, 'destination_cidrs', []), bgp_policy_labels=std.get(range, 'bgp_policy_labels', {}), + policy_labels=std.get(range, 'policy_labels', {}), ) { metadata+: { labels+: egw.espejoteLabel,