Merge current v2.8 into master
This commit is contained in:
commit
626da4c0ae
90 changed files with 1019 additions and 707 deletions
|
@ -35,7 +35,6 @@ spec:
|
|||
- secret-ca1
|
||||
- secret-ca2
|
||||
clientAuthType: VerifyClientCertIfGiven
|
||||
preferServerCipherSuites: true
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
|
|
|
@ -35,7 +35,6 @@ spec:
|
|||
- secret-ca-default1
|
||||
- secret-ca-default2
|
||||
clientAuthType: VerifyClientCertIfGiven
|
||||
preferServerCipherSuites: true
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
|
|
|
@ -35,7 +35,6 @@ spec:
|
|||
- secret-ca1
|
||||
- secret-ca2
|
||||
clientAuthType: VerifyClientCertIfGiven
|
||||
preferServerCipherSuites: true
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
|
|
|
@ -35,7 +35,6 @@ spec:
|
|||
- secret-ca1
|
||||
- secret-ca2
|
||||
clientAuthType: VerifyClientCertIfGiven
|
||||
preferServerCipherSuites: true
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
|
|
|
@ -45,14 +45,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
|||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
|
|
|
@ -45,14 +45,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
|||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
|
|
|
@ -881,9 +881,8 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options
|
|||
CAFiles: clientCAs,
|
||||
ClientAuthType: tlsOption.Spec.ClientAuth.ClientAuthType,
|
||||
},
|
||||
SniStrict: tlsOption.Spec.SniStrict,
|
||||
PreferServerCipherSuites: tlsOption.Spec.PreferServerCipherSuites,
|
||||
ALPNProtocols: alpnProtocols,
|
||||
SniStrict: tlsOption.Spec.SniStrict,
|
||||
ALPNProtocols: alpnProtocols,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -666,8 +666,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
|
|||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
SniStrict: true,
|
||||
PreferServerCipherSuites: true,
|
||||
SniStrict: true,
|
||||
ALPNProtocols: []string{
|
||||
"h2",
|
||||
"http/1.1",
|
||||
|
@ -2748,8 +2747,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
SniStrict: true,
|
||||
PreferServerCipherSuites: true,
|
||||
SniStrict: true,
|
||||
ALPNProtocols: []string{
|
||||
"h2",
|
||||
"http/1.1",
|
||||
|
@ -2862,8 +2860,7 @@ func TestLoadIngressRoutes(t *testing.T) {
|
|||
},
|
||||
ClientAuthType: "VerifyClientCertIfGiven",
|
||||
},
|
||||
SniStrict: true,
|
||||
PreferServerCipherSuites: true,
|
||||
SniStrict: true,
|
||||
ALPNProtocols: []string{
|
||||
"h2",
|
||||
"http/1.1",
|
||||
|
|
|
@ -42,7 +42,8 @@ type TLSOptionSpec struct {
|
|||
// SniStrict defines whether Traefik allows connections from clients connections that do not specify a server_name extension.
|
||||
SniStrict bool `json:"sniStrict,omitempty"`
|
||||
// PreferServerCipherSuites defines whether the server chooses a cipher suite among his own instead of among the client's.
|
||||
// It is enabled automatically when minVersion or maxVersion are set.
|
||||
// It is enabled automatically when minVersion or maxVersion is set.
|
||||
// Deprecated: https://github.com/golang/go/issues/45430
|
||||
PreferServerCipherSuites bool `json:"preferServerCipherSuites,omitempty"`
|
||||
// ALPNProtocols defines the list of supported application level protocols for the TLS handshake, in order of preference.
|
||||
// More info: https://doc.traefik.io/traefik/v2.8/https/tls/#alpn-protocols
|
||||
|
|
|
@ -304,7 +304,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
serviceName := provider.Normalize(ingress.Namespace + "-" + pa.Backend.Service.Name + "-" + portString)
|
||||
conf.HTTP.Services[serviceName] = service
|
||||
|
||||
routerKey := strings.TrimPrefix(provider.Normalize(ingress.Name+"-"+ingress.Namespace+"-"+rule.Host+pa.Path), "-")
|
||||
routerKey := strings.TrimPrefix(provider.Normalize(ingress.Namespace+"-"+ingress.Name+"-"+rule.Host+pa.Path), "-")
|
||||
routers[routerKey] = append(routers[routerKey], loadRouter(rule, pa, rtConfig, serviceName))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1696,7 +1696,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
|
|||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"example-com-testing-bar": {
|
||||
"testing-example-com-bar": {
|
||||
Rule: "PathPrefix(`/bar`)",
|
||||
Service: "testing-service-bar-8080",
|
||||
},
|
||||
|
@ -1724,7 +1724,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
|
|||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"example-com-testing-foo": {
|
||||
"testing-example-com-foo": {
|
||||
Rule: "PathPrefix(`/foo`)",
|
||||
Service: "testing-service-foo-8080",
|
||||
},
|
||||
|
|
|
@ -67,7 +67,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
|
|||
logger := log.FromContext(ctx)
|
||||
|
||||
operation := func() error {
|
||||
if _, err := p.kvClient.Exists(path.Join(p.RootKey, "qmslkjdfmqlskdjfmqlksjazçueznbvbwzlkajzebvkwjdcqmlsfj"), nil); err != nil {
|
||||
if _, err := p.kvClient.Exists(ctx, path.Join(p.RootKey, "qmslkjdfmqlskdjfmqlksjazçueznbvbwzlkajzebvkwjdcqmlsfj"), nil); err != nil {
|
||||
return fmt.Errorf("KV store connection error: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -76,12 +76,12 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
|
|||
notify := func(err error, time time.Duration) {
|
||||
logger.Errorf("KV connection error: %+v, retrying in %s", err, time)
|
||||
}
|
||||
err := backoff.RetryNotify(safe.OperationWithRecover(operation), job.NewBackOff(backoff.NewExponentialBackOff()), notify)
|
||||
err := backoff.RetryNotify(safe.OperationWithRecover(operation), backoff.WithContext(job.NewBackOff(backoff.NewExponentialBackOff()), ctx), notify)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot connect to KV server: %w", err)
|
||||
}
|
||||
|
||||
configuration, err := p.buildConfiguration()
|
||||
configuration, err := p.buildConfiguration(ctx)
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot build the configuration: %v", err)
|
||||
} else {
|
||||
|
@ -105,7 +105,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
|
|||
|
||||
func (p *Provider) watchKv(ctx context.Context, configurationChan chan<- dynamic.Message) error {
|
||||
operation := func() error {
|
||||
events, err := p.kvClient.WatchTree(p.RootKey, ctx.Done(), nil)
|
||||
events, err := p.kvClient.WatchTree(ctx, p.RootKey, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to watch KV: %w", err)
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ func (p *Provider) watchKv(ctx context.Context, configurationChan chan<- dynamic
|
|||
return errors.New("the WatchTree channel is closed")
|
||||
}
|
||||
|
||||
configuration, errC := p.buildConfiguration()
|
||||
configuration, errC := p.buildConfiguration(ctx)
|
||||
if errC != nil {
|
||||
return errC
|
||||
}
|
||||
|
@ -146,8 +146,8 @@ func (p *Provider) watchKv(ctx context.Context, configurationChan chan<- dynamic
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) buildConfiguration() (*dynamic.Configuration, error) {
|
||||
pairs, err := p.kvClient.List(p.RootKey, nil)
|
||||
func (p *Provider) buildConfiguration(ctx context.Context) (*dynamic.Configuration, error) {
|
||||
pairs, err := p.kvClient.List(ctx, p.RootKey, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ func (p *Provider) createKVClient(ctx context.Context) (store.Store, error) {
|
|||
redis.Register()
|
||||
}
|
||||
|
||||
kvStore, err := valkeyrie.NewStore(p.storeType, p.Endpoints, storeConfig)
|
||||
kvStore, err := valkeyrie.NewStore(ctx, p.storeType, p.Endpoints, storeConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package kv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
|
@ -41,11 +42,11 @@ func newKvClientMock(kvPairs []*store.KVPair, err error) *Mock {
|
|||
return mock
|
||||
}
|
||||
|
||||
func (s *Mock) Put(key string, value []byte, opts *store.WriteOptions) error {
|
||||
func (s *Mock) Put(ctx context.Context, key string, value []byte, opts *store.WriteOptions) error {
|
||||
return errors.New("method Put not supported")
|
||||
}
|
||||
|
||||
func (s *Mock) Get(key string, options *store.ReadOptions) (*store.KVPair, error) {
|
||||
func (s *Mock) Get(ctx context.Context, key string, options *store.ReadOptions) (*store.KVPair, error) {
|
||||
if err := s.Error.Get; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -57,12 +58,12 @@ func (s *Mock) Get(key string, options *store.ReadOptions) (*store.KVPair, error
|
|||
return nil, store.ErrKeyNotFound
|
||||
}
|
||||
|
||||
func (s *Mock) Delete(key string) error {
|
||||
func (s *Mock) Delete(ctx context.Context, key string) error {
|
||||
return errors.New("method Delete not supported")
|
||||
}
|
||||
|
||||
// Exists mock.
|
||||
func (s *Mock) Exists(key string, options *store.ReadOptions) (bool, error) {
|
||||
func (s *Mock) Exists(ctx context.Context, key string, options *store.ReadOptions) (bool, error) {
|
||||
if err := s.Error.Get; err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -75,22 +76,22 @@ func (s *Mock) Exists(key string, options *store.ReadOptions) (bool, error) {
|
|||
}
|
||||
|
||||
// Watch mock.
|
||||
func (s *Mock) Watch(key string, stopCh <-chan struct{}, options *store.ReadOptions) (<-chan *store.KVPair, error) {
|
||||
func (s *Mock) Watch(ctx context.Context, key string, options *store.ReadOptions) (<-chan *store.KVPair, error) {
|
||||
return nil, errors.New("method Watch not supported")
|
||||
}
|
||||
|
||||
// WatchTree mock.
|
||||
func (s *Mock) WatchTree(prefix string, stopCh <-chan struct{}, options *store.ReadOptions) (<-chan []*store.KVPair, error) {
|
||||
func (s *Mock) WatchTree(ctx context.Context, prefix string, options *store.ReadOptions) (<-chan []*store.KVPair, error) {
|
||||
return s.WatchTreeMethod(), nil
|
||||
}
|
||||
|
||||
// NewLock mock.
|
||||
func (s *Mock) NewLock(key string, options *store.LockOptions) (store.Locker, error) {
|
||||
func (s *Mock) NewLock(ctx context.Context, key string, options *store.LockOptions) (store.Locker, error) {
|
||||
return nil, errors.New("method NewLock not supported")
|
||||
}
|
||||
|
||||
// List mock.
|
||||
func (s *Mock) List(prefix string, options *store.ReadOptions) ([]*store.KVPair, error) {
|
||||
func (s *Mock) List(ctx context.Context, prefix string, options *store.ReadOptions) ([]*store.KVPair, error) {
|
||||
if err := s.Error.List; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -104,19 +105,21 @@ func (s *Mock) List(prefix string, options *store.ReadOptions) ([]*store.KVPair,
|
|||
}
|
||||
|
||||
// DeleteTree mock.
|
||||
func (s *Mock) DeleteTree(prefix string) error {
|
||||
func (s *Mock) DeleteTree(ctx context.Context, prefix string) error {
|
||||
return errors.New("method DeleteTree not supported")
|
||||
}
|
||||
|
||||
// AtomicPut mock.
|
||||
func (s *Mock) AtomicPut(key string, value []byte, previous *store.KVPair, opts *store.WriteOptions) (bool, *store.KVPair, error) {
|
||||
func (s *Mock) AtomicPut(ctx context.Context, key string, value []byte, previous *store.KVPair, opts *store.WriteOptions) (bool, *store.KVPair, error) {
|
||||
return false, nil, errors.New("method AtomicPut not supported")
|
||||
}
|
||||
|
||||
// AtomicDelete mock.
|
||||
func (s *Mock) AtomicDelete(key string, previous *store.KVPair) (bool, error) {
|
||||
func (s *Mock) AtomicDelete(ctx context.Context, key string, previous *store.KVPair) (bool, error) {
|
||||
return false, errors.New("method AtomicDelete not supported")
|
||||
}
|
||||
|
||||
// Close mock.
|
||||
func (s *Mock) Close() {}
|
||||
func (s *Mock) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -283,7 +283,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"traefik/tls/certificates/1/stores/1": "foobar",
|
||||
}))
|
||||
|
||||
cfg, err := provider.buildConfiguration()
|
||||
cfg, err := provider.buildConfiguration(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := &dynamic.Configuration{
|
||||
|
@ -929,7 +929,7 @@ func Test_buildConfiguration_KV_error(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
cfg, err := provider.buildConfiguration()
|
||||
cfg, err := provider.buildConfiguration(context.Background())
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, cfg)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package kv
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/kvtools/valkeyrie/store"
|
||||
"github.com/traefik/traefik/v2/pkg/log"
|
||||
)
|
||||
|
@ -9,110 +11,110 @@ type storeWrapper struct {
|
|||
store.Store
|
||||
}
|
||||
|
||||
func (s *storeWrapper) Put(key string, value []byte, options *store.WriteOptions) error {
|
||||
func (s *storeWrapper) Put(ctx context.Context, key string, value []byte, options *store.WriteOptions) error {
|
||||
log.WithoutContext().Debugf("Put: %s", key, string(value))
|
||||
|
||||
if s.Store == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Store.Put(key, value, options)
|
||||
return s.Store.Put(ctx, key, value, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) Get(key string, options *store.ReadOptions) (*store.KVPair, error) {
|
||||
func (s *storeWrapper) Get(ctx context.Context, key string, options *store.ReadOptions) (*store.KVPair, error) {
|
||||
log.WithoutContext().Debugf("Get: %s", key)
|
||||
|
||||
if s.Store == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return s.Store.Get(key, options)
|
||||
return s.Store.Get(ctx, key, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) Delete(key string) error {
|
||||
func (s *storeWrapper) Delete(ctx context.Context, key string) error {
|
||||
log.WithoutContext().Debugf("Delete: %s", key)
|
||||
|
||||
if s.Store == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Store.Delete(key)
|
||||
return s.Store.Delete(ctx, key)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) Exists(key string, options *store.ReadOptions) (bool, error) {
|
||||
func (s *storeWrapper) Exists(ctx context.Context, key string, options *store.ReadOptions) (bool, error) {
|
||||
log.WithoutContext().Debugf("Exists: %s", key)
|
||||
|
||||
if s.Store == nil {
|
||||
return true, nil
|
||||
}
|
||||
return s.Store.Exists(key, options)
|
||||
return s.Store.Exists(ctx, key, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) Watch(key string, stopCh <-chan struct{}, options *store.ReadOptions) (<-chan *store.KVPair, error) {
|
||||
func (s *storeWrapper) Watch(ctx context.Context, key string, options *store.ReadOptions) (<-chan *store.KVPair, error) {
|
||||
log.WithoutContext().Debugf("Watch: %s", key)
|
||||
|
||||
if s.Store == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return s.Store.Watch(key, stopCh, options)
|
||||
return s.Store.Watch(ctx, key, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) WatchTree(directory string, stopCh <-chan struct{}, options *store.ReadOptions) (<-chan []*store.KVPair, error) {
|
||||
func (s *storeWrapper) WatchTree(ctx context.Context, directory string, options *store.ReadOptions) (<-chan []*store.KVPair, error) {
|
||||
log.WithoutContext().Debugf("WatchTree: %s", directory)
|
||||
|
||||
if s.Store == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return s.Store.WatchTree(directory, stopCh, options)
|
||||
return s.Store.WatchTree(ctx, directory, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) NewLock(key string, options *store.LockOptions) (store.Locker, error) {
|
||||
func (s *storeWrapper) NewLock(ctx context.Context, key string, options *store.LockOptions) (store.Locker, error) {
|
||||
log.WithoutContext().Debugf("NewLock: %s", key)
|
||||
|
||||
if s.Store == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return s.Store.NewLock(key, options)
|
||||
return s.Store.NewLock(ctx, key, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) List(directory string, options *store.ReadOptions) ([]*store.KVPair, error) {
|
||||
func (s *storeWrapper) List(ctx context.Context, directory string, options *store.ReadOptions) ([]*store.KVPair, error) {
|
||||
log.WithoutContext().Debugf("List: %s", directory)
|
||||
|
||||
if s.Store == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return s.Store.List(directory, options)
|
||||
return s.Store.List(ctx, directory, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) DeleteTree(directory string) error {
|
||||
func (s *storeWrapper) DeleteTree(ctx context.Context, directory string) error {
|
||||
log.WithoutContext().Debugf("DeleteTree: %s", directory)
|
||||
|
||||
if s.Store == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Store.DeleteTree(directory)
|
||||
return s.Store.DeleteTree(ctx, directory)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) AtomicPut(key string, value []byte, previous *store.KVPair, options *store.WriteOptions) (bool, *store.KVPair, error) {
|
||||
func (s *storeWrapper) AtomicPut(ctx context.Context, key string, value []byte, previous *store.KVPair, options *store.WriteOptions) (bool, *store.KVPair, error) {
|
||||
log.WithoutContext().Debugf("AtomicPut: %s", key, string(value), previous)
|
||||
|
||||
if s.Store == nil {
|
||||
return true, nil, nil
|
||||
}
|
||||
return s.Store.AtomicPut(key, value, previous, options)
|
||||
return s.Store.AtomicPut(ctx, key, value, previous, options)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) AtomicDelete(key string, previous *store.KVPair) (bool, error) {
|
||||
func (s *storeWrapper) AtomicDelete(ctx context.Context, key string, previous *store.KVPair) (bool, error) {
|
||||
log.WithoutContext().Debugf("AtomicDelete: %s", key, previous)
|
||||
|
||||
if s.Store == nil {
|
||||
return true, nil
|
||||
}
|
||||
return s.Store.AtomicDelete(key, previous)
|
||||
return s.Store.AtomicDelete(ctx, key, previous)
|
||||
}
|
||||
|
||||
func (s *storeWrapper) Close() {
|
||||
func (s *storeWrapper) Close() error {
|
||||
log.WithoutContext().Debugf("Close")
|
||||
|
||||
if s.Store == nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
s.Store.Close()
|
||||
return s.Store.Close()
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
|
|||
notify := func(err error, time time.Duration) {
|
||||
logger.Errorf("Provider connection error %+v, retrying in %s", err, time)
|
||||
}
|
||||
err := backoff.RetryNotify(safe.OperationWithRecover(operation), job.NewBackOff(backoff.NewExponentialBackOff()), notify)
|
||||
err := backoff.RetryNotify(safe.OperationWithRecover(operation), backoff.WithContext(job.NewBackOff(backoff.NewExponentialBackOff()), ctx), notify)
|
||||
if err != nil {
|
||||
logger.Errorf("Cannot connect to Provider server: %+v", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue