Filter ingress class resources by name

Co-authored-by: SantoDE <manuel.zapf@traefik.io>
This commit is contained in:
Tom Moulard 2021-03-02 21:34:03 +01:00 committed by GitHub
parent 438eec720a
commit e658712d53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 364 additions and 6 deletions

View file

@ -616,7 +616,7 @@ Kubernetes certificate authority file path (not needed for in-cluster client).
Kubernetes server endpoint (required for external cluster client).
`--providers.kubernetesingress.ingressclass`:
Value of kubernetes.io/ingress.class annotation to watch for.
Value of kubernetes.io/ingress.class annotation or IngressClass name to watch for.
`--providers.kubernetesingress.ingressendpoint.hostname`:
Hostname used for Kubernetes Ingress endpoints.

View file

@ -616,7 +616,7 @@ Kubernetes certificate authority file path (not needed for in-cluster client).
Kubernetes server endpoint (required for external cluster client).
`TRAEFIK_PROVIDERS_KUBERNETESINGRESS_INGRESSCLASS`:
Value of kubernetes.io/ingress.class annotation to watch for.
Value of kubernetes.io/ingress.class annotation or IngressClass name to watch for.
`TRAEFIK_PROVIDERS_KUBERNETESINGRESS_INGRESSENDPOINT_HOSTNAME`:
Hostname used for Kubernetes Ingress endpoints.

View file

@ -0,0 +1,70 @@
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
name: traefik-keep
spec:
controller: traefik.io/ingress-controller
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: "whoami-keep-route"
spec:
ingressClassName: "traefik-keep"
rules:
- host: "whoami.test.keep"
http:
paths:
- path: "/keep"
backend:
serviceName: "whoami"
servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
name: traefik-drop
spec:
controller: traefik.io/ingress-controller
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: "whoami-drop-route"
spec:
ingressClassName: "traefik-drop"
rules:
- host: "whoami.test.drop"
http:
paths:
- path: "/drop"
backend:
serviceName: "whoami"
servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
name: traefik-not-ingress-controller
spec:
controller: not.tr43phic.io/ingress-controller
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: "whoami-drop-ingress"
spec:
ingressClassName: "traefik-not-ingress-controller"
rules:
- host: "whoami.test.not.ingress"
http:
paths:
- path: "/ingress"
backend:
serviceName: "whoami"
servicePort: 80

View file

@ -0,0 +1,16 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
[api]
insecure = true
[entryPoints]
[entryPoints.web]
address = ":8000"
[providers.kubernetesIngress]
ingressClass = "traefik-keep"

View file

