Filter ingress class resources by name
Co-authored-by: SantoDE <manuel.zapf@traefik.io>
This commit is contained in:
parent
438eec720a
commit
e658712d53
15 changed files with 364 additions and 6 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
70
integration/fixtures/k8s/08-ingressclass.yml
Normal file
70
integration/fixtures/k8s/08-ingressclass.yml
Normal 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
|
16
integration/fixtures/k8s_ingressclass.toml
Normal file
16
integration/fixtures/k8s_ingressclass.toml
Normal 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"
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
44
integration/testdata/rawdata-ingress.json
vendored
44
integration/testdata/rawdata-ingress.json
vendored
|
@ -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": [
|
||||
|
|
106
integration/testdata/rawdata-ingressclass.json
vendored
Normal file
106
integration/testdata/rawdata-ingressclass.json
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
kind: Endpoints
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 10.10.0.1
|
||||
ports:
|
||||
- port: 8080
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,10 @@
|
|||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIP: 10.0.0.1
|
|
@ -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,8 +198,12 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
log.FromContext(ctx).Warnf("Failed to list ingress classes: %v", err)
|
||||
}
|
||||
|
||||
if p.IngressClass != "" {
|
||||
ingressClasses = filterIngressClassByName(p.IngressClass, ics)
|
||||
} else {
|
||||
ingressClasses = ics
|
||||
}
|
||||
}
|
||||
|
||||
ingresses := client.GetIngresses()
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue