Use consistent protocol determination
This commit is contained in:
parent
e04ebaa364
commit
3b4c8ba439
3 changed files with 101 additions and 14 deletions
|
@ -313,6 +313,16 @@ Register the `IngressRoute` kind in the Kubernetes cluster before creating `Ingr
|
|||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||
```
|
||||
|
||||
!!! important "Configuring Backend Protocol"
|
||||
|
||||
There are 3 ways to configure the backend protocol for communication between Traefik and your pods:
|
||||
|
||||
- Setting the scheme explicitly (http/https/h2c)
|
||||
- Configuring the name of the kubernetes service port to start with https (https)
|
||||
- Setting the kubernetes service port to use port 443 (https)
|
||||
|
||||
If you do not configure the above, Traefik will assume an http connection.
|
||||
|
||||
### Kind: `Middleware`
|
||||
|
||||
`Middleware` is the CRD implementation of a [Traefik middleware](../../middlewares/overview.md).
|
||||
|
|
|
@ -307,9 +307,9 @@ func (c configBuilder) loadServers(fallbackNamespace string, svc v1alpha1.LoadBa
|
|||
|
||||
var servers []dynamic.Server
|
||||
if service.Spec.Type == corev1.ServiceTypeExternalName {
|
||||
protocol := "http"
|
||||
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, "https") {
|
||||
protocol = "https"
|
||||
protocol, err := parseServiceProtocol(svc.Scheme, portSpec.Name, portSpec.Port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return append(servers, dynamic.Server{
|
||||
|
@ -341,17 +341,9 @@ func (c configBuilder) loadServers(fallbackNamespace string, svc v1alpha1.LoadBa
|
|||
return nil, fmt.Errorf("cannot define a port for %s/%s", namespace, sanitizedName)
|
||||
}
|
||||
|
||||
protocol := httpProtocol
|
||||
scheme := svc.Scheme
|
||||
switch scheme {
|
||||
case httpProtocol, httpsProtocol, "h2c":
|
||||
protocol = scheme
|
||||
case "":
|
||||
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, httpsProtocol) {
|
||||
protocol = httpsProtocol
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid scheme %q specified", scheme)
|
||||
protocol, err := parseServiceProtocol(svc.Scheme, portSpec.Name, portSpec.Port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, addr := range subset.Addresses {
|
||||
|
@ -448,3 +440,19 @@ func getTLSHTTP(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sCli
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseServiceProtocol parses the scheme, port name, and number to determine the correct protocol.
|
||||
// an error is returned if the scheme provided is invalid.
|
||||
func parseServiceProtocol(providedScheme string, portName string, portNumber int32) (string, error) {
|
||||
switch providedScheme {
|
||||
case httpProtocol, httpsProtocol, "h2c":
|
||||
return providedScheme, nil
|
||||
case "":
|
||||
if portNumber == 443 || strings.HasPrefix(portName, httpsProtocol) {
|
||||
return httpsProtocol, nil
|
||||
}
|
||||
return httpProtocol, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("invalid scheme %q specified", providedScheme)
|
||||
}
|
||||
|
|
|
@ -2311,3 +2311,72 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseServiceProtocol(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
scheme string
|
||||
portName string
|
||||
portNumber int32
|
||||
expected string
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
desc: "Empty scheme and name",
|
||||
scheme: "",
|
||||
portName: "",
|
||||
portNumber: 1000,
|
||||
expected: "http",
|
||||
},
|
||||
{
|
||||
desc: "h2c scheme and emptyname",
|
||||
scheme: "h2c",
|
||||
portName: "",
|
||||
portNumber: 1000,
|
||||
expected: "h2c",
|
||||
},
|
||||
{
|
||||
desc: "invalid scheme",
|
||||
scheme: "foo",
|
||||
portName: "",
|
||||
portNumber: 1000,
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
desc: "Empty scheme and https name",
|
||||
scheme: "",
|
||||
portName: "https-secure",
|
||||
portNumber: 1000,
|
||||
expected: "https",
|
||||
},
|
||||
{
|
||||
desc: "Empty scheme and port number",
|
||||
scheme: "",
|
||||
portName: "",
|
||||
portNumber: 443,
|
||||
expected: "https",
|
||||
},
|
||||
{
|
||||
desc: "https scheme",
|
||||
scheme: "https",
|
||||
portName: "",
|
||||
portNumber: 1000,
|
||||
expected: "https",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
protocol, err := parseServiceProtocol(test.scheme, test.portName, test.portNumber)
|
||||
if test.expectedError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.Equal(t, test.expected, protocol)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue