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=
|
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`
|
### Kind: `Middleware`
|
||||||
|
|
||||||
`Middleware` is the CRD implementation of a [Traefik middleware](../../middlewares/overview.md).
|
`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
|
var servers []dynamic.Server
|
||||||
if service.Spec.Type == corev1.ServiceTypeExternalName {
|
if service.Spec.Type == corev1.ServiceTypeExternalName {
|
||||||
protocol := "http"
|
protocol, err := parseServiceProtocol(svc.Scheme, portSpec.Name, portSpec.Port)
|
||||||
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, "https") {
|
if err != nil {
|
||||||
protocol = "https"
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(servers, dynamic.Server{
|
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)
|
return nil, fmt.Errorf("cannot define a port for %s/%s", namespace, sanitizedName)
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol := httpProtocol
|
protocol, err := parseServiceProtocol(svc.Scheme, portSpec.Name, portSpec.Port)
|
||||||
scheme := svc.Scheme
|
if err != nil {
|
||||||
switch scheme {
|
return nil, err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, addr := range subset.Addresses {
|
for _, addr := range subset.Addresses {
|
||||||
|
@ -448,3 +440,19 @@ func getTLSHTTP(ctx context.Context, ingressRoute *v1alpha1.IngressRoute, k8sCli
|
||||||
|
|
||||||
return nil
|
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…
Add table
Reference in a new issue