diff --git a/go.mod b/go.mod index 7d5219b5fa..a0f0f2c29f 100644 --- a/go.mod +++ b/go.mod @@ -94,7 +94,7 @@ require ( github.com/opencontainers/runc v1.0.0-rc10 github.com/opencontainers/selinux v1.5.3-0.20200613095409-bb88c45a3863 github.com/pkg/errors v0.9.1 - github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234 + github.com/rancher/dynamiclistener v0.2.1 github.com/rancher/helm-controller v0.6.5 github.com/rancher/kine v0.4.0 github.com/rancher/remotedialer v0.2.0 diff --git a/go.sum b/go.sum index 3d1a29e04f..d487db79b0 100644 --- a/go.sum +++ b/go.sum @@ -632,8 +632,8 @@ github.com/rancher/cri v1.3.0-k3s.7 h1:5V/AVFLCpYIsJMavJKjKpwrQU92e87dhWSX43N4q8 github.com/rancher/cri v1.3.0-k3s.7/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.1-0.20200418023342-52ede5ec9234 h1:wZ1Zh7fI7B9hfZw9Ouhz7171CZKu6XffM3ysUhhO6i0= -github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234/go.mod h1:9WusTANoiRr8cDWCTtf5txieulezHbpv4vhLADPp0zU= +github.com/rancher/dynamiclistener v0.2.1 h1:QiY1jxs2TOLrKB04G36vE2ehEvPMPGiWp8zEHLKB1nE= +github.com/rancher/dynamiclistener v0.2.1/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 cdda1f67da..da1161a1f5 100644 --- a/pkg/cluster/https.go +++ b/pkg/cluster/https.go @@ -39,7 +39,7 @@ func (c *Cluster) newListener(ctx context.Context) (net.Listener, http.Handler, CipherSuites: c.config.TLSCipherSuites, }, SANs: append(c.config.SANs, "localhost", "kubernetes", "kubernetes.default", "kubernetes.default.svc."+c.config.ClusterDomain), - ExpirationDaysCheck: 90, + ExpirationDaysCheck: config.CertificateRenewDays, }) } diff --git a/pkg/daemons/config/types.go b/pkg/daemons/config/types.go index e0349a9da4..1093bbf2f4 100644 --- a/pkg/daemons/config/types.go +++ b/pkg/daemons/config/types.go @@ -20,6 +20,7 @@ const ( FlannelBackendHostGW = "host-gw" FlannelBackendIPSEC = "ipsec" FlannelBackendWireguard = "wireguard" + CertificateRenewDays = 90 ) type Node struct { diff --git a/pkg/daemons/control/server.go b/pkg/daemons/control/server.go index aed73fb605..20d2fabf6f 100644 --- a/pkg/daemons/control/server.go +++ b/pkg/daemons/control/server.go @@ -898,7 +898,7 @@ func expired(certFile string, pool *x509.CertPool) bool { if err != nil { return true } - return certutil.IsCertExpired(certificates[0]) + return certutil.IsCertExpired(certificates[0], config.CertificateRenewDays) } func cloudControllerManager(ctx context.Context, cfg *config.Control, runtime *config.ControlRuntime) { diff --git a/vendor/github.com/rancher/dynamiclistener/cert/cert.go b/vendor/github.com/rancher/dynamiclistener/cert/cert.go index bdf4834850..c82e2d5d5b 100644 --- a/vendor/github.com/rancher/dynamiclistener/cert/cert.go +++ b/vendor/github.com/rancher/dynamiclistener/cert/cert.go @@ -33,7 +33,7 @@ import ( "math" "math/big" "net" - "path" + "path/filepath" "strings" "time" @@ -45,6 +45,10 @@ const ( duration365d = time.Hour * 24 * 365 ) +var ( + ErrStaticCert = errors.New("cannot renew static certificate") +) + // Config contains the basic fields required for creating a certificate type Config struct { CommonName string @@ -119,7 +123,13 @@ func NewSignedCert(cfg Config, key crypto.Signer, caCert *x509.Certificate, caKe if err != nil { return nil, err } - return x509.ParseCertificate(certDERBytes) + + parsedCert, err := x509.ParseCertificate(certDERBytes) + if err == nil { + logrus.Infof("certificate %s signed by %s: notBefore=%s notAfter=%s", + parsedCert.Subject, caCert.Subject, parsedCert.NotBefore, parsedCert.NotAfter) + } + return parsedCert, err } // MakeEllipticPrivateKeyPEM creates an ECDSA private key @@ -161,8 +171,8 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a maxAge := time.Hour * 24 * 365 // one year self-signed certs baseName := fmt.Sprintf("%s_%s_%s", host, strings.Join(ipsToStrings(alternateIPs), "-"), strings.Join(alternateDNS, "-")) - certFixturePath := path.Join(fixtureDirectory, baseName+".crt") - keyFixturePath := path.Join(fixtureDirectory, baseName+".key") + certFixturePath := filepath.Join(fixtureDirectory, baseName+".crt") + keyFixturePath := filepath.Join(fixtureDirectory, baseName+".key") if len(fixtureDirectory) > 0 { cert, err := ioutil.ReadFile(certFixturePath) if err == nil { @@ -271,11 +281,11 @@ func ipsToStrings(ips []net.IP) []string { } // IsCertExpired checks if the certificate about to expire -func IsCertExpired(cert *x509.Certificate) bool { +func IsCertExpired(cert *x509.Certificate, days int) bool { expirationDate := cert.NotAfter - diffDays := expirationDate.Sub(time.Now()).Hours() / 24.0 - if diffDays <= 90 { - logrus.Infof("certificate will expire in %f days", diffDays) + diffDays := time.Until(expirationDate).Hours() / 24.0 + if diffDays <= float64(days) { + logrus.Infof("certificate %s will expire in %f days at %s", cert.Subject, diffDays, cert.NotAfter) return true } return false diff --git a/vendor/github.com/rancher/dynamiclistener/cert/io.go b/vendor/github.com/rancher/dynamiclistener/cert/io.go index 53195668ab..984307fb02 100644 --- a/vendor/github.com/rancher/dynamiclistener/cert/io.go +++ b/vendor/github.com/rancher/dynamiclistener/cert/io.go @@ -34,15 +34,15 @@ func CanReadCertAndKey(certPath, keyPath string) (bool, error) { certReadable := canReadFile(certPath) keyReadable := canReadFile(keyPath) - if certReadable == false && keyReadable == false { + if !certReadable && !keyReadable { return false, nil } - if certReadable == false { + if !certReadable { return false, fmt.Errorf("error reading %s, certificate and key must be supplied as a pair", certPath) } - if keyReadable == false { + if !keyReadable { return false, fmt.Errorf("error reading %s, certificate and key must be supplied as a pair", keyPath) } diff --git a/vendor/github.com/rancher/dynamiclistener/factory/cert_utils.go b/vendor/github.com/rancher/dynamiclistener/factory/cert_utils.go index cb626787d6..95405e6807 100644 --- a/vendor/github.com/rancher/dynamiclistener/factory/cert_utils.go +++ b/vendor/github.com/rancher/dynamiclistener/factory/cert_utils.go @@ -11,6 +11,8 @@ import ( "math/big" "net" "time" + + "github.com/sirupsen/logrus" ) const ( @@ -40,6 +42,31 @@ func NewSelfSignedCACert(key crypto.Signer, cn string, org ...string) (*x509.Cer return x509.ParseCertificate(certDERBytes) } +func NewSignedClientCert(signer crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer, cn string) (*x509.Certificate, error) { + serialNumber, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) + if err != nil { + return nil, err + } + + parent := x509.Certificate{ + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + NotAfter: time.Now().Add(time.Hour * 24 * 365).UTC(), + NotBefore: caCert.NotBefore, + SerialNumber: serialNumber, + Subject: pkix.Name{ + CommonName: cn, + }, + } + + cert, err := x509.CreateCertificate(rand.Reader, &parent, caCert, signer.Public(), caKey) + if err != nil { + return nil, err + } + + return x509.ParseCertificate(cert) +} + func NewSignedCert(signer crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer, cn string, orgs []string, domains []string, ips []net.IP) (*x509.Certificate, error) { @@ -67,7 +94,12 @@ func NewSignedCert(signer crypto.Signer, caCert *x509.Certificate, caKey crypto. return nil, err } - return x509.ParseCertificate(cert) + parsedCert, err := x509.ParseCertificate(cert) + if err == nil { + logrus.Infof("certificate %s signed by %s: notBefore=%s notAfter=%s", + parsedCert.Subject, caCert.Subject, parsedCert.NotBefore, parsedCert.NotAfter) + } + return parsedCert, err } func ParseCertPEM(pemCerts []byte) (*x509.Certificate, error) { diff --git a/vendor/github.com/rancher/dynamiclistener/factory/gen.go b/vendor/github.com/rancher/dynamiclistener/factory/gen.go index ddd5b6df72..ff15a932ac 100644 --- a/vendor/github.com/rancher/dynamiclistener/factory/gen.go +++ b/vendor/github.com/rancher/dynamiclistener/factory/gen.go @@ -5,10 +5,10 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" - "crypto/sha256" + "crypto/sha1" "crypto/x509" - "encoding/hex" "encoding/pem" + "fmt" "net" "regexp" "sort" @@ -20,9 +20,9 @@ import ( ) const ( - cnPrefix = "listener.cattle.io/cn-" - Static = "listener.cattle.io/static" - hashKey = "listener.cattle.io/hash" + cnPrefix = "listener.cattle.io/cn-" + Static = "listener.cattle.io/static" + fingerprint = "listener.cattle.io/fingerprint" ) var ( @@ -49,16 +49,14 @@ func cns(secret *v1.Secret) (cns []string) { return } -func collectCNs(secret *v1.Secret) (domains []string, ips []net.IP, hash string, err error) { +func collectCNs(secret *v1.Secret) (domains []string, ips []net.IP, err error) { var ( - cns = cns(secret) - digest = sha256.New() + cns = cns(secret) ) sort.Strings(cns) for _, v := range cns { - digest.Write([]byte(v)) ip := net.ParseIP(v) if ip == nil { domains = append(domains, v) @@ -67,40 +65,61 @@ func collectCNs(secret *v1.Secret) (domains []string, ips []net.IP, hash string, } } - hash = hex.EncodeToString(digest.Sum(nil)) return } +// Merge combines the SAN lists from the target and additional Secrets, and returns a potentially modified Secret, +// along with a bool indicating if the returned Secret has been updated or not. If the two SAN lists alread matched +// and no merging was necessary, but the Secrets' certificate fingerprints differed, the second secret is returned +// and the updated bool is set to true despite neither certificate having actually been modified. This is required +// to support handling certificate renewal within the kubernetes storage provider. func (t *TLS) Merge(target, additional *v1.Secret) (*v1.Secret, bool, error) { - return t.AddCN(target, cns(additional)...) + secret, updated, err := t.AddCN(target, cns(additional)...) + if !updated { + if target.Annotations[fingerprint] != additional.Annotations[fingerprint] { + secret = additional + updated = true + } + } + return secret, updated, err } -func (t *TLS) Refresh(secret *v1.Secret) (*v1.Secret, error) { +// Renew returns a copy of the given certificate that has been re-signed +// to extend the NotAfter date. It is an error to attempt to renew +// a static (user-provided) certificate. +func (t *TLS) Renew(secret *v1.Secret) (*v1.Secret, error) { + if IsStatic(secret) { + return secret, cert.ErrStaticCert + } cns := cns(secret) secret = secret.DeepCopy() secret.Annotations = map[string]string{} - secret, _, err := t.AddCN(secret, cns...) + secret, _, err := t.generateCert(secret, cns...) return secret, err } +// Filter ensures that the CNs are all valid accorting to both internal logic, and any filter callbacks. +// The returned list will contain only approved CN entries. func (t *TLS) Filter(cn ...string) []string { - if t.FilterCN == nil { + if len(cn) == 0 || t.FilterCN == nil { return cn } return t.FilterCN(cn...) } +// AddCN attempts to add a list of CN strings to a given Secret, returning the potentially-modified +// Secret along with a bool indicating whether or not it has been updated. The Secret will not be changed +// if it has an attribute indicating that it is static (aka user-provided), or if no new CNs were added. func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) { - var ( - err error - ) - cn = t.Filter(cn...) - if !NeedsUpdate(0, secret, cn...) { + if IsStatic(secret) || !NeedsUpdate(0, secret, cn...) { return secret, false, nil } + return t.generateCert(secret, cn...) +} +func (t *TLS) generateCert(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) { secret = secret.DeepCopy() if secret == nil { secret = &v1.Secret{} @@ -113,7 +132,7 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) { return nil, false, err } - domains, ips, hash, err := collectCNs(secret) + domains, ips, err := collectCNs(secret) if err != nil { return nil, false, err } @@ -133,7 +152,7 @@ func (t *TLS) AddCN(secret *v1.Secret, cn ...string) (*v1.Secret, bool, error) { } secret.Data[v1.TLSCertKey] = certBytes secret.Data[v1.TLSPrivateKeyKey] = keyBytes - secret.Annotations[hashKey] = hash + secret.Annotations[fingerprint] = fmt.Sprintf("SHA1=%X", sha1.Sum(newCert.Raw)) return secret, true, nil } @@ -157,15 +176,21 @@ func populateCN(secret *v1.Secret, cn ...string) *v1.Secret { return secret } +// IsStatic returns true if the Secret has an attribute indicating that it contains +// a static (aka user-provided) certificate, which should not be modified. +func IsStatic(secret *v1.Secret) bool { + return secret.Annotations[Static] == "true" +} + +// NeedsUpdate returns true if any of the CNs are not currently present on the +// secret's Certificate, as recorded in the cnPrefix annotations. It will return +// false if all requested CNs are already present, or if maxSANs is non-zero and has +// been exceeded. 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 { @@ -192,6 +217,7 @@ func getPrivateKey(secret *v1.Secret) (crypto.Signer, error) { return NewPrivateKey() } +// Marshal returns the given cert and key as byte slices. func Marshal(x509Cert *x509.Certificate, privateKey crypto.Signer) ([]byte, []byte, error) { certBlock := pem.Block{ Type: CertificateBlockType, @@ -206,6 +232,7 @@ func Marshal(x509Cert *x509.Certificate, privateKey crypto.Signer) ([]byte, []by return pem.EncodeToMemory(&certBlock), keyBytes, nil } +// NewPrivateKey returnes a new ECDSA key func NewPrivateKey() (crypto.Signer, error) { return ecdsa.GenerateKey(elliptic.P256(), rand.Reader) } diff --git a/vendor/github.com/rancher/dynamiclistener/listener.go b/vendor/github.com/rancher/dynamiclistener/listener.go index 54b3fed7b3..3a30e2047f 100644 --- a/vendor/github.com/rancher/dynamiclistener/listener.go +++ b/vendor/github.com/rancher/dynamiclistener/listener.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/rancher/dynamiclistener/cert" "github.com/rancher/dynamiclistener/factory" "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" @@ -22,7 +23,7 @@ type TLSStorage interface { } type TLSFactory interface { - Refresh(secret *v1.Secret) (*v1.Secret, error) + Renew(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 @@ -152,13 +153,18 @@ type listener struct { func (l *listener) WrapExpiration(days int) net.Listener { ctx, cancel := context.WithCancel(context.Background()) go func() { - time.Sleep(5 * time.Minute) + time.Sleep(30 * time.Second) 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 + logrus.Errorf("failed to check and renew dynamic cert: %v", err) + // Don't go into short retry loop if we're using a static (user-provided) cert. + // We will still check and print an error every six hours until the user updates the secret with + // a cert that is not about to expire. Hopefully this will prompt them to take action. + if err != cert.ErrStaticCert { + wait = 5 * time.Minute + } } select { case <-ctx.Done(): @@ -191,22 +197,26 @@ func (l *listener) checkExpiration(days int) error { return err } - cert, err := tls.X509KeyPair(secret.Data[v1.TLSCertKey], secret.Data[v1.TLSPrivateKeyKey]) + keyPair, err := tls.X509KeyPair(secret.Data[v1.TLSCertKey], secret.Data[v1.TLSPrivateKeyKey]) if err != nil { return err } - certParsed, err := x509.ParseCertificate(cert.Certificate[0]) + certParsed, err := x509.ParseCertificate(keyPair.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 cert.IsCertExpired(certParsed, days) { + secret, err := l.factory.Renew(secret) if err != nil { return err } - return l.storage.Update(secret) + if err := l.storage.Update(secret); err != nil { + return err + } + // clear version to force cert reload + l.version = "" } return nil @@ -304,7 +314,7 @@ func (l *listener) updateCert(cn ...string) error { return err } - if !factory.NeedsUpdate(l.maxSANs, secret, cn...) { + if !factory.IsStatic(secret) && !factory.NeedsUpdate(l.maxSANs, secret, cn...) { return nil } @@ -324,13 +334,6 @@ 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 @@ -366,6 +369,15 @@ func (l *listener) loadCert() (*tls.Certificate, error) { return nil, err } + // cert has changed, close closeWrapper wrapped connections + if l.conns != nil { + l.connLock.Lock() + for _, conn := range l.conns { + _ = conn.close() + } + l.connLock.Unlock() + } + l.cert = &cert l.version = secret.ResourceVersion return l.cert, nil diff --git a/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go index 388936440c..5d418451b8 100644 --- a/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go +++ b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/ca.go @@ -19,27 +19,46 @@ func LoadOrGenCA(secrets v1controller.SecretClient, namespace, name string) (*x5 return factory.LoadCA(secret.Data[v1.TLSCertKey], secret.Data[v1.TLSPrivateKeyKey]) } +func LoadOrGenClient(secrets v1controller.SecretClient, namespace, name, cn string, ca *x509.Certificate, key crypto.Signer) (*x509.Certificate, crypto.Signer, error) { + secret, err := getClientSecret(secrets, namespace, name, cn, ca, key) + if err != nil { + return nil, nil, err + } + return factory.LoadCA(secret.Data[v1.TLSCertKey], secret.Data[v1.TLSPrivateKeyKey]) +} + +func getClientSecret(secrets v1controller.SecretClient, namespace, name, cn string, caCert *x509.Certificate, caKey crypto.Signer) (*v1.Secret, error) { + s, err := secrets.Get(namespace, name, metav1.GetOptions{}) + if !errors.IsNotFound(err) { + return s, err + } + + return createAndStoreClientCert(secrets, namespace, name, cn, caCert, caKey) +} + 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{}) + return createAndStore(secrets, namespace, name) } -func createAndStore(secrets v1controller.SecretClient, namespace string, name string) error { - ca, cert, err := factory.GenCA() +func createAndStoreClientCert(secrets v1controller.SecretClient, namespace string, name, cn string, caCert *x509.Certificate, caKey crypto.Signer) (*v1.Secret, error) { + key, err := factory.NewPrivateKey() if err != nil { - return err + return nil, err } - certPem, keyPem, err := factory.Marshal(ca, cert) + cert, err := factory.NewSignedClientCert(key, caCert, caKey, cn) if err != nil { - return err + return nil, err + } + + certPem, keyPem, err := factory.Marshal(cert, key) + if err != nil { + return nil, err } secret := &v1.Secret{ @@ -54,6 +73,31 @@ func createAndStore(secrets v1controller.SecretClient, namespace string, name st Type: v1.SecretTypeTLS, } - secrets.Create(secret) - return nil + return secrets.Create(secret) +} + +func createAndStore(secrets v1controller.SecretClient, namespace string, name string) (*v1.Secret, error) { + ca, cert, err := factory.GenCA() + if err != nil { + return nil, err + } + + certPem, keyPem, err := factory.Marshal(ca, cert) + if err != nil { + return nil, err + } + + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: map[string][]byte{ + v1.TLSCertKey: certPem, + v1.TLSPrivateKeyKey: keyPem, + }, + Type: v1.SecretTypeTLS, + } + + return secrets.Create(secret) } diff --git a/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go index 683ab9c502..70d5d7c44b 100644 --- a/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go +++ b/vendor/github.com/rancher/dynamiclistener/storage/kubernetes/controller.go @@ -156,10 +156,9 @@ func (s *storage) saveInK8s(secret *v1.Secret) (*v1.Secret, error) { if targetSecret.UID == "" { logrus.Infof("Creating new TLS secret for %v (count: %d): %v", targetSecret.Name, len(targetSecret.Annotations)-1, targetSecret.Annotations) return s.secrets.Create(targetSecret) - } else { - logrus.Infof("Updating TLS secret for %v (count: %d): %v", targetSecret.Name, len(targetSecret.Annotations)-1, targetSecret.Annotations) - return s.secrets.Update(targetSecret) } + logrus.Infof("Updating TLS secret for %v (count: %d): %v", targetSecret.Name, len(targetSecret.Annotations)-1, targetSecret.Annotations) + return s.secrets.Update(targetSecret) } func (s *storage) Update(secret *v1.Secret) (err error) { diff --git a/vendor/github.com/rancher/dynamiclistener/storage/memory/memory.go b/vendor/github.com/rancher/dynamiclistener/storage/memory/memory.go index c417e304cb..54f6251780 100644 --- a/vendor/github.com/rancher/dynamiclistener/storage/memory/memory.go +++ b/vendor/github.com/rancher/dynamiclistener/storage/memory/memory.go @@ -32,13 +32,15 @@ func (m *memory) Get() (*v1.Secret, error) { } func (m *memory) Update(secret *v1.Secret) error { - if m.storage != nil { - if err := m.storage.Update(secret); err != nil { - return err + if m.secret == nil || m.secret.ResourceVersion != secret.ResourceVersion { + if m.storage != nil { + if err := m.storage.Update(secret); err != nil { + return err + } } - } - logrus.Infof("Active TLS secret %s (ver=%s) (count %d): %v", secret.Name, secret.ResourceVersion, len(secret.Annotations)-1, secret.Annotations) - m.secret = secret + logrus.Infof("Active TLS secret %s (ver=%s) (count %d): %v", secret.Name, secret.ResourceVersion, len(secret.Annotations)-1, secret.Annotations) + m.secret = secret + } return nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 0bc14b5f62..ae9e3e85b8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -726,7 +726,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.1-0.20200418023342-52ede5ec9234 +# github.com/rancher/dynamiclistener v0.2.1 github.com/rancher/dynamiclistener github.com/rancher/dynamiclistener/cert github.com/rancher/dynamiclistener/factory