Support 'networking.k8s.io/v1beta1' ingress apiVersion
This commit is contained in:
parent
6b7be462b8
commit
72e702a15a
47 changed files with 190 additions and 161 deletions
|
@ -40,7 +40,7 @@ Then any router can refer to an instance of the wanted middleware.
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="K8s Ingress"
|
```yaml tab="K8s Ingress"
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: traefik
|
name: traefik
|
||||||
|
|
|
@ -24,7 +24,7 @@ The Kubernetes Ingress Controller, The Custom Resource Way.
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: apps/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: traefik
|
name: traefik
|
||||||
labels:
|
labels:
|
||||||
|
@ -97,7 +97,7 @@ The Kubernetes Ingress Controller, The Custom Resource Way.
|
||||||
|
|
||||||
```yaml tab="Whoami"
|
```yaml tab="Whoami"
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: apps/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: whoami
|
name: whoami
|
||||||
namespace: default
|
namespace: default
|
||||||
|
|
|
@ -11,7 +11,7 @@ which in turn will create the resulting routers, services, handlers, etc.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: foo
|
name: foo
|
||||||
namespace: production
|
namespace: production
|
||||||
|
@ -40,7 +40,7 @@ spec:
|
||||||
|
|
||||||
```yaml tab="Ingress"
|
```yaml tab="Ingress"
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: foo
|
name: foo
|
||||||
namespace: production
|
namespace: production
|
||||||
|
@ -234,7 +234,7 @@ and will connect via TLS automatically.
|
||||||
|
|
||||||
```yaml tab="Ingress"
|
```yaml tab="Ingress"
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: foo
|
name: foo
|
||||||
namespace: production
|
namespace: production
|
||||||
|
@ -276,7 +276,7 @@ TLS certificates can be managed in Secrets objects.
|
||||||
Ingresses can be created that look like the following:
|
Ingresses can be created that look like the following:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: cheese
|
name: cheese
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: apps/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: whoami
|
name: whoami
|
||||||
namespace: default
|
namespace: default
|
||||||
|
@ -42,7 +42,7 @@ spec:
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: apps/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: whoamitcp
|
name: whoamitcp
|
||||||
namespace: default
|
namespace: default
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: test.ingress.https
|
name: test.ingress.https
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: test.ingress
|
name: test.ingress
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions"
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions"
|
||||||
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
|
||||||
kubeerror "k8s.io/apimachinery/pkg/api/errors"
|
kubeerror "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
@ -53,11 +52,9 @@ type Client interface {
|
||||||
GetTraefikServices() []*v1alpha1.TraefikService
|
GetTraefikServices() []*v1alpha1.TraefikService
|
||||||
GetTLSOptions() []*v1alpha1.TLSOption
|
GetTLSOptions() []*v1alpha1.TLSOption
|
||||||
|
|
||||||
GetIngresses() []*extensionsv1beta1.Ingress
|
|
||||||
GetService(namespace, name string) (*corev1.Service, bool, error)
|
GetService(namespace, name string) (*corev1.Service, bool, error)
|
||||||
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
||||||
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
|
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
|
||||||
UpdateIngressStatus(namespace, name, ip, hostname string) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add tests for the clientWrapper (and its methods) itself.
|
// TODO: add tests for the clientWrapper (and its methods) itself.
|
||||||
|
@ -272,7 +269,7 @@ func (c *clientWrapper) GetTraefikServices() []*v1alpha1.TraefikService {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTLSOptions
|
// GetTLSOptions returns all TLS options.
|
||||||
func (c *clientWrapper) GetTLSOptions() []*v1alpha1.TLSOption {
|
func (c *clientWrapper) GetTLSOptions() []*v1alpha1.TLSOption {
|
||||||
var result []*v1alpha1.TLSOption
|
var result []*v1alpha1.TLSOption
|
||||||
|
|
||||||
|
@ -287,48 +284,6 @@ func (c *clientWrapper) GetTLSOptions() []*v1alpha1.TLSOption {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIngresses returns all Ingresses for observed namespaces in the cluster.
|
|
||||||
func (c *clientWrapper) GetIngresses() []*extensionsv1beta1.Ingress {
|
|
||||||
var result []*extensionsv1beta1.Ingress
|
|
||||||
for ns, factory := range c.factoriesKube {
|
|
||||||
ings, err := factory.Extensions().V1beta1().Ingresses().Lister().List(c.labelSelector)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to list ingresses in namespace %s: %v", ns, err)
|
|
||||||
}
|
|
||||||
result = append(result, ings...)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateIngressStatus updates an Ingress with a provided status.
|
|
||||||
func (c *clientWrapper) UpdateIngressStatus(namespace, name, ip, hostname string) error {
|
|
||||||
if !c.isWatchedNamespace(namespace) {
|
|
||||||
return fmt.Errorf("failed to get ingress %s/%s: namespace is not within watched namespaces", namespace, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
ing, err := c.factoriesKube[c.lookupNamespace(namespace)].Extensions().V1beta1().Ingresses().Lister().Ingresses(namespace).Get(name)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to get ingress %s/%s: %v", namespace, name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ing.Status.LoadBalancer.Ingress) > 0 {
|
|
||||||
if ing.Status.LoadBalancer.Ingress[0].Hostname == hostname && ing.Status.LoadBalancer.Ingress[0].IP == ip {
|
|
||||||
// If status is already set, skip update
|
|
||||||
log.Debugf("Skipping status update on ingress %s/%s", ing.Namespace, ing.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ingCopy := ing.DeepCopy()
|
|
||||||
ingCopy.Status = extensionsv1beta1.IngressStatus{LoadBalancer: corev1.LoadBalancerStatus{Ingress: []corev1.LoadBalancerIngress{{IP: ip, Hostname: hostname}}}}
|
|
||||||
|
|
||||||
_, err = c.csKube.ExtensionsV1beta1().Ingresses(ingCopy.Namespace).UpdateStatus(ingCopy)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to update ingress status %s/%s: %v", namespace, name, err)
|
|
||||||
}
|
|
||||||
log.Infof("Updated status on ingress %s/%s", namespace, name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetService returns the named service from the given namespace.
|
// GetService returns the named service from the given namespace.
|
||||||
func (c *clientWrapper) GetService(namespace, name string) (*corev1.Service, bool, error) {
|
func (c *clientWrapper) GetService(namespace, name string) (*corev1.Service, bool, error) {
|
||||||
if !c.isWatchedNamespace(namespace) {
|
if !c.isWatchedNamespace(namespace) {
|
||||||
|
@ -379,11 +334,20 @@ func (c *clientWrapper) newResourceEventHandler(events chan<- interface{}) cache
|
||||||
return &cache.FilteringResourceEventHandler{
|
return &cache.FilteringResourceEventHandler{
|
||||||
FilterFunc: func(obj interface{}) bool {
|
FilterFunc: func(obj interface{}) bool {
|
||||||
// Ignore Ingresses that do not match our custom label selector.
|
// Ignore Ingresses that do not match our custom label selector.
|
||||||
if ing, ok := obj.(*extensionsv1beta1.Ingress); ok {
|
switch v := obj.(type) {
|
||||||
lbls := labels.Set(ing.GetLabels())
|
case *v1alpha1.IngressRoute:
|
||||||
return c.labelSelector.Matches(lbls)
|
return c.labelSelector.Matches(labels.Set(v.GetLabels()))
|
||||||
|
case *v1alpha1.IngressRouteTCP:
|
||||||
|
return c.labelSelector.Matches(labels.Set(v.GetLabels()))
|
||||||
|
case *v1alpha1.TraefikService:
|
||||||
|
return c.labelSelector.Matches(labels.Set(v.GetLabels()))
|
||||||
|
case *v1alpha1.TLSOption:
|
||||||
|
return c.labelSelector.Matches(labels.Set(v.GetLabels()))
|
||||||
|
case *v1alpha1.Middleware:
|
||||||
|
return c.labelSelector.Matches(labels.Set(v.GetLabels()))
|
||||||
|
default:
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
},
|
},
|
||||||
Handler: &resourceEventHandler{ev: events},
|
Handler: &resourceEventHandler{ev: events},
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,6 @@ import (
|
||||||
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
"github.com/containous/traefik/v2/pkg/provider/kubernetes/k8s"
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/k8s"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
|
||||||
v1beta12 "k8s.io/api/extensions/v1beta1"
|
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,15 +22,13 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type clientMock struct {
|
type clientMock struct {
|
||||||
ingresses []*extensionsv1beta1.Ingress
|
|
||||||
services []*corev1.Service
|
services []*corev1.Service
|
||||||
secrets []*corev1.Secret
|
secrets []*corev1.Secret
|
||||||
endpoints []*corev1.Endpoints
|
endpoints []*corev1.Endpoints
|
||||||
|
|
||||||
apiServiceError error
|
apiServiceError error
|
||||||
apiSecretError error
|
apiSecretError error
|
||||||
apiEndpointsError error
|
apiEndpointsError error
|
||||||
apiIngressStatusError error
|
|
||||||
|
|
||||||
ingressRoutes []*v1alpha1.IngressRoute
|
ingressRoutes []*v1alpha1.IngressRoute
|
||||||
ingressRouteTCPs []*v1alpha1.IngressRouteTCP
|
ingressRouteTCPs []*v1alpha1.IngressRouteTCP
|
||||||
|
@ -69,8 +65,6 @@ func newClientMock(paths ...string) clientMock {
|
||||||
c.traefikServices = append(c.traefikServices, o)
|
c.traefikServices = append(c.traefikServices, o)
|
||||||
case *v1alpha1.TLSOption:
|
case *v1alpha1.TLSOption:
|
||||||
c.tlsOptions = append(c.tlsOptions, o)
|
c.tlsOptions = append(c.tlsOptions, o)
|
||||||
case *v1beta12.Ingress:
|
|
||||||
c.ingresses = append(c.ingresses, o)
|
|
||||||
case *corev1.Secret:
|
case *corev1.Secret:
|
||||||
c.secrets = append(c.secrets, o)
|
c.secrets = append(c.secrets, o)
|
||||||
default:
|
default:
|
||||||
|
@ -122,10 +116,6 @@ func (c clientMock) GetTLSOption(namespace, name string) (*v1alpha1.TLSOption, b
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c clientMock) GetIngresses() []*extensionsv1beta1.Ingress {
|
|
||||||
return c.ingresses
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c clientMock) GetService(namespace, name string) (*corev1.Service, bool, error) {
|
func (c clientMock) GetService(namespace, name string) (*corev1.Service, bool, error) {
|
||||||
if c.apiServiceError != nil {
|
if c.apiServiceError != nil {
|
||||||
return nil, false, c.apiServiceError
|
return nil, false, c.apiServiceError
|
||||||
|
@ -169,7 +159,3 @@ func (c clientMock) GetSecret(namespace, name string) (*corev1.Secret, bool, err
|
||||||
func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) {
|
func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error) {
|
||||||
return c.watchChan, nil
|
return c.watchChan, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c clientMock) UpdateIngressStatus(namespace, name, ip, hostname string) error {
|
|
||||||
return c.apiIngressStatusError
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package ingress
|
package ingress
|
||||||
|
|
||||||
import (
|
import (
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
"k8s.io/api/networking/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildIngress(opts ...func(*extensionsv1beta1.Ingress)) *extensionsv1beta1.Ingress {
|
func buildIngress(opts ...func(*v1beta1.Ingress)) *v1beta1.Ingress {
|
||||||
i := &extensionsv1beta1.Ingress{}
|
i := &v1beta1.Ingress{}
|
||||||
i.Kind = "Ingress"
|
i.Kind = "Ingress"
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(i)
|
opt(i)
|
||||||
|
@ -13,15 +13,15 @@ func buildIngress(opts ...func(*extensionsv1beta1.Ingress)) *extensionsv1beta1.I
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func iNamespace(value string) func(*extensionsv1beta1.Ingress) {
|
func iNamespace(value string) func(*v1beta1.Ingress) {
|
||||||
return func(i *extensionsv1beta1.Ingress) {
|
return func(i *v1beta1.Ingress) {
|
||||||
i.Namespace = value
|
i.Namespace = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func iRules(opts ...func(*extensionsv1beta1.IngressSpec)) func(*extensionsv1beta1.Ingress) {
|
func iRules(opts ...func(*v1beta1.IngressSpec)) func(*v1beta1.Ingress) {
|
||||||
return func(i *extensionsv1beta1.Ingress) {
|
return func(i *v1beta1.Ingress) {
|
||||||
s := &extensionsv1beta1.IngressSpec{}
|
s := &v1beta1.IngressSpec{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(s)
|
opt(s)
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,9 @@ func iRules(opts ...func(*extensionsv1beta1.IngressSpec)) func(*extensionsv1beta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func iRule(opts ...func(*extensionsv1beta1.IngressRule)) func(*extensionsv1beta1.IngressSpec) {
|
func iRule(opts ...func(*v1beta1.IngressRule)) func(*v1beta1.IngressSpec) {
|
||||||
return func(spec *extensionsv1beta1.IngressSpec) {
|
return func(spec *v1beta1.IngressSpec) {
|
||||||
r := &extensionsv1beta1.IngressRule{}
|
r := &v1beta1.IngressRule{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(r)
|
opt(r)
|
||||||
}
|
}
|
||||||
|
@ -39,24 +39,24 @@ func iRule(opts ...func(*extensionsv1beta1.IngressRule)) func(*extensionsv1beta1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func iHost(name string) func(*extensionsv1beta1.IngressRule) {
|
func iHost(name string) func(*v1beta1.IngressRule) {
|
||||||
return func(rule *extensionsv1beta1.IngressRule) {
|
return func(rule *v1beta1.IngressRule) {
|
||||||
rule.Host = name
|
rule.Host = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func iTLSes(opts ...func(*extensionsv1beta1.IngressTLS)) func(*extensionsv1beta1.Ingress) {
|
func iTLSes(opts ...func(*v1beta1.IngressTLS)) func(*v1beta1.Ingress) {
|
||||||
return func(i *extensionsv1beta1.Ingress) {
|
return func(i *v1beta1.Ingress) {
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
iTLS := extensionsv1beta1.IngressTLS{}
|
iTLS := v1beta1.IngressTLS{}
|
||||||
opt(&iTLS)
|
opt(&iTLS)
|
||||||
i.Spec.TLS = append(i.Spec.TLS, iTLS)
|
i.Spec.TLS = append(i.Spec.TLS, iTLS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func iTLS(secret string, hosts ...string) func(*extensionsv1beta1.IngressTLS) {
|
func iTLS(secret string, hosts ...string) func(*v1beta1.IngressTLS) {
|
||||||
return func(i *extensionsv1beta1.IngressTLS) {
|
return func(i *v1beta1.IngressTLS) {
|
||||||
i.SecretName = secret
|
i.SecretName = secret
|
||||||
i.Hosts = hosts
|
i.Hosts = hosts
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/containous/traefik/v2/pkg/log"
|
"github.com/containous/traefik/v2/pkg/log"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
|
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||||
kubeerror "k8s.io/apimachinery/pkg/api/errors"
|
kubeerror "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
@ -42,11 +43,11 @@ func (reh *resourceEventHandler) OnDelete(obj interface{}) {
|
||||||
// The stores can then be accessed via the Get* functions.
|
// The stores can then be accessed via the Get* functions.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error)
|
WatchAll(namespaces []string, stopCh <-chan struct{}) (<-chan interface{}, error)
|
||||||
GetIngresses() []*extensionsv1beta1.Ingress
|
GetIngresses() []*networkingv1beta1.Ingress
|
||||||
GetService(namespace, name string) (*corev1.Service, bool, error)
|
GetService(namespace, name string) (*corev1.Service, bool, error)
|
||||||
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
GetSecret(namespace, name string) (*corev1.Secret, bool, error)
|
||||||
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
|
GetEndpoints(namespace, name string) (*corev1.Endpoints, bool, error)
|
||||||
UpdateIngressStatus(namespace, name, ip, hostname string) error
|
UpdateIngressStatus(ing *networkingv1beta1.Ingress, ip, hostname string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type clientWrapper struct {
|
type clientWrapper struct {
|
||||||
|
@ -165,27 +166,65 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (<
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIngresses returns all Ingresses for observed namespaces in the cluster.
|
// GetIngresses returns all Ingresses for observed namespaces in the cluster.
|
||||||
func (c *clientWrapper) GetIngresses() []*extensionsv1beta1.Ingress {
|
func (c *clientWrapper) GetIngresses() []*networkingv1beta1.Ingress {
|
||||||
var result []*extensionsv1beta1.Ingress
|
var results []*networkingv1beta1.Ingress
|
||||||
|
|
||||||
for ns, factory := range c.factories {
|
for ns, factory := range c.factories {
|
||||||
|
// extensions
|
||||||
ings, err := factory.Extensions().V1beta1().Ingresses().Lister().List(c.ingressLabelSelector)
|
ings, err := factory.Extensions().V1beta1().Ingresses().Lister().List(c.ingressLabelSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to list ingresses in namespace %s: %s", ns, err)
|
log.Errorf("Failed to list ingresses in namespace %s: %v", ns, err)
|
||||||
}
|
}
|
||||||
result = append(result, ings...)
|
|
||||||
|
for _, ing := range ings {
|
||||||
|
n, err := extensionsToNetworking(ing)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to convert ingress %s from extensions/v1beta1 to networking/v1beta1: %v", ns, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
results = append(results, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// networking
|
||||||
|
list, err := factory.Networking().V1beta1().Ingresses().Lister().List(c.ingressLabelSelector)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to list ingresses in namespace %s: %v", ns, err)
|
||||||
|
}
|
||||||
|
results = append(results, list...)
|
||||||
}
|
}
|
||||||
return result
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
func extensionsToNetworking(ing *extensionsv1beta1.Ingress) (*networkingv1beta1.Ingress, error) {
|
||||||
|
log.Warnf("Ingress %s/%s: the apiVersion 'extensions/v1beta1' is deprecated, use 'networking.k8s.io/v1beta1' instead.", ing.Namespace, ing.Name)
|
||||||
|
|
||||||
|
data, err := ing.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ni := &networkingv1beta1.Ingress{}
|
||||||
|
err = ni.Unmarshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ni, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateIngressStatus updates an Ingress with a provided status.
|
// UpdateIngressStatus updates an Ingress with a provided status.
|
||||||
func (c *clientWrapper) UpdateIngressStatus(namespace, name, ip, hostname string) error {
|
func (c *clientWrapper) UpdateIngressStatus(src *networkingv1beta1.Ingress, ip, hostname string) error {
|
||||||
if !c.isWatchedNamespace(namespace) {
|
if !c.isWatchedNamespace(src.Namespace) {
|
||||||
return fmt.Errorf("failed to get ingress %s/%s: namespace is not within watched namespaces", namespace, name)
|
return fmt.Errorf("failed to get ingress %s/%s: namespace is not within watched namespaces", src.Namespace, src.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
ing, err := c.factories[c.lookupNamespace(namespace)].Extensions().V1beta1().Ingresses().Lister().Ingresses(namespace).Get(name)
|
if src.GetObjectKind().GroupVersionKind().Group != "networking.k8s.io" {
|
||||||
|
return c.updateIngressStatusOld(src, ip, hostname)
|
||||||
|
}
|
||||||
|
|
||||||
|
ing, err := c.factories[c.lookupNamespace(src.Namespace)].Networking().V1beta1().Ingresses().Lister().Ingresses(src.Namespace).Get(src.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get ingress %s/%s: %v", namespace, name, err)
|
return fmt.Errorf("failed to get ingress %s/%s: %v", src.Namespace, src.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ing.Status.LoadBalancer.Ingress) > 0 {
|
if len(ing.Status.LoadBalancer.Ingress) > 0 {
|
||||||
|
@ -195,14 +234,42 @@ func (c *clientWrapper) UpdateIngressStatus(namespace, name, ip, hostname string
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ingCopy := ing.DeepCopy()
|
||||||
|
ingCopy.Status = networkingv1beta1.IngressStatus{LoadBalancer: corev1.LoadBalancerStatus{Ingress: []corev1.LoadBalancerIngress{{IP: ip, Hostname: hostname}}}}
|
||||||
|
|
||||||
|
_, err = c.clientset.NetworkingV1beta1().Ingresses(ingCopy.Namespace).UpdateStatus(ingCopy)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update ingress status %s/%s: %v", src.Namespace, src.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Updated status on ingress %s/%s", src.Namespace, src.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *clientWrapper) updateIngressStatusOld(src *networkingv1beta1.Ingress, ip, hostname string) error {
|
||||||
|
ing, err := c.factories[c.lookupNamespace(src.Namespace)].Extensions().V1beta1().Ingresses().Lister().Ingresses(src.Namespace).Get(src.Name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get ingress %s/%s: %v", src.Namespace, src.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ing.Status.LoadBalancer.Ingress) > 0 {
|
||||||
|
if ing.Status.LoadBalancer.Ingress[0].Hostname == hostname && ing.Status.LoadBalancer.Ingress[0].IP == ip {
|
||||||
|
// If status is already set, skip update
|
||||||
|
log.Debugf("Skipping status update on ingress %s/%s", ing.Namespace, ing.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ingCopy := ing.DeepCopy()
|
ingCopy := ing.DeepCopy()
|
||||||
ingCopy.Status = extensionsv1beta1.IngressStatus{LoadBalancer: corev1.LoadBalancerStatus{Ingress: []corev1.LoadBalancerIngress{{IP: ip, Hostname: hostname}}}}
|
ingCopy.Status = extensionsv1beta1.IngressStatus{LoadBalancer: corev1.LoadBalancerStatus{Ingress: []corev1.LoadBalancerIngress{{IP: ip, Hostname: hostname}}}}
|
||||||
|
|
||||||
_, err = c.clientset.ExtensionsV1beta1().Ingresses(ingCopy.Namespace).UpdateStatus(ingCopy)
|
_, err = c.clientset.ExtensionsV1beta1().Ingresses(ingCopy.Namespace).UpdateStatus(ingCopy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to update ingress status %s/%s: %v", namespace, name, err)
|
return fmt.Errorf("failed to update ingress status %s/%s: %v", src.Namespace, src.Name, err)
|
||||||
}
|
}
|
||||||
log.Infof("Updated status on ingress %s/%s", namespace, name)
|
|
||||||
|
log.Infof("Updated status on ingress %s/%s", src.Namespace, src.Name)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,11 +323,16 @@ func (c *clientWrapper) newResourceEventHandler(events chan<- interface{}) cache
|
||||||
return &cache.FilteringResourceEventHandler{
|
return &cache.FilteringResourceEventHandler{
|
||||||
FilterFunc: func(obj interface{}) bool {
|
FilterFunc: func(obj interface{}) bool {
|
||||||
// Ignore Ingresses that do not match our custom label selector.
|
// Ignore Ingresses that do not match our custom label selector.
|
||||||
if ing, ok := obj.(*extensionsv1beta1.Ingress); ok {
|
switch v := obj.(type) {
|
||||||
lbls := labels.Set(ing.GetLabels())
|
case *extensionsv1beta1.Ingress:
|
||||||
|
lbls := labels.Set(v.GetLabels())
|
||||||
return c.ingressLabelSelector.Matches(lbls)
|
return c.ingressLabelSelector.Matches(lbls)
|
||||||
|
case *networkingv1beta1.Ingress:
|
||||||
|
lbls := labels.Set(v.GetLabels())
|
||||||
|
return c.ingressLabelSelector.Matches(lbls)
|
||||||
|
default:
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
},
|
},
|
||||||
Handler: &resourceEventHandler{ev: events},
|
Handler: &resourceEventHandler{ev: events},
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,13 @@ import (
|
||||||
"github.com/containous/traefik/v2/pkg/provider/kubernetes/k8s"
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/k8s"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
v1beta12 "k8s.io/api/extensions/v1beta1"
|
"k8s.io/api/networking/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Client = (*clientMock)(nil)
|
var _ Client = (*clientMock)(nil)
|
||||||
|
|
||||||
type clientMock struct {
|
type clientMock struct {
|
||||||
ingresses []*extensionsv1beta1.Ingress
|
ingresses []*v1beta1.Ingress
|
||||||
services []*corev1.Service
|
services []*corev1.Service
|
||||||
secrets []*corev1.Secret
|
secrets []*corev1.Secret
|
||||||
endpoints []*corev1.Endpoints
|
endpoints []*corev1.Endpoints
|
||||||
|
@ -44,8 +44,14 @@ func newClientMock(paths ...string) clientMock {
|
||||||
c.secrets = append(c.secrets, o)
|
c.secrets = append(c.secrets, o)
|
||||||
case *corev1.Endpoints:
|
case *corev1.Endpoints:
|
||||||
c.endpoints = append(c.endpoints, o)
|
c.endpoints = append(c.endpoints, o)
|
||||||
case *v1beta12.Ingress:
|
case *v1beta1.Ingress:
|
||||||
c.ingresses = append(c.ingresses, o)
|
c.ingresses = append(c.ingresses, o)
|
||||||
|
case *extensionsv1beta1.Ingress:
|
||||||
|
ing, err := extensionsToNetworking(o)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
c.ingresses = append(c.ingresses, ing)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("Unknown runtime object %+v %T", o, o))
|
panic(fmt.Sprintf("Unknown runtime object %+v %T", o, o))
|
||||||
}
|
}
|
||||||
|
@ -55,7 +61,7 @@ func newClientMock(paths ...string) clientMock {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c clientMock) GetIngresses() []*extensionsv1beta1.Ingress {
|
func (c clientMock) GetIngresses() []*v1beta1.Ingress {
|
||||||
return c.ingresses
|
return c.ingresses
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +109,6 @@ func (c clientMock) WatchAll(namespaces []string, stopCh <-chan struct{}) (<-cha
|
||||||
return c.watchChan, nil
|
return c.watchChan, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c clientMock) UpdateIngressStatus(namespace, name, ip, hostname string) error {
|
func (c clientMock) UpdateIngressStatus(_ *v1beta1.Ingress, _, _ string) error {
|
||||||
return c.apiIngressStatusError
|
return c.apiIngressStatusError
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
@ -21,7 +21,7 @@ spec:
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: toto
|
namespace: toto
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
@ -11,7 +11,7 @@ spec:
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
@ -18,7 +18,7 @@ spec:
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
metadata:
|
metadata:
|
||||||
name: ""
|
name: ""
|
||||||
namespace: testing
|
namespace: testing
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"github.com/containous/traefik/v2/pkg/types"
|
"github.com/containous/traefik/v2/pkg/types"
|
||||||
"github.com/mitchellh/hashstructure"
|
"github.com/mitchellh/hashstructure"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/api/extensions/v1beta1"
|
"k8s.io/api/networking/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
@ -283,7 +283,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
||||||
return conf
|
return conf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) updateIngressStatus(i *v1beta1.Ingress, k8sClient Client) error {
|
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 {
|
if p.IngressEndpoint == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -294,13 +294,14 @@ func (p *Provider) updateIngressStatus(i *v1beta1.Ingress, k8sClient Client) err
|
||||||
return errors.New("publishedService or ip or hostname must be defined")
|
return errors.New("publishedService or ip or hostname must be defined")
|
||||||
}
|
}
|
||||||
|
|
||||||
return k8sClient.UpdateIngressStatus(i.Namespace, i.Name, p.IngressEndpoint.IP, p.IngressEndpoint.Hostname)
|
return k8sClient.UpdateIngressStatus(ing, p.IngressEndpoint.IP, p.IngressEndpoint.Hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceInfo := strings.Split(p.IngressEndpoint.PublishedService, "/")
|
serviceInfo := strings.Split(p.IngressEndpoint.PublishedService, "/")
|
||||||
if len(serviceInfo) != 2 {
|
if len(serviceInfo) != 2 {
|
||||||
return fmt.Errorf("invalid publishedService format (expected 'namespace/service' format): %s", p.IngressEndpoint.PublishedService)
|
return fmt.Errorf("invalid publishedService format (expected 'namespace/service' format): %s", p.IngressEndpoint.PublishedService)
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceNamespace, serviceName := serviceInfo[0], serviceInfo[1]
|
serviceNamespace, serviceName := serviceInfo[0], serviceInfo[1]
|
||||||
|
|
||||||
service, exists, err := k8sClient.GetService(serviceNamespace, serviceName)
|
service, exists, err := k8sClient.GetService(serviceNamespace, serviceName)
|
||||||
|
@ -310,7 +311,7 @@ func (p *Provider) updateIngressStatus(i *v1beta1.Ingress, k8sClient Client) err
|
||||||
|
|
||||||
if exists && service.Status.LoadBalancer.Ingress == nil {
|
if exists && service.Status.LoadBalancer.Ingress == nil {
|
||||||
// service exists, but has no Load Balancer status
|
// service exists, but has no Load Balancer status
|
||||||
log.Debugf("Skipping updating Ingress %s/%s due to service %s having no status set", i.Namespace, i.Name, p.IngressEndpoint.PublishedService)
|
log.Debugf("Skipping updating Ingress %s/%s due to service %s having no status set", ing.Namespace, ing.Name, p.IngressEndpoint.PublishedService)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +319,7 @@ func (p *Provider) updateIngressStatus(i *v1beta1.Ingress, k8sClient Client) err
|
||||||
return fmt.Errorf("missing service: %s", p.IngressEndpoint.PublishedService)
|
return fmt.Errorf("missing service: %s", p.IngressEndpoint.PublishedService)
|
||||||
}
|
}
|
||||||
|
|
||||||
return k8sClient.UpdateIngressStatus(i.Namespace, i.Name, service.Status.LoadBalancer.Ingress[0].IP, service.Status.LoadBalancer.Ingress[0].Hostname)
|
return k8sClient.UpdateIngressStatus(ing, service.Status.LoadBalancer.Ingress[0].IP, service.Status.LoadBalancer.Ingress[0].Hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldProcessIngress(ingressClass string, ingressClassAnnotation string) bool {
|
func shouldProcessIngress(ingressClass string, ingressClassAnnotation string) bool {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/containous/traefik/v2/pkg/types"
|
"github.com/containous/traefik/v2/pkg/types"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/api/extensions/v1beta1"
|
"k8s.io/api/networking/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue