From 48785720cc13e5b0ba92d3daac89d05d98b1f57b Mon Sep 17 00:00:00 2001 From: kahirokunn Date: Mon, 9 Mar 2026 15:23:03 +0900 Subject: [PATCH] feat: set IngressRule.Tag from traffic target name Populate the new Tag field when building IngressRules so that downstream ingress controllers can trace generated resources back to their originating traffic tag. Signed-off-by: kahirokunn --- pkg/reconciler/route/resources/ingress.go | 10 ++++++---- pkg/reconciler/route/resources/ingress_test.go | 15 ++++++++++++--- pkg/reconciler/route/route_test.go | 12 ++++++++++++ vendor/knative.dev/networking/config/ingress.yaml | 3 +++ .../pkg/apis/networking/v1alpha1/ingress_types.go | 4 ++++ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/pkg/reconciler/route/resources/ingress.go b/pkg/reconciler/route/resources/ingress.go index ba593ebe421d..c3af1363501a 100644 --- a/pkg/reconciler/route/resources/ingress.go +++ b/pkg/reconciler/route/resources/ingress.go @@ -155,7 +155,7 @@ func makeIngressSpec( return netv1alpha1.IngressSpec{}, err } domainRules := makeIngressRules(domains, r.Namespace, - visibility, tc.Targets[name], ro.RolloutsByTag(name), networkConfig.SystemInternalTLSEnabled()) + visibility, tc.Targets[name], ro.RolloutsByTag(name), networkConfig.SystemInternalTLSEnabled(), name) // Apply tag header routing and ACME merging to each rule for i := range domainRules { @@ -240,30 +240,32 @@ func makeIngressRules(domains sets.Set[string], ns string, targets traffic.RevisionTargets, roCfgs []*traffic.ConfigurationRollout, encryption bool, + tag string, ) []netv1alpha1.IngressRule { basePath := makeBaseIngressPath(ns, targets, roCfgs, encryption) // ClusterLocal: keep multi-host (no ACME challenges needed) if visibility == netv1alpha1.IngressVisibilityClusterLocal { - return []netv1alpha1.IngressRule{makeIngressRuleForHosts(sets.List(domains), visibility, basePath)} + return []netv1alpha1.IngressRule{makeIngressRuleForHosts(sets.List(domains), visibility, basePath, tag)} } // ExternalIP: create one rule per domain (enables per-host ACME challenge merging) domainList := sets.List(domains) rules := make([]netv1alpha1.IngressRule, 0, len(domainList)) for _, domain := range domainList { - rules = append(rules, makeIngressRuleForHosts([]string{domain}, visibility, basePath)) + rules = append(rules, makeIngressRuleForHosts([]string{domain}, visibility, basePath, tag)) } return rules } -func makeIngressRuleForHosts(hosts []string, visibility netv1alpha1.IngressVisibility, basePath *netv1alpha1.HTTPIngressPath) netv1alpha1.IngressRule { +func makeIngressRuleForHosts(hosts []string, visibility netv1alpha1.IngressVisibility, basePath *netv1alpha1.HTTPIngressPath, tag string) netv1alpha1.IngressRule { return netv1alpha1.IngressRule{ Hosts: hosts, Visibility: visibility, HTTP: &netv1alpha1.HTTPIngressRuleValue{ Paths: []netv1alpha1.HTTPIngressPath{*basePath}, }, + Tag: tag, } } diff --git a/pkg/reconciler/route/resources/ingress_test.go b/pkg/reconciler/route/resources/ingress_test.go index 2bfd12db0ff8..6effe1ee2dbb 100644 --- a/pkg/reconciler/route/resources/ingress_test.go +++ b/pkg/reconciler/route/resources/ingress_test.go @@ -400,6 +400,7 @@ func TestMakeIngressWithActualRollout(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityClusterLocal, + Tag: "hammer", }, { Hosts: []string{ "hammer-test-route." + ns + ".example.com", @@ -454,6 +455,7 @@ func TestMakeIngressWithActualRollout(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityExternalIP, + Tag: "hammer", }} if got, want := ing.Spec.Rules, wantRules; !cmp.Equal(got, want) { t.Errorf("Rules mismatch: diff(-want,+got)\n%s", cmp.Diff(want, got)) @@ -562,6 +564,7 @@ func TestMakeIngressSpecCorrectRules(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityClusterLocal, + Tag: "v1", }, { Hosts: []string{ "v1-test-route." + ns + ".example.com", @@ -583,6 +586,7 @@ func TestMakeIngressSpecCorrectRules(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityExternalIP, + Tag: "v1", }} tc := &traffic.Config{Targets: targets} @@ -811,6 +815,7 @@ func TestMakeIngressSpecCorrectRulesWithTagBasedRouting(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityClusterLocal, + Tag: "v1", }, { Hosts: []string{ "v1-test-route." + ns + ".example.com", @@ -835,6 +840,7 @@ func TestMakeIngressSpecCorrectRulesWithTagBasedRouting(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityExternalIP, + Tag: "v1", }} ctx := testContext() @@ -869,7 +875,7 @@ func TestMakeIngressRuleVanilla(t *testing.T) { } ro := tc.BuildRollout() rules := makeIngressRules(domains, ns, - netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), false /* internal encryption */) + netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), false /* internal encryption */, traffic.DefaultTarget) // ExternalIP visibility creates one rule per host if len(rules) != 2 { @@ -930,7 +936,7 @@ func TestMakeIngressRuleZeroPercentTarget(t *testing.T) { } ro := tc.BuildRollout() rules := makeIngressRules(domains, ns, - netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), false /* internal encryption */) + netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), false /* internal encryption */, traffic.DefaultTarget) if len(rules) != 1 { t.Fatalf("Expected 1 rule, got %d", len(rules)) @@ -985,7 +991,7 @@ func TestMakeIngressRuleTwoTargets(t *testing.T) { ro := tc.BuildRollout() domains := sets.New("test.org") rules := makeIngressRules(domains, ns, netv1alpha1.IngressVisibilityExternalIP, - targets, ro.RolloutsByTag("a-tag"), false /* internal encryption */) + targets, ro.RolloutsByTag("a-tag"), false /* internal encryption */, "a-tag") if len(rules) != 1 { t.Fatalf("Expected 1 rule, got %d", len(rules)) @@ -1021,6 +1027,7 @@ func TestMakeIngressRuleTwoTargets(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityExternalIP, + Tag: "a-tag", } if !cmp.Equal(expected, rules[0]) { @@ -1196,6 +1203,7 @@ func TestMakeIngressWithActivatorCA(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityClusterLocal, + Tag: "v1", }, { Hosts: []string{ "v1-test-route." + ns + ".example.com", @@ -1217,6 +1225,7 @@ func TestMakeIngressWithActivatorCA(t *testing.T) { }}, }, Visibility: netv1alpha1.IngressVisibilityExternalIP, + Tag: "v1", }} tc := &traffic.Config{Targets: targets} diff --git a/pkg/reconciler/route/route_test.go b/pkg/reconciler/route/route_test.go index 7cc392ea3f39..c53fd814b422 100644 --- a/pkg/reconciler/route/route_test.go +++ b/pkg/reconciler/route/route_test.go @@ -681,6 +681,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityClusterLocal, + Tag: "test-revision-1", }, { Hosts: []string{ "test-revision-1-test-route.test.test-domain.dev", @@ -702,6 +703,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityExternalIP, + Tag: "test-revision-1", }, { Hosts: []string{ "test-revision-2-test-route.test", @@ -725,6 +727,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityClusterLocal, + Tag: "test-revision-2", }, { Hosts: []string{ "test-revision-2-test-route.test.test-domain.dev", @@ -746,6 +749,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityExternalIP, + Tag: "test-revision-2", }}, } @@ -885,6 +889,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityClusterLocal, + Tag: "bar", }, { Hosts: []string{"bar-test-route.test.test-domain.dev"}, HTTP: &v1alpha1.HTTPIngressRuleValue{ @@ -904,6 +909,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityExternalIP, + Tag: "bar", }, { Hosts: []string{ "foo-test-route.test", @@ -927,6 +933,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityClusterLocal, + Tag: "foo", }, { Hosts: []string{"foo-test-route.test.test-domain.dev"}, HTTP: &v1alpha1.HTTPIngressRuleValue{ @@ -946,6 +953,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityExternalIP, + Tag: "foo", }}, } @@ -1183,6 +1191,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityClusterLocal, + Tag: "bar", }, { Hosts: []string{ "bar-test-route.test.test-domain.dev", @@ -1207,6 +1216,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityExternalIP, + Tag: "bar", }, { Hosts: []string{ "foo-test-route.test", @@ -1233,6 +1243,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityClusterLocal, + Tag: "foo", }, { Hosts: []string{"foo-test-route.test.test-domain.dev"}, HTTP: &v1alpha1.HTTPIngressRuleValue{ @@ -1255,6 +1266,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) { }}, }, Visibility: v1alpha1.IngressVisibilityExternalIP, + Tag: "foo", }}, } diff --git a/vendor/knative.dev/networking/config/ingress.yaml b/vendor/knative.dev/networking/config/ingress.yaml index 33ee6b01542a..890490263a40 100644 --- a/vendor/knative.dev/networking/config/ingress.yaml +++ b/vendor/knative.dev/networking/config/ingress.yaml @@ -203,6 +203,9 @@ spec: - type: integer - type: string x-kubernetes-int-or-string: true + tag: + description: Tag is the name of the traffic tag associated with this rule. + type: string visibility: description: |- Visibility signifies whether this rule should `ClusterLocal`. If it's not diff --git a/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_types.go b/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_types.go index 44b0d74e2814..6b72ea1c0c1a 100644 --- a/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_types.go +++ b/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_types.go @@ -177,6 +177,10 @@ type IngressRule struct { // HTTP represents a rule to apply against incoming requests. If the // rule is satisfied, the request is routed to the specified backend. HTTP *HTTPIngressRuleValue `json:"http,omitempty"` + + // Tag is the name of the traffic tag associated with this rule. + // +optional + Tag string `json:"tag,omitzero"` } // HTTPIngressRuleValue is a list of http selectors pointing to backends.