diff --git a/CHANGELOG.md b/CHANGELOG.md index 4985700316..542a4e5127 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -108,6 +108,8 @@ Adding a new version? You'll need three changes: in translating and applying configurations to Kong. [#5296](https://github.com/Kong/kubernetes-ingress-controller/pull/5296) [#5299](https://github.com/Kong/kubernetes-ingress-controller/pull/5299) +- Added support in Gateway Discovery for specifying that the Admin API should use HTTP via the appProtocol field on the admin port. + [#5251](https://github.com/Kong/kubernetes-ingress-controller/pull/5251) ### Fixed diff --git a/internal/adminapi/endpoints.go b/internal/adminapi/endpoints.go index c3d4f9a78d..3d47f075cb 100644 --- a/internal/adminapi/endpoints.go +++ b/internal/adminapi/endpoints.go @@ -162,15 +162,19 @@ func adminAPIFromEndpoint( Namespace: endpoint.TargetRef.Namespace, } + // Format for calling the Admin API. If the port explicitly indicates http as the AppProtocol, use http. + // Otherwise, default to HTTPS as a best practice. Consumers may want to use HTTP if they have a service mesh in place which + // is already handling TLS authentication for them. + adminAPIAddressFormat := "https://%s:%d" + if port.AppProtocol != nil && *port.AppProtocol == "http" { + adminAPIAddressFormat = "http://%s:%d" + } + // NOTE: Endpoint's addresses are assumed to be fungible, therefore we pick // only the first one. // For the context please see the `Endpoint.Addresses` godoc. eAddress := endpoint.Addresses[0] - // NOTE: We assume https below because the referenced Admin API - // server will live in another Pod/elsewhere so allowing http would - // not be considered best practice. - switch dnsStrategy { case cfgtypes.ServiceScopedPodDNSStrategy: if service.Name == "" { @@ -184,7 +188,7 @@ func adminAPIFromEndpoint( address := fmt.Sprintf("%s.%s.%s.svc", ipAddr, service.Name, service.Namespace) return DiscoveredAdminAPI{ - Address: fmt.Sprintf("https://%s:%d", address, *port.Port), + Address: fmt.Sprintf(adminAPIAddressFormat, address, *port.Port), PodRef: podNN, }, nil @@ -193,7 +197,7 @@ func adminAPIFromEndpoint( address := fmt.Sprintf("%s.%s.pod", ipAddr, service.Namespace) return DiscoveredAdminAPI{ - Address: fmt.Sprintf("https://%s:%d", address, *port.Port), + Address: fmt.Sprintf(adminAPIAddressFormat, address, *port.Port), PodRef: podNN, }, nil @@ -203,7 +207,7 @@ func adminAPIFromEndpoint( bounded = fmt.Sprintf("[%s]", bounded) } return DiscoveredAdminAPI{ - Address: fmt.Sprintf("https://%s:%d", bounded, *port.Port), + Address: fmt.Sprintf(adminAPIAddressFormat, bounded, *port.Port), PodRef: podNN, }, nil diff --git a/internal/adminapi/endpoints_test.go b/internal/adminapi/endpoints_test.go index d905786dec..5406b5797d 100644 --- a/internal/adminapi/endpoints_test.go +++ b/internal/adminapi/endpoints_test.go @@ -81,6 +81,34 @@ func TestDiscoverer_AddressesFromEndpointSlice(t *testing.T) { ), dnsStrategy: cfgtypes.NamespaceScopedPodDNSStrategy, }, + { + name: "basic with appProtocol http", + endpoints: discoveryv1.EndpointSlice{ + ObjectMeta: endpointsSliceObjectMeta, + AddressType: discoveryv1.AddressTypeIPv4, + Endpoints: []discoveryv1.Endpoint{ + { + Addresses: []string{"10.0.0.1", "10.0.0.2"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: lo.ToPtr(true), + Terminating: lo.ToPtr(false), + }, + TargetRef: testPodReference(namespaceName, "pod-1"), + }, + }, + Ports: builder.NewEndpointPort(8444).WithName("admin").WithAppProtocol("http").IntoSlice(), + }, + portNames: sets.New("admin"), + want: sets.New( + DiscoveredAdminAPI{ + Address: "http://10-0-0-1.ns.pod:8444", + PodRef: k8stypes.NamespacedName{ + Name: "pod-1", Namespace: namespaceName, + }, + }, + ), + dnsStrategy: cfgtypes.NamespaceScopedPodDNSStrategy, + }, { name: "basic", endpoints: discoveryv1.EndpointSlice{ diff --git a/internal/util/builder/endpointport.go b/internal/util/builder/endpointport.go index fbe3002cc2..18c714ae63 100644 --- a/internal/util/builder/endpointport.go +++ b/internal/util/builder/endpointport.go @@ -32,6 +32,12 @@ func (b *EndpointPortBuilder) WithName(name string) *EndpointPortBuilder { return b } +// WithAppProtocol sets the appProtocol on the endpoint port. +func (b *EndpointPortBuilder) WithAppProtocol(appProtocol string) *EndpointPortBuilder { + b.ep.AppProtocol = lo.ToPtr(appProtocol) + return b +} + // Build returns the configured EndpointPort. func (b *EndpointPortBuilder) Build() discoveryv1.EndpointPort { return b.ep