@ -119,6 +119,17 @@ func (s *K8sSuite) TestGatewayConfiguration(c *check.C) {
testConfiguration(c, "testdata/rawdata-gateway.json", "8080")
}
func (s *K8sSuite) TestIngressclass(c *check.C) {
cmd, display := s.traefikCmd(withConfigFile("fixtures/k8s_ingressclass.toml"))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
testConfiguration(c, "testdata/rawdata-ingressclass.json", "8080")
}
func testConfiguration(c *check.C, path, apiPort string) {
err := try.GetRequest("http://127.0.0.1:"+apiPort+"/api/entrypoints", 20*time.Second, try.BodyContains(`"name":"web"`))
c.Assert(err, checker.IsNil)

View file

@ -1,5 +1,5 @@
server:
image: rancher/k3s:v1.17.2-k3s1
image: rancher/k3s:v1.18.15-k3s1
command: server --disable-agent --no-deploy coredns --no-deploy servicelb --no-deploy traefik --no-deploy local-storage --no-deploy metrics-server --log /output/k3s.log
environment:
- K3S_CLUSTER_SECRET=somethingtotallyrandom
@ -12,7 +12,7 @@ server:
- 6443:6443
node:
image: rancher/k3s:v1.17.2-k3s1
image: rancher/k3s:v1.18.15-k3s1
privileged: true
links:
- server

View file

@ -49,6 +49,28 @@
"using": [
"web"
]
},
"whoami-drop-route-default-whoami-test-drop-drop@kubernetes": {
"entryPoints": [
"web"
],
"service": "default-whoami-80",
"rule": "Host(`whoami.test.drop`) \u0026\u0026 PathPrefix(`/drop`)",
"status": "enabled",
"using": [
"web"
]
},
"whoami-keep-route-default-whoami-test-keep-keep@kubernetes": {
"entryPoints": [
"web"
],
"service": "default-whoami-80",
"rule": "Host(`whoami.test.keep`) \u0026\u0026 PathPrefix(`/keep`)",
"status": "enabled",
"using": [
"web"
]
}
},
"middlewares": {
@ -89,6 +111,28 @@
"dashboard@internal"
]
},
"default-whoami-80@kubernetes": {
"loadBalancer": {
"servers": [
{
"url": "XXXX"
},
{
"url": "XXXX"
}
],
"passHostHeader": true
},
"status": "enabled",
"usedBy": [
"whoami-drop-route-default-whoami-test-drop-drop@kubernetes",
"whoami-keep-route-default-whoami-test-keep-keep@kubernetes"
],
"serverStatus": {
"http://XXXX": "UP",
"http://XXXX": "UP"
}
},
"default-whoami-http@kubernetes": {
"loadBalancer": {
"servers": [

View file

@ -0,0 +1,106 @@
{
"routers": {
"api@internal": {
"entryPoints": [
"traefik"
],
"service": "api@internal",
"rule": "PathPrefix(`/api`)",
"priority": 2147483646,
"status": "enabled",
"using": [
"traefik"
]
},
"dashboard@internal": {
"entryPoints": [
"traefik"
],
"middlewares": [
"dashboard_redirect@internal",
"dashboard_stripprefix@internal"
],
"service": "dashboard@internal",
"rule": "PathPrefix(`/`)",
"priority": 2147483645,
"status": "enabled",
"using": [
"traefik"
]
},
"whoami-keep-route-default-whoami-test-keep-keep@kubernetes": {
"entryPoints": [
"web"
],
"service": "default-whoami-80",
"rule": "Host(`whoami.test.keep`) \u0026\u0026 PathPrefix(`/keep`)",
"status": "enabled",
"using": [
"web"
]
}
},
"middlewares": {
"dashboard_redirect@internal": {
"redirectRegex": {
"regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$",
"replacement": "${1}/dashboard/",
"permanent": true
},
"status": "enabled",
"usedBy": [
"dashboard@internal"
]
},
"dashboard_stripprefix@internal": {
"stripPrefix": {
"prefixes": [
"/dashboard/",
"/dashboard"
]
},
"status": "enabled",
"usedBy": [
"dashboard@internal"
]
}
},
"services": {
"api@internal": {
"status": "enabled",
"usedBy": [
"api@internal"
]
},
"dashboard@internal": {
"status": "enabled",
"usedBy": [
"dashboard@internal"
]
},
"default-whoami-80@kubernetes": {
"loadBalancer": {
"servers": [
{
"url": "http://10.42.0.4:80"
},
{
"url": "http://10.42.0.5:80"
}
],
"passHostHeader": true
},
"status": "enabled",
"usedBy": [
"whoami-keep-route-default-whoami-test-keep-keep@kubernetes"
],
"serverStatus": {
"http://10.42.0.4:80": "UP",
"http://10.42.0.5:80": "UP"
}
},
"noop@internal": {
"status": "enabled"
}
}
}

View file

@ -476,3 +476,16 @@ func supportsIngressClass(serverVersion *version.Version) bool {
return ingressClassVersion.LessThanOrEqual(serverVersion)
}
// filterIngressClassByName return a slice containing ingressclasses with the correct name.
func filterIngressClassByName(ingressClassName string, ics []*networkingv1beta1.IngressClass) []*networkingv1beta1.IngressClass {
var ingressClasses []*networkingv1beta1.IngressClass
for _, ic := range ics {
if ic.Name == ingressClassName {
ingressClasses = append(ingressClasses, ic)
}
}
return ingressClasses
}

View file

@ -0,0 +1,11 @@
kind: Endpoints
apiVersion: v1
metadata:
name: service1
namespace: testing
subsets:
- addresses:
- ip: 10.10.0.1
ports:
- port: 8080

View file

@ -0,0 +1,30 @@
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: ""
namespace: testing
spec:
ingressClassName: traefik-lb
rules:
- http:
paths:
- path: /bar
backend:
serviceName: service1
servicePort: 80
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: ""
namespace: testing
spec:
ingressClassName: traefik-lb2
rules:
- http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 80

View file

@ -0,0 +1,14 @@
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
name: traefik-lb2
spec:
controller: traefik.io/ingress-controller
---
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
name: traefik-lb
spec:
controller: traefik.io/ingress-controller

View file

@ -0,0 +1,10 @@
kind: Service
apiVersion: v1
metadata:
name: service1
namespace: testing
spec:
ports:
- port: 80
clusterIP: 10.0.0.1

View file

@ -42,7 +42,7 @@ type Provider struct {
CertAuthFilePath string `description:"Kubernetes certificate authority file path (not needed for in-cluster client)." json:"certAuthFilePath,omitempty" toml:"certAuthFilePath,omitempty" yaml:"certAuthFilePath,omitempty"`
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
LabelSelector string `description:"Kubernetes Ingress label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation or IngressClass name to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint." json:"ingressEndpoint,omitempty" toml:"ingressEndpoint,omitempty" yaml:"ingressEndpoint,omitempty" export:"true"`
ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
lastConfiguration safe.Safe
@ -198,7 +198,11 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
log.FromContext(ctx).Warnf("Failed to list ingress classes: %v", err)
}
ingressClasses = ics
if p.IngressClass != "" {
ingressClasses = filterIngressClassByName(p.IngressClass, ics)
} else {
ingressClasses = ics
}
}
ingresses := client.GetIngresses()

View file

@ -1273,6 +1273,35 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
},
},
},
{
desc: "v18 Ingress with ingressClasses filter",
serverVersion: "v1.18",
ingressClass: "traefik-lb2",
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{},
HTTP: &dynamic.HTTPConfiguration{
Middlewares: map[string]*dynamic.Middleware{},
Routers: map[string]*dynamic.Router{
"testing-foo": {
Rule: "PathPrefix(`/foo`)",
Service: "testing-service1-80",
},
},
Services: map[string]*dynamic.Service{
"testing-service1-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{
PassHostHeader: Bool(true),
Servers: []dynamic.Server{
{
URL: "http://10.10.0.1:8080",
},
},
},
},
},
},
},
},
}
for _, test := range testCases {