diff --git a/docs/user-guide/nginx-configuration/configmap.md b/docs/user-guide/nginx-configuration/configmap.md index 002f8a500..1ce47f582 100644 --- a/docs/user-guide/nginx-configuration/configmap.md +++ b/docs/user-guide/nginx-configuration/configmap.md @@ -195,6 +195,8 @@ The following table shows a configuration option's name, type, and the default v |[limit-rate](#limit-rate)| int | 0 || |[limit-rate-after](#limit-rate-after)| int | 0 || |[lua-shared-dicts](#lua-shared-dicts)| string | "" || +|[include-endpoint-target-refs](#include-endpoint-target-refs)| bool | "false" || + |[http-redirect-code](#http-redirect-code)| int | 308 || |[proxy-buffering](#proxy-buffering)| string | "off" || |[limit-req-status-code](#limit-req-status-code)| int | 503 || @@ -1212,6 +1214,10 @@ lua-shared-dicts: "certificate_data: 100, my_custom_plugin: 512k" _References:_ [https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after](https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after) +## include-endpoint-target-refs + +Enables including an endpoint's target reference when updating the dynamic configuration of backends. Useful for exposing things like pod name. + ## http-redirect-code Sets the HTTP status code to be used in redirects. diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index 5e0ca2296..0a3ab0d89 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -709,6 +709,9 @@ type Configuration struct { // Lua shared dict configuration data / certificate data LuaSharedDicts map[string]int `json:"lua-shared-dicts"` + // Include endpoint target references (e.g., pod name) when updating dynamic configuration + IncludeEndpointTargetRefs bool `json:"include-endpoint-target-refs"` + // DefaultSSLCertificate holds the default SSL certificate to use in the configuration // It can be the fake certificate or the one behind the flag --default-ssl-certificate DefaultSSLCertificate *ingress.SSLCert `json:"-"` @@ -828,6 +831,7 @@ func NewDefault() Configuration { LogFormatEscapeJSON: false, LogFormatStream: logFormatStream, LogFormatUpstream: logFormatUpstream, + IncludeEndpointTargetRefs: false, EnableMultiAccept: true, MaxWorkerConnections: 16384, MaxWorkerOpenFiles: 0, diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go index f74b3245e..c10aed864 100644 --- a/internal/ingress/controller/nginx.go +++ b/internal/ingress/controller/nginx.go @@ -859,7 +859,7 @@ func (n *NGINXController) setupSSLProxy() { func (n *NGINXController) configureDynamically(pcfg *ingress.Configuration) error { backendsChanged := !reflect.DeepEqual(n.runningConfig.Backends, pcfg.Backends) if backendsChanged { - err := configureBackends(pcfg.Backends) + err := n.configureBackends(pcfg.Backends) if err != nil { return err } @@ -941,7 +941,9 @@ func updateStreamConfiguration(tcpEndpoints, udpEndpoints []ingress.L4Service) e return nil } -func configureBackends(rawBackends []*ingress.Backend) error { +func (n *NGINXController) configureBackends(rawBackends []*ingress.Backend) error { + backend_config := n.store.GetBackendConfiguration() + backends := make([]*ingress.Backend, len(rawBackends)) for i, backend := range rawBackends { @@ -962,15 +964,21 @@ func configureBackends(rawBackends []*ingress.Backend) error { AlternativeBackends: backend.AlternativeBackends, } - var endpoints []ingress.Endpoint + var luaEndpoints []ingress.Endpoint for _, endpoint := range backend.Endpoints { - endpoints = append(endpoints, ingress.Endpoint{ + luaEndpoint := ingress.Endpoint{ Address: endpoint.Address, Port: endpoint.Port, - }) + } + + if backend_config.IncludeEndpointTargetRefs { + luaEndpoint.Target = endpoint.Target + } + + luaEndpoints = append(luaEndpoints, luaEndpoint) } - luaBackend.Endpoints = endpoints + luaBackend.Endpoints = luaEndpoints backends[i] = luaBackend } diff --git a/internal/ingress/controller/nginx_test.go b/internal/ingress/controller/nginx_test.go index 27180e066..37224af3e 100644 --- a/internal/ingress/controller/nginx_test.go +++ b/internal/ingress/controller/nginx_test.go @@ -28,10 +28,16 @@ import ( "testing" "time" + "github.com/eapache/channels" jsoniter "github.com/json-iterator/go" apiv1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes/fake" + "k8s.io/ingress-nginx/internal/ingress/controller/ingressclass" + "k8s.io/ingress-nginx/internal/ingress/controller/store" "k8s.io/ingress-nginx/internal/nginx" "k8s.io/ingress-nginx/pkg/apis/ingress" ) @@ -49,6 +55,7 @@ func TestConfigureDynamically(t *testing.T) { } defer streamListener.Close() + targetIncluded := false endpointStats := map[string]int{"/configuration/backends": 0, "/configuration/general": 0, "/configuration/servers": 0} resetEndpointStats := func() { for k := range endpointStats { @@ -78,7 +85,7 @@ func TestConfigureDynamically(t *testing.T) { switch r.URL.Path { case "/configuration/backends": if strings.Contains(body, "target") { - t.Errorf("unexpected target reference in JSON content: %v", body) + targetIncluded = true } if !strings.Contains(body, "service") { @@ -133,9 +140,28 @@ func TestConfigureDynamically(t *testing.T) { Servers: servers, } + ns := corev1.NamespaceDefault + + storer := store.New( + ns, + labels.Nothing(), + fmt.Sprintf("%v/config", ns), + fmt.Sprintf("%v/tcp", ns), + fmt.Sprintf("%v/udp", ns), + "", + 10*time.Minute, + fake.NewSimpleClientset(), + channels.NewRingChannel(10), + false, + true, + &ingressclass.Configuration{}, + false, + ) + n := &NGINXController{ runningConfig: &ingress.Configuration{}, cfg: &Configuration{}, + store: storer, } err = n.configureDynamically(commonConfig) @@ -145,6 +171,19 @@ func TestConfigureDynamically(t *testing.T) { if commonConfig.Backends[0].Endpoints[0].Target != target { t.Errorf("unexpected change in the configuration object after configureDynamically invocation") } + if targetIncluded { + t.Errorf("unexpected target reference in JSON content") + } + + backend_config := n.store.GetBackendConfiguration() + err = n.configureDynamically(commonConfig) + if err != nil { + t.Errorf("unexpected error posting dynamic configuration: %v", err) + } + if !targetIncluded { + t.Errorf("expected target reference in JSON content not found") + } + backend_config.IncludeEndpointTargetRefs = false resetEndpointStats() n.runningConfig.Backends = backends