Add new ingressClass support to ingress provider
* add new ingressClass * add doc * lint * adjust behavior to look for a class with a specific controller * remove looking strange test ingressclass * return nil rather than en empty object * change documentation * apply @kevinpollet suggestion * change order of processIngress to be correct and adjust tests * review: clean. * review: clean. * Fix for review Co-authored-by: Manuel Zapf <manuel@containo.us> Co-authored-by: Fernandez Ludovic <ludovic@containo.us> Co-authored-by: Michael <michael.matur@gmail.com>
This commit is contained in:
parent
1ef93fead7
commit
cb6ec507e2
13 changed files with 265 additions and 22 deletions
|
@ -21,14 +21,16 @@ import (
|
|||
"github.com/mitchellh/hashstructure"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/api/networking/v1beta1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
const (
|
||||
annotationKubernetesIngressClass = "kubernetes.io/ingress.class"
|
||||
traefikDefaultIngressClass = "traefik"
|
||||
defaultPathMatcher = "PathPrefix"
|
||||
annotationKubernetesIngressClass = "kubernetes.io/ingress.class"
|
||||
traefikDefaultIngressClass = "traefik"
|
||||
traefikDefaultIngressClassController = "traefik.io/ingress-controller"
|
||||
defaultPathMatcher = "PathPrefix"
|
||||
)
|
||||
|
||||
// Provider holds configurations of the provider.
|
||||
|
@ -181,13 +183,36 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
TCP: &dynamic.TCPConfiguration{},
|
||||
}
|
||||
|
||||
major, minor, err := client.GetServerVersion()
|
||||
if err != nil {
|
||||
log.FromContext(ctx).Errorf("Failed to get server version: %v", err)
|
||||
return conf
|
||||
}
|
||||
|
||||
var ingressClass *networkingv1beta1.IngressClass
|
||||
|
||||
if major >= 1 && minor >= 18 {
|
||||
ic, err := client.GetIngressClass()
|
||||
if err != nil {
|
||||
log.FromContext(ctx).Errorf("Failed to find an ingress class: %v", err)
|
||||
return conf
|
||||
}
|
||||
|
||||
if ic == nil {
|
||||
log.FromContext(ctx).Errorf("No ingress class for the traefik-controller in the cluster")
|
||||
return conf
|
||||
}
|
||||
|
||||
ingressClass = ic
|
||||
}
|
||||
|
||||
ingresses := client.GetIngresses()
|
||||
|
||||
certConfigs := make(map[string]*tls.CertAndStores)
|
||||
for _, ingress := range ingresses {
|
||||
ctx = log.With(ctx, log.Str("ingress", ingress.Name), log.Str("namespace", ingress.Namespace))
|
||||
|
||||
if !shouldProcessIngress(p.IngressClass, ingress.Annotations[annotationKubernetesIngressClass]) {
|
||||
if !p.shouldProcessIngress(p.IngressClass, ingress, ingressClass) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -273,7 +298,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
}
|
||||
|
||||
func (p *Provider) updateIngressStatus(ing *v1beta1.Ingress, k8sClient Client) error {
|
||||
// Only process if an EndpointIngress has been configured
|
||||
// Only process if an EndpointIngress has been configured.
|
||||
if p.IngressEndpoint == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -311,6 +336,12 @@ func (p *Provider) updateIngressStatus(ing *v1beta1.Ingress, k8sClient Client) e
|
|||
return k8sClient.UpdateIngressStatus(ing, service.Status.LoadBalancer.Ingress[0].IP, service.Status.LoadBalancer.Ingress[0].Hostname)
|
||||
}
|
||||
|
||||
func (p *Provider) shouldProcessIngress(providerIngressClass string, ingress *networkingv1beta1.Ingress, ingressClass *networkingv1beta1.IngressClass) bool {
|
||||
return ingressClass != nil && ingress.Spec.IngressClassName != nil && ingressClass.ObjectMeta.Name == *ingress.Spec.IngressClassName ||
|
||||
providerIngressClass == ingress.Annotations[annotationKubernetesIngressClass] ||
|
||||
len(providerIngressClass) == 0 && ingress.Annotations[annotationKubernetesIngressClass] == traefikDefaultIngressClass
|
||||
}
|
||||
|
||||
func buildHostRule(host string) string {
|
||||
if strings.HasPrefix(host, "*.") {
|
||||
return "HostRegexp(`" + strings.Replace(host, "*.", "{subdomain:[a-zA-Z0-9-]+}.", 1) + "`)"
|
||||
|
@ -319,11 +350,6 @@ func buildHostRule(host string) string {
|
|||
return "Host(`" + host + "`)"
|
||||
}
|
||||
|
||||
func shouldProcessIngress(ingressClass, ingressClassAnnotation string) bool {
|
||||
return ingressClass == ingressClassAnnotation ||
|
||||
(len(ingressClass) == 0 && ingressClassAnnotation == traefikDefaultIngressClass)
|
||||
}
|
||||
|
||||
func getCertificates(ctx context.Context, ingress *v1beta1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error {
|
||||
for _, t := range ingress.Spec.TLS {
|
||||
if t.SecretName == "" {
|
||||
|
@ -552,7 +578,8 @@ func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *s
|
|||
if throttleDuration == 0 {
|
||||
return nil
|
||||
}
|
||||
// Create a buffered channel to hold the pending event (if we're delaying processing the event due to throttling)
|
||||
|
||||
// Create a buffered channel to hold the pending event (if we're delaying processing the event due to throttling).
|
||||
eventsChanBuffered := make(chan interface{}, 1)
|
||||
|
||||
// Run a goroutine that reads events from eventChan and does a
|
||||
|
@ -571,7 +598,7 @@ func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *s
|
|||
// We already have an event in eventsChanBuffered, so we'll
|
||||
// do a refresh as soon as our throttle allows us to. It's fine
|
||||
// to drop the event and keep whatever's in the buffer -- we
|
||||
// don't do different things for different events
|
||||
// don't do different things for different events.
|
||||
log.FromContext(ctx).Debugf("Dropping event kind %T due to throttling", nextEvent)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue