From 3e8141dc659eba644c8966bb09da02e8f335286e Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Wed, 22 Jul 2020 19:34:51 -0700 Subject: [PATCH] Update dynamiclistener Signed-off-by: Brad Davidson --- go.mod | 2 +- go.sum | 4 +- pkg/cluster/https.go | 5 +- .../rancher/dynamiclistener/factory/ca.go | 24 +- .../rancher/dynamiclistener/factory/gen.go | 57 ++++- .../github.com/rancher/dynamiclistener/go.mod | 1 + .../rancher/dynamiclistener/listener.go | 219 +++++++++++++++++- .../rancher/dynamiclistener/redirect.go | 4 +- .../dynamiclistener/storage/file/file.go | 1 - .../dynamiclistener/storage/kubernetes/ca.go | 59 +++++ .../storage/kubernetes/controller.go | 28 ++- vendor/modules.txt | 2 +- 12 files changed, 361 insertions(+), 45 deletions(-) create mode 100644 vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go diff --git a/go.mod b/go.mod index 8cd9cdd99a..fc66e6b5de 100644 --- a/go.mod +++ b/go.mod @@ -95,7 +95,7 @@ require ( github.com/opencontainers/runc v1.0.0-rc10 github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 github.com/pkg/errors v0.9.1 - github.com/rancher/dynamiclistener v0.2.0 + github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234 github.com/rancher/helm-controller v0.6.3 github.com/rancher/kine v0.4.0 github.com/rancher/remotedialer v0.2.0 diff --git a/go.sum b/go.sum index 6d1f9afe02..497d4bc971 100644 --- a/go.sum +++ b/go.sum @@ -620,8 +620,8 @@ github.com/rancher/cri v1.3.0-k3s.6 h1:jeom53pNYUJHlZBHpax8vpQeBoW19vSVGAQn9jPyI github.com/rancher/cri v1.3.0-k3s.6/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY= github.com/rancher/cri-tools v1.18.0-k3s1 h1:pLYthxpSu6k3Up9tNAMA0MK2ERqB6FC1sZQPRSW1qSg= github.com/rancher/cri-tools v1.18.0-k3s1/go.mod h1:Ij/GWNRcEDP6zVN6eQpvN/s0nhuJVtPQFy7RAdl+Wu8= -github.com/rancher/dynamiclistener v0.2.0 h1:KucYwJXVVGhZ/NndfMCeQoCafT/VN7kvqSGgmlX8Lxk= -github.com/rancher/dynamiclistener v0.2.0/go.mod h1:fs/dxyNcB3YT6W9fVz4bDGfhmSQS17QQup6BIcGF++s= +github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234 h1:wZ1Zh7fI7B9hfZw9Ouhz7171CZKu6XffM3ysUhhO6i0= +github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234/go.mod h1:9WusTANoiRr8cDWCTtf5txieulezHbpv4vhLADPp0zU= github.com/rancher/flannel v0.12.0-k3s1 h1:P23dWSk/9mGT1x2rDWW9JXNrF/0kjftiHwMau/+ZLGM= github.com/rancher/flannel v0.12.0-k3s1/go.mod h1:zQ/9Uhaw0yV4Wh6ljVwHVT1x5KuhenZA+6L8lRzOJEY= github.com/rancher/go-powershell v0.0.0-20200701182037-6845e6fcfa79 h1:UeC0rjrIel8hHz92cdVN09Cm4Hz+BhsPP/ZvQnPOr58= diff --git a/pkg/cluster/https.go b/pkg/cluster/https.go index 5dea465c27..cdda1f67da 100644 --- a/pkg/cluster/https.go +++ b/pkg/cluster/https.go @@ -33,12 +33,13 @@ func (c *Cluster) newListener(ctx context.Context) (net.Listener, http.Handler, return dynamiclistener.NewListener(tcp, storage, cert, key, dynamiclistener.Config{ CN: version.Program, Organization: []string{version.Program}, - TLSConfig: tls.Config{ + TLSConfig: &tls.Config{ ClientAuth: tls.RequestClientCert, MinVersion: c.config.TLSMinVersion, CipherSuites: c.config.TLSCipherSuites, }, - SANs: append(c.config.SANs, "localhost", "kubernetes", "kubernetes.default", "kubernetes.default.svc."+c.config.ClusterDomain), + SANs: append(c.config.SANs, "localhost", "kubernetes", "kubernetes.default", "kubernetes.default.svc."+c.config.ClusterDomain), + ExpirationDaysCheck: 90, }) } diff --git a/vendor/github.com/rancher/dynamiclistener/factory/ca.go b/vendor/github.com/rancher/dynamiclistener/factory/ca.go index cc3380f7af..5dfa863383 100644 --- a/vendor/github.com/rancher/dynamiclistener/factory/ca.go +++ b/vendor/github.com/rancher/dynamiclistener/factory/ca.go @@ -59,16 +59,7 @@ func loadCA() (*x509.Certificate, crypto.Signer, error) { return LoadCerts("./certs/ca.pem", "./certs/ca.key") } -func LoadCerts(certFile, keyFile string) (*x509.Certificate, crypto.Signer, error) { - caPem, err := ioutil.ReadFile(certFile) - if err != nil { - return nil, nil, err - } - caKey, err := ioutil.ReadFile(keyFile) - if err != nil { - return nil, nil, err - } - +func LoadCA(caPem, caKey []byte) (*x509.Certificate, crypto.Signer, error) { key, err := cert.ParsePrivateKeyPEM(caKey) if err != nil { return nil, nil, err @@ -85,3 +76,16 @@ func LoadCerts(certFile, keyFile string) (*x509.Certificate, crypto.Signer, erro return cert, signer, nil } + +func LoadCerts(certFile, keyFile string) (*x509.Certificate, crypto.Signer, error) { + caPem, err := ioutil.ReadFile(certFile) + if err != nil { + return nil, nil, err + } + caKey, err := ioutil.ReadFile(keyFile) + if err != nil { + return nil, nil, err + } + + return LoadCA(caPem, caKey) +} diff --git a/vendor/github.com/rancher/dynamiclistener/factory/gen.go b/vendor/github.com/rancher/dynamiclistener/factory/gen.go index cbe34fe307..ddd5b6df72 100644 --- a/vendor/github.com/rancher/dynamiclistener/factory/gen.go +++ b/vendor/github.com/rancher/dynamiclistener/factory/gen.go @@ -10,27 +10,37 @@ import ( "encoding/hex" "encoding/pem" "net" + "regexp" "sort" "strings" "github.com/rancher/dynamiclistener/cert" + "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" ) const ( cnPrefix = "listener.cattle.io/cn-" - static = "listener.cattle.io/static" + Static = "listener.cattle.io/static" hashKey = "listener.cattle.io/hash" ) +var ( + cnRegexp = regexp.MustCompile("^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$") +) + type TLS struct { CACert *x509.Certificate CAKey crypto.Signer CN string Organization []string + FilterCN func(...string) []string } func cns(secret *v1.Secret) (cns []string) { + if secret == nil { + return nil + } for k, v := range secret.Annotations { if strings.HasPrefix(k, cnPrefix) { cns = append(cns, v) @@ -61,8 +71,23 @@ func collectCNs(secret *v1.Secret) (domains []string, ips []net.IP, hash string, return } -func (t *TLS) Merge(secret, other *v1.Secret) (*v1.Secret, bool, error) { - return t.AddCN(secret, cns(other)...) +func (t *TLS) Merge(target, additional *v1.Secret) (*v1.Secret, bool, error) { + return t.AddCN(target, cns(additional)...) +} + +func (t *TLS) Refresh(secret *v1.Secret) (*v1.Secret, error) { + cns := cns(secret) + secret = secret.DeepCopy() + secret.Annotations = map[string]string{} + secret, _, err := t.AddCN(secret, cns...) + return secret, err +} + +func (t *TLS) Filter(cn ...string) []string { + if t.FilterCN == nil { + return cn + } + return t.FilterCN(cn...) } func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) { @@ -70,10 +95,17 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) { err error ) - if !NeedsUpdate(secret, cn...) { + cn = t.Filter(cn...) + + if !NeedsUpdate(0, secret, cn...) { return secret, false, nil } + secret = secret.DeepCopy() + if secret == nil { + secret = &v1.Secret{} + } + secret = populateCN(secret, cn...) privateKey, err := getPrivateKey(secret) @@ -116,18 +148,29 @@ func populateCN(secret *v1.Secret, cn ...string) *v1.Secret { secret.Annotations = map[string]string{} } for _, cn := range cn { - secret.Annotations[cnPrefix+cn] = cn + if cnRegexp.MatchString(cn) { + secret.Annotations[cnPrefix+cn] = cn + } else { + logrus.Errorf("dropping invalid CN: %s", cn) + } } return secret } -func NeedsUpdate(secret *v1.Secret, cn ...string) bool { - if secret.Annotations[static] == "true" { +func NeedsUpdate(maxSANs int, secret *v1.Secret, cn ...string) bool { + if secret == nil { + return true + } + + if secret.Annotations[Static] == "true" { return false } for _, cn := range cn { if secret.Annotations[cnPrefix+cn] == "" { + if maxSANs > 0 && len(cns(secret)) >= maxSANs { + return false + } return true } } diff --git a/vendor/github.com/rancher/dynamiclistener/go.mod b/vendor/github.com/rancher/dynamiclistener/go.mod index f08bac29eb..8eb297f0fa 100644 --- a/vendor/github.com/rancher/dynamiclistener/go.mod +++ b/vendor/github.com/rancher/dynamiclistener/go.mod @@ -6,6 +6,7 @@ require ( github.com/rancher/wrangler v0.1.4 github.com/rancher/wrangler-api v0.2.0 github.com/sirupsen/logrus v1.4.1 + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d ) diff --git a/vendor/github.com/rancher/dynamiclistener/listener.go b/vendor/github.com/rancher/dynamiclistener/listener.go index f3e84f3d2e..54b3fed7b3 100644 --- a/vendor/github.com/rancher/dynamiclistener/listener.go +++ b/vendor/github.com/rancher/dynamiclistener/listener.go @@ -1,6 +1,7 @@ package dynamiclistener import ( + "context" "crypto" "crypto/tls" "crypto/x509" @@ -8,6 +9,7 @@ import ( "net/http" "strings" "sync" + "time" "github.com/rancher/dynamiclistener/factory" "github.com/sirupsen/logrus" @@ -19,15 +21,15 @@ type TLSStorage interface { Update(secret *v1.Secret) error } -type SetFactory interface { - SetFactory(tls *factory.TLS) +type TLSFactory interface { + Refresh(secret *v1.Secret) (*v1.Secret, error) + AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) + Merge(target *v1.Secret, additional *v1.Secret) (*v1.Secret, bool, error) + Filter(cn ...string) []string } -type Config struct { - CN string - Organization []string - TLSConfig tls.Config - SANs []string +type SetFactory interface { + SetFactory(tls TLSFactory) } func NewListener(l net.Listener, storage TLSStorage, caCert *x509.Certificate, caKey crypto.Signer, config Config) (net.Listener, http.Handler, error) { @@ -37,6 +39,9 @@ func NewListener(l net.Listener, storage TLSStorage, caCert *x509.Certificate, c if len(config.Organization) == 0 { config.Organization = []string{"dynamic"} } + if config.TLSConfig == nil { + config.TLSConfig = &tls.Config{} + } dynamicListener := &listener{ factory: &factory.TLS{ @@ -44,34 +49,169 @@ func NewListener(l net.Listener, storage TLSStorage, caCert *x509.Certificate, c CAKey: caKey, CN: config.CN, Organization: config.Organization, + FilterCN: allowDefaultSANs(config.SANs, config.FilterCN), }, Listener: l, storage: &nonNil{storage: storage}, sans: config.SANs, + maxSANs: config.MaxSANs, tlsConfig: config.TLSConfig, } + if dynamicListener.tlsConfig == nil { + dynamicListener.tlsConfig = &tls.Config{} + } dynamicListener.tlsConfig.GetCertificate = dynamicListener.getCertificate + if config.CloseConnOnCertChange { + if len(dynamicListener.tlsConfig.Certificates) == 0 { + dynamicListener.tlsConfig.NextProtos = []string{"http/1.1"} + } + dynamicListener.conns = map[int]*closeWrapper{} + } + if setter, ok := storage.(SetFactory); ok { setter.SetFactory(dynamicListener.factory) } - return tls.NewListener(dynamicListener, &dynamicListener.tlsConfig), dynamicListener.cacheHandler(), nil + if config.ExpirationDaysCheck == 0 { + config.ExpirationDaysCheck = 30 + } + + tlsListener := tls.NewListener(dynamicListener.WrapExpiration(config.ExpirationDaysCheck), dynamicListener.tlsConfig) + return tlsListener, dynamicListener.cacheHandler(), nil +} + +func allowDefaultSANs(sans []string, next func(...string) []string) func(...string) []string { + if next == nil { + return nil + } else if len(sans) == 0 { + return next + } + + sanMap := map[string]bool{} + for _, san := range sans { + sanMap[san] = true + } + + return func(s ...string) []string { + var ( + good []string + unknown []string + ) + for _, s := range s { + if sanMap[s] { + good = append(good, s) + } else { + unknown = append(unknown, s) + } + } + + return append(good, next(unknown...)...) + } +} + +type cancelClose struct { + cancel func() + net.Listener +} + +func (c *cancelClose) Close() error { + c.cancel() + return c.Listener.Close() +} + +type Config struct { + CN string + Organization []string + TLSConfig *tls.Config + SANs []string + MaxSANs int + ExpirationDaysCheck int + CloseConnOnCertChange bool + FilterCN func(...string) []string } type listener struct { sync.RWMutex net.Listener - factory *factory.TLS + conns map[int]*closeWrapper + connID int + connLock sync.Mutex + + factory TLSFactory storage TLSStorage version string - tlsConfig tls.Config + tlsConfig *tls.Config cert *tls.Certificate sans []string + maxSANs int init sync.Once } +func (l *listener) WrapExpiration(days int) net.Listener { + ctx, cancel := context.WithCancel(context.Background()) + go func() { + time.Sleep(5 * time.Minute) + + for { + wait := 6 * time.Hour + if err := l.checkExpiration(days); err != nil { + logrus.Errorf("failed to check and refresh dynamic cert: %v", err) + wait = 5 + time.Minute + } + select { + case <-ctx.Done(): + return + case <-time.After(wait): + } + } + }() + + return &cancelClose{ + cancel: cancel, + Listener: l, + } +} + +func (l *listener) checkExpiration(days int) error { + l.Lock() + defer l.Unlock() + + if days == 0 { + return nil + } + + if l.cert == nil { + return nil + } + + secret, err := l.storage.Get() + if err != nil { + return err + } + + cert, err := tls.X509KeyPair(secret.Data[v1.TLSCertKey], secret.Data[v1.TLSPrivateKeyKey]) + if err != nil { + return err + } + + certParsed, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + return err + } + + if time.Now().UTC().Add(time.Hour * 24 * time.Duration(days)).After(certParsed.NotAfter) { + secret, err := l.factory.Refresh(secret) + if err != nil { + return err + } + return l.storage.Update(secret) + } + + return nil +} + func (l *listener) Accept() (net.Conn, error) { l.init.Do(func() { if len(l.sans) > 0 { @@ -97,13 +237,49 @@ func (l *listener) Accept() (net.Conn, error) { if !strings.Contains(host, ":") { if err := l.updateCert(host); err != nil { - logrus.Infof("failed to create TLS cert for: %s", host) + logrus.Infof("failed to create TLS cert for: %s, %v", host, err) } } + if l.conns != nil { + conn = l.wrap(conn) + } + return conn, nil } +func (l *listener) wrap(conn net.Conn) net.Conn { + l.connLock.Lock() + defer l.connLock.Unlock() + l.connID++ + + wrapper := &closeWrapper{ + Conn: conn, + id: l.connID, + l: l, + } + l.conns[l.connID] = wrapper + + return wrapper +} + +type closeWrapper struct { + net.Conn + id int + l *listener +} + +func (c *closeWrapper) close() error { + delete(c.l.conns, c.id) + return c.Conn.Close() +} + +func (c *closeWrapper) Close() error { + c.l.connLock.Lock() + defer c.l.connLock.Unlock() + return c.close() +} + func (l *listener) getCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { if hello.ServerName != "" { if err := l.updateCert(hello.ServerName); err != nil { @@ -115,6 +291,11 @@ func (l *listener) getCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, } func (l *listener) updateCert(cn ...string) error { + cn = l.factory.Filter(cn...) + if len(cn) == 0 { + return nil + } + l.RLock() defer l.RUnlock() @@ -123,7 +304,7 @@ func (l *listener) updateCert(cn ...string) error { return err } - if !factory.NeedsUpdate(secret, cn...) { + if !factory.NeedsUpdate(l.maxSANs, secret, cn...) { return nil } @@ -143,6 +324,13 @@ func (l *listener) updateCert(cn ...string) error { } // clear version to force cert reload l.version = "" + if l.conns != nil { + l.connLock.Lock() + for _, conn := range l.conns { + _ = conn.close() + } + l.connLock.Unlock() + } } return nil @@ -179,6 +367,7 @@ func (l *listener) loadCert() (*tls.Certificate, error) { } l.cert = &cert + l.version = secret.ResourceVersion return l.cert, nil } @@ -191,6 +380,12 @@ func (l *listener) cacheHandler() http.Handler { ip := net.ParseIP(h) if len(ip) > 0 { + for _, v := range req.Header["User-Agent"] { + if strings.Contains(strings.ToLower(v), "mozilla") { + return + } + } + l.updateCert(h) } }) diff --git a/vendor/github.com/rancher/dynamiclistener/redirect.go b/vendor/github.com/rancher/dynamiclistener/redirect.go index 3987172ff9..76ff14424b 100644 --- a/vendor/github.com/rancher/dynamiclistener/redirect.go +++ b/vendor/github.com/rancher/dynamiclistener/redirect.go @@ -11,8 +11,10 @@ import ( func HTTPRedirect(next http.Handler) http.Handler { return http.HandlerFunc( func(rw http.ResponseWriter, r *http.Request) { - if r.Header.Get("x-Forwarded-Proto") == "https" || + if r.TLS != nil || + r.Header.Get("x-Forwarded-Proto") == "https" || r.Header.Get("x-Forwarded-Proto") == "wss" || + strings.HasPrefix(r.URL.Path, "/.well-known/") || strings.HasPrefix(r.URL.Path, "/ping") || strings.HasPrefix(r.URL.Path, "/health") { next.ServeHTTP(rw, r) diff --git a/vendor/github.com/rancher/dynamiclistener/storage/file/file.go b/vendor/github.com/rancher/dynamiclistener/storage/file/file.go index ba738bcdbe..06729446b2 100644 --- a/vendor/github.com/rancher/dynamiclistener/storage/file/file.go +++ b/vendor/github.com/rancher/dynamiclistener/storage/file/file.go @@ -39,4 +39,3 @@ func (s *storage) Update(secret *v1.Secret) error { return json.NewEncoder(f).Encode(secret) } - diff --git a/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go new file mode 100644 index 0000000000..388936440c --- /dev/null +++ b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go @@ -0,0 +1,59 @@ +package kubernetes + +import ( + "crypto" + "crypto/x509" + + "github.com/rancher/dynamiclistener/factory" + v1controller "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func LoadOrGenCA(secrets v1controller.SecretClient, namespace, name string) (*x509.Certificate, crypto.Signer, error) { + secret, err := getSecret(secrets, namespace, name) + if err != nil { + return nil, nil, err + } + return factory.LoadCA(secret.Data[v1.TLSCertKey], secret.Data[v1.TLSPrivateKeyKey]) +} + +func getSecret(secrets v1controller.SecretClient, namespace, name string) (*v1.Secret, error) { + s, err := secrets.Get(namespace, name, metav1.GetOptions{}) + if !errors.IsNotFound(err) { + return s, err + } + + if err := createAndStore(secrets, namespace, name); err != nil { + return nil, err + } + return secrets.Get(namespace, name, metav1.GetOptions{}) +} + +func createAndStore(secrets v1controller.SecretClient, namespace string, name string) error { + ca, cert, err := factory.GenCA() + if err != nil { + return err + } + + certPem, keyPem, err := factory.Marshal(ca, cert) + if err != nil { + return err + } + + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: map[string][]byte{ + v1.TLSCertKey: certPem, + v1.TLSPrivateKeyKey: keyPem, + }, + Type: v1.SecretTypeTLS, + } + + secrets.Create(secret) + return nil +} diff --git a/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go index 0c91e7579b..683ab9c502 100644 --- a/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go +++ b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go @@ -6,19 +6,28 @@ import ( "time" "github.com/rancher/dynamiclistener" - "github.com/rancher/dynamiclistener/factory" "github.com/rancher/wrangler-api/pkg/generated/controllers/core" v1controller "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1" "github.com/rancher/wrangler/pkg/start" "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type CoreGetter func() *core.Factory +func Load(ctx context.Context, secrets v1controller.SecretController, namespace, name string, backing dynamiclistener.TLSStorage) dynamiclistener.TLSStorage { + storage := &storage{ + name: name, + namespace: namespace, + storage: backing, + ctx: ctx, + } + storage.init(secrets) + return storage +} + func New(ctx context.Context, core CoreGetter, namespace, name string, backing dynamiclistener.TLSStorage) dynamiclistener.TLSStorage { storage := &storage{ name: name, @@ -55,10 +64,10 @@ type storage struct { storage dynamiclistener.TLSStorage secrets v1controller.SecretClient ctx context.Context - tls *factory.TLS + tls dynamiclistener.TLSFactory } -func (s *storage) SetFactory(tls *factory.TLS) { +func (s *storage) SetFactory(tls dynamiclistener.TLSFactory) { s.tls = tls } @@ -122,7 +131,7 @@ func (s *storage) saveInK8s(secret *v1.Secret) (*v1.Secret, error) { } if existing, err := s.storage.Get(); err == nil && s.tls != nil { - if newSecret, updated, err := s.tls.Merge(secret, existing); err == nil && updated { + if newSecret, updated, err := s.tls.Merge(existing, secret); err == nil && updated { secret = newSecret } } @@ -132,9 +141,12 @@ func (s *storage) saveInK8s(secret *v1.Secret) (*v1.Secret, error) { return nil, err } - if equality.Semantic.DeepEqual(targetSecret.Annotations, secret.Annotations) && - equality.Semantic.DeepEqual(targetSecret.Data, secret.Data) { - return secret, nil + if newSecret, updated, err := s.tls.Merge(targetSecret, secret); err != nil { + return nil, err + } else if !updated { + return newSecret, nil + } else { + secret = newSecret } targetSecret.Annotations = secret.Annotations diff --git a/vendor/modules.txt b/vendor/modules.txt index f1ac7ca9b7..d37760e076 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -717,7 +717,7 @@ github.com/prometheus/procfs/xfs # github.com/rakelkar/gonetsh v0.0.0-20190930180311-e5c5ffe4bdf0 github.com/rakelkar/gonetsh/netroute github.com/rakelkar/gonetsh/netsh -# github.com/rancher/dynamiclistener v0.2.0 +# github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234 github.com/rancher/dynamiclistener github.com/rancher/dynamiclistener/cert github.com/rancher/dynamiclistener/factory