diff --git a/modules/common/endpoint/endpoint.go b/modules/common/endpoint/endpoint.go index 32c34e9fd..b725a6d9f 100644 --- a/modules/common/endpoint/endpoint.go +++ b/modules/common/endpoint/endpoint.go @@ -33,6 +33,9 @@ import ( // Endpoint - typedef to enumerate Endpoint verbs type Endpoint string +// Protocol of the endpoint (http/https) +type Protocol string + const ( // EndpointAdmin - admin endpoint EndpointAdmin Endpoint = "admin" @@ -42,6 +45,12 @@ const ( EndpointPublic Endpoint = "public" // AnnotationHostnameKey - AnnotationHostnameKey = "dnsmasq.network.openstack.org/hostname" + // ProtocolHTTP - + ProtocolHTTP Protocol = "http" + // ProtocolHTTPS - + ProtocolHTTPS Protocol = "https" + // ProtocolNone - + ProtocolNone Protocol = "" ) // Data - information for generation of K8S services and Keystone endpoint URLs @@ -54,6 +63,8 @@ type Data struct { MetalLB *MetalLBData // possible overrides for Route RouteOverride *route.OverrideSpec + // protocol of the endpoint (http/https/none) + Protocol *Protocol } // MetalLBData - information specific to creating the MetalLB service @@ -175,7 +186,6 @@ func ExposeEndpoints( // Create the route if it is public endpoint if endpointType == EndpointPublic { // Create the route - // TODO TLS route := route.NewRoute( route.GenericRoute(&route.GenericRouteDetails{ Name: endpointName, @@ -189,6 +199,8 @@ func ExposeEndpoints( data.RouteOverride, ) + // TODO create TLS cert if non provided in override and data.Protocol == ProtocolHTTPS + ctrlResult, err = route.CreateOrPatch(ctx, h) if err != nil { return endpointMap, ctrlResult, err @@ -197,23 +209,20 @@ func ExposeEndpoints( } // create route - end + // set data.Protocol to https if the route has any spec.TLS configured + // (either automated, see TODO comment above, or via override) + if route.IsTLS() { + data.Protocol = PtrProtocol(ProtocolHTTPS) + } + hostname = route.GetHostname() } } // Update instance status with service endpoint url from route host information - var protocol string - - // TODO: need to support https default here - if !strings.HasPrefix(hostname, "http") { - protocol = "http://" - } else { - protocol = "" - } - // Do not include data.Path in parsing check because %(project_id)s // is invalid without being encoded, but they should not be encoded in the actual endpoint - apiEndpoint, err := url.Parse(protocol + hostname) + apiEndpoint, err := url.Parse(endptProtocol(data.Protocol) + hostname) if err != nil { return endpointMap, ctrl.Result{}, err } @@ -222,3 +231,19 @@ func ExposeEndpoints( return endpointMap, ctrl.Result{}, nil } + +func endptProtocol(proto *Protocol) string { + if proto == nil { + return string(ProtocolHTTP) + "://" + } + if *proto == ProtocolNone { + return "" + } + + return string(*proto) + "://" +} + +// PtrProtocol returns a pointer to a protocol. +func PtrProtocol(p Protocol) *Protocol { + return &p +} diff --git a/modules/common/endpoint/endpoint_test.go b/modules/common/endpoint/endpoint_test.go new file mode 100644 index 000000000..2dbc1b099 --- /dev/null +++ b/modules/common/endpoint/endpoint_test.go @@ -0,0 +1,60 @@ +/* +Copyright 2023 Red Hat + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package endpoint + +import ( + "testing" + + . "github.com/onsi/gomega" +) + +func TestEndptProtocol(t *testing.T) { + + tests := []struct { + name string + proto *Protocol + want string + }{ + { + name: "None protocol", + proto: PtrProtocol(ProtocolNone), + want: "", + }, + { + name: "http protocol", + proto: PtrProtocol(ProtocolHTTP), + want: "http://", + }, + { + name: "https protocol", + proto: PtrProtocol(ProtocolHTTPS), + want: "https://", + }, + { + name: "Nil protocol", + proto: nil, + want: "http://", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + g.Expect(endptProtocol(tt.proto)).To(Equal(tt.want)) + }) + } +} diff --git a/modules/common/route/route.go b/modules/common/route/route.go index 12f22d7e5..764eccaa1 100644 --- a/modules/common/route/route.go +++ b/modules/common/route/route.go @@ -53,6 +53,14 @@ func (r *Route) GetHostname() string { return r.hostname } +// IsTLS - returns true if spec.TLS is configured for the route +func (r *Route) IsTLS() bool { + if r.route.Spec.TLS != nil { + return true + } + return false +} + // GenericRoute func func GenericRoute(routeInfo *GenericRouteDetails) *routev1.Route { serviceRef := routev1.RouteTargetReference{ diff --git a/modules/common/test/functional/route_test.go b/modules/common/test/functional/route_test.go index 383950eab..48db80f0d 100644 --- a/modules/common/test/functional/route_test.go +++ b/modules/common/test/functional/route_test.go @@ -81,6 +81,7 @@ var _ = Describe("route package", func() { _, err := r.CreateOrPatch(ctx, h) Expect(err).ShouldNot(HaveOccurred()) + Expect(r.IsTLS()).To(BeFalse()) rv1 := th.AssertRouteExists(types.NamespacedName{Namespace: namespace, Name: "test-route"}) Expect(rv1.Annotations["anno"]).To(Equal("a")) Expect(rv1.Annotations["replace"]).To(Equal("a")) @@ -90,7 +91,6 @@ var _ = Describe("route package", func() { Expect(rv1.Spec.Port.TargetPort.IntVal).To(Equal(int32(80))) Expect(rv1.Spec.To.Name).To(Equal("my-service")) Expect(*rv1.Spec.To.Weight).To(Equal(int32(100))) - }) It("merges labels to the route", func() { @@ -286,6 +286,7 @@ var _ = Describe("route package", func() { _, err := r.CreateOrPatch(ctx, h) Expect(err).ShouldNot(HaveOccurred()) + Expect(r.IsTLS()).To(BeTrue()) rv1 := th.AssertRouteExists(types.NamespacedName{Namespace: namespace, Name: "test-route"}) Expect(rv1.Spec.TLS.Termination).To(Equal(routev1.TLSTerminationEdge)) Expect(rv1.Spec.TLS.Certificate).To(Equal("cert"))