Bumping k8s dependencies to 1.13

This commit is contained in:
Cheng Xing
2018-11-16 14:08:25 -08:00
parent 305407125c
commit b4c0b68ec7
8002 changed files with 884099 additions and 276228 deletions

7
vendor/k8s.io/client-go/util/cert/OWNERS generated vendored Normal file
View File

@@ -0,0 +1,7 @@
approvers:
- sig-auth-certificates-approvers
reviewers:
- sig-auth-certificates-reviewers
labels:
- sig/auth

View File

@@ -18,6 +18,7 @@ package cert
import (
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
@@ -64,7 +65,7 @@ func NewPrivateKey() (*rsa.PrivateKey, error) {
}
// NewSelfSignedCACert creates a CA certificate
func NewSelfSignedCACert(cfg Config, key *rsa.PrivateKey) (*x509.Certificate, error) {
func NewSelfSignedCACert(cfg Config, key crypto.Signer) (*x509.Certificate, error) {
now := time.Now()
tmpl := x509.Certificate{
SerialNumber: new(big.Int).SetInt64(0),
@@ -76,7 +77,7 @@ func NewSelfSignedCACert(cfg Config, key *rsa.PrivateKey) (*x509.Certificate, er
NotAfter: now.Add(duration365d * 10).UTC(),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,
IsCA: true,
}
certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, key.Public(), key)
@@ -87,7 +88,7 @@ func NewSelfSignedCACert(cfg Config, key *rsa.PrivateKey) (*x509.Certificate, er
}
// NewSignedCert creates a signed certificate using the given CA certificate and key
func NewSignedCert(cfg Config, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
func NewSignedCert(cfg Config, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
if err != nil {
return nil, err
@@ -187,7 +188,7 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,
IsCA: true,
}
caDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &caTemplate, &caTemplate, &caKey.PublicKey, caKey)

View File

@@ -1,8 +1,7 @@
reviewers:
- mikedanese
- liggit
- smarterclayton
approvers:
- mikedanese
- liggit
- smarterclayton
- sig-auth-certificates-approvers
reviewers:
- sig-auth-certificates-reviewers
labels:
- sig/auth

View File

@@ -274,7 +274,7 @@ func (m *manager) Start() {
if m.dynamicTemplate {
go wait.Forever(func() {
// check if the current template matches what we last requested
if !reflect.DeepEqual(m.getLastRequest(), m.getTemplate()) {
if !m.certSatisfiesTemplate() && !reflect.DeepEqual(m.getLastRequest(), m.getTemplate()) {
// if the template is different, queue up an interrupt of the rotation deadline loop.
// if we've requested a CSR that matches the new template by the time the interrupt is handled, the interrupt is disregarded.
templateChanged <- struct{}{}
@@ -389,35 +389,30 @@ func (m *manager) rotateCerts() (bool, error) {
return true, nil
}
// nextRotationDeadline returns a value for the threshold at which the
// current certificate should be rotated, 80%+/-10% of the expiration of the
// certificate.
func (m *manager) nextRotationDeadline() time.Time {
// forceRotation is not protected by locks
if m.forceRotation {
m.forceRotation = false
return time.Now()
}
m.certAccessLock.RLock()
defer m.certAccessLock.RUnlock()
// Check that the current certificate on disk satisfies the requests from the
// current template.
//
// Note that extra items in the certificate's SAN or orgs that don't exist in
// the template will not trigger a renewal.
//
// Requires certAccessLock to be locked.
func (m *manager) certSatisfiesTemplateLocked() bool {
if m.cert == nil {
return time.Now()
return false
}
// Ensure the currently held certificate satisfies the requested subject CN and SANs
if template := m.getTemplate(); template != nil {
if template.Subject.CommonName != m.cert.Leaf.Subject.CommonName {
glog.V(2).Infof("Current certificate CN (%s) does not match requested CN (%s), rotating now", m.cert.Leaf.Subject.CommonName, template.Subject.CommonName)
return time.Now()
glog.V(2).Infof("Current certificate CN (%s) does not match requested CN (%s)", m.cert.Leaf.Subject.CommonName, template.Subject.CommonName)
return false
}
currentDNSNames := sets.NewString(m.cert.Leaf.DNSNames...)
desiredDNSNames := sets.NewString(template.DNSNames...)
missingDNSNames := desiredDNSNames.Difference(currentDNSNames)
if len(missingDNSNames) > 0 {
glog.V(2).Infof("Current certificate is missing requested DNS names %v, rotating now", missingDNSNames.List())
return time.Now()
glog.V(2).Infof("Current certificate is missing requested DNS names %v", missingDNSNames.List())
return false
}
currentIPs := sets.NewString()
@@ -430,9 +425,43 @@ func (m *manager) nextRotationDeadline() time.Time {
}
missingIPs := desiredIPs.Difference(currentIPs)
if len(missingIPs) > 0 {
glog.V(2).Infof("Current certificate is missing requested IP addresses %v, rotating now", missingIPs.List())
return time.Now()
glog.V(2).Infof("Current certificate is missing requested IP addresses %v", missingIPs.List())
return false
}
currentOrgs := sets.NewString(m.cert.Leaf.Subject.Organization...)
desiredOrgs := sets.NewString(template.Subject.Organization...)
missingOrgs := desiredOrgs.Difference(currentOrgs)
if len(missingOrgs) > 0 {
glog.V(2).Infof("Current certificate is missing requested orgs %v", missingOrgs.List())
return false
}
}
return true
}
func (m *manager) certSatisfiesTemplate() bool {
m.certAccessLock.RLock()
defer m.certAccessLock.RUnlock()
return m.certSatisfiesTemplateLocked()
}
// nextRotationDeadline returns a value for the threshold at which the
// current certificate should be rotated, 80%+/-10% of the expiration of the
// certificate.
func (m *manager) nextRotationDeadline() time.Time {
// forceRotation is not protected by locks
if m.forceRotation {
m.forceRotation = false
return time.Now()
}
m.certAccessLock.RLock()
defer m.certAccessLock.RUnlock()
if !m.certSatisfiesTemplateLocked() {
return time.Now()
}
notAfter := m.cert.Leaf.NotAfter

View File

@@ -22,6 +22,7 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"net"
"strings"
"testing"
"time"
@@ -212,6 +213,170 @@ func TestSetRotationDeadline(t *testing.T) {
}
}
func TestCertSatisfiesTemplate(t *testing.T) {
testCases := []struct {
name string
cert *x509.Certificate
template *x509.CertificateRequest
shouldSatisfy bool
}{
{
name: "No certificate, no template",
cert: nil,
template: nil,
shouldSatisfy: false,
},
{
name: "No certificate",
cert: nil,
template: &x509.CertificateRequest{},
shouldSatisfy: false,
},
{
name: "No template",
cert: &x509.Certificate{
Subject: pkix.Name{
CommonName: "system:node:fake-node-name",
},
},
template: nil,
shouldSatisfy: true,
},
{
name: "Mismatched common name",
cert: &x509.Certificate{
Subject: pkix.Name{
CommonName: "system:node:fake-node-name-2",
},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "system:node:fake-node-name",
},
},
shouldSatisfy: false,
},
{
name: "Missing orgs in certificate",
cert: &x509.Certificate{
Subject: pkix.Name{
Organization: []string{"system:nodes"},
},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{
Organization: []string{"system:nodes", "foobar"},
},
},
shouldSatisfy: false,
},
{
name: "Extra orgs in certificate",
cert: &x509.Certificate{
Subject: pkix.Name{
Organization: []string{"system:nodes", "foobar"},
},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{
Organization: []string{"system:nodes"},
},
},
shouldSatisfy: true,
},
{
name: "Missing DNS names in certificate",
cert: &x509.Certificate{
Subject: pkix.Name{},
DNSNames: []string{"foo.example.com"},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{},
DNSNames: []string{"foo.example.com", "bar.example.com"},
},
shouldSatisfy: false,
},
{
name: "Extra DNS names in certificate",
cert: &x509.Certificate{
Subject: pkix.Name{},
DNSNames: []string{"foo.example.com", "bar.example.com"},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{},
DNSNames: []string{"foo.example.com"},
},
shouldSatisfy: true,
},
{
name: "Missing IP addresses in certificate",
cert: &x509.Certificate{
Subject: pkix.Name{},
IPAddresses: []net.IP{net.ParseIP("192.168.1.1")},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{},
IPAddresses: []net.IP{net.ParseIP("192.168.1.1"), net.ParseIP("192.168.1.2")},
},
shouldSatisfy: false,
},
{
name: "Extra IP addresses in certificate",
cert: &x509.Certificate{
Subject: pkix.Name{},
IPAddresses: []net.IP{net.ParseIP("192.168.1.1"), net.ParseIP("192.168.1.2")},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{},
IPAddresses: []net.IP{net.ParseIP("192.168.1.1")},
},
shouldSatisfy: true,
},
{
name: "Matching certificate",
cert: &x509.Certificate{
Subject: pkix.Name{
CommonName: "system:node:fake-node-name",
Organization: []string{"system:nodes"},
},
DNSNames: []string{"foo.example.com"},
IPAddresses: []net.IP{net.ParseIP("192.168.1.1")},
},
template: &x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "system:node:fake-node-name",
Organization: []string{"system:nodes"},
},
DNSNames: []string{"foo.example.com"},
IPAddresses: []net.IP{net.ParseIP("192.168.1.1")},
},
shouldSatisfy: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
var tlsCert *tls.Certificate
if tc.cert != nil {
tlsCert = &tls.Certificate{
Leaf: tc.cert,
}
}
m := manager{
cert: tlsCert,
getTemplate: func() *x509.CertificateRequest { return tc.template },
}
result := m.certSatisfiesTemplate()
if result != tc.shouldSatisfy {
t.Errorf("cert: %+v, template: %+v, certSatisfiesTemplate returned %v, want %v", m.cert, tc.template, result, tc.shouldSatisfy)
}
})
}
}
func TestRotateCertCreateCSRError(t *testing.T) {
now := time.Now()
m := manager{

View File

@@ -21,7 +21,6 @@ import (
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@@ -171,11 +170,9 @@ func (s *fileStore) Current() (*tls.Certificate, error) {
}
func loadFile(pairFile string) (*tls.Certificate, error) {
certBlock, keyBlock, err := loadCertKeyBlocks(pairFile)
if err != nil {
return nil, err
}
cert, err := tls.X509KeyPair(pem.EncodeToMemory(certBlock), pem.EncodeToMemory(keyBlock))
// LoadX509KeyPair knows how to parse combined cert and private key from
// the same file.
cert, err := tls.LoadX509KeyPair(pairFile, pairFile)
if err != nil {
return nil, fmt.Errorf("could not convert data from %q into cert/key pair: %v", pairFile, err)
}
@@ -187,22 +184,6 @@ func loadFile(pairFile string) (*tls.Certificate, error) {
return &cert, nil
}
func loadCertKeyBlocks(pairFile string) (cert *pem.Block, key *pem.Block, err error) {
data, err := ioutil.ReadFile(pairFile)
if err != nil {
return nil, nil, fmt.Errorf("could not load cert/key pair from %q: %v", pairFile, err)
}
certBlock, rest := pem.Decode(data)
if certBlock == nil {
return nil, nil, fmt.Errorf("could not decode the first block from %q from expected PEM format", pairFile)
}
keyBlock, _ := pem.Decode(rest)
if keyBlock == nil {
return nil, nil, fmt.Errorf("could not decode the second block from %q from expected PEM format", pairFile)
}
return certBlock, keyBlock, nil
}
func (s *fileStore) Update(certData, keyData []byte) (*tls.Certificate, error) {
ts := time.Now().Format("2006-01-02-15-04-05")
pemFilename := s.filename(ts)

View File

@@ -17,12 +17,11 @@ limitations under the License.
package certificate
import (
"bytes"
"io/ioutil"
"os"
"path/filepath"
"testing"
"k8s.io/client-go/util/cert"
)
func TestUpdateSymlinkExistingFileError(t *testing.T) {
@@ -69,16 +68,16 @@ func TestUpdateSymlinkNewFileNotExist(t *testing.T) {
pairNamePrefix: "kubelet",
}
if err := s.updateSymlink(oldPairFile); err != nil {
t.Errorf("Got %v, wanted successful update of the symlink to point to %q", err, oldPairFile)
t.Errorf("Got error %v, wanted successful update of the symlink to point to %q", err, oldPairFile)
}
if _, err := os.Stat(oldPairFile); err != nil {
t.Errorf("Got %v, wanted file %q to be there.", oldPairFile, err)
t.Errorf("Got error %v, wanted file %q to be there.", err, oldPairFile)
}
currentPairFile := filepath.Join(dir, "kubelet-current.pem")
if fi, err := os.Lstat(currentPairFile); err != nil {
t.Errorf("Got %v, wanted file %q to be there", currentPairFile, err)
t.Errorf("Got error %v, wanted file %q to be there", err, currentPairFile)
} else if fi.Mode()&os.ModeSymlink != os.ModeSymlink {
t.Errorf("Got %q not a symlink.", currentPairFile)
}
@@ -113,7 +112,7 @@ func TestUpdateSymlinkNoSymlink(t *testing.T) {
}
if _, err := os.Stat(pairFile); err != nil {
t.Errorf("Got error %v, wanted file %q to be there", pairFile, err)
t.Errorf("Got error %v, wanted file %q to be there", err, pairFile)
}
currentPairFile := filepath.Join(dir, "kubelet-current.pem")
if fi, err := os.Lstat(currentPairFile); err != nil {
@@ -178,96 +177,6 @@ func TestUpdateSymlinkReplaceExistingSymlink(t *testing.T) {
}
}
func TestLoadCertKeyBlocksNoFile(t *testing.T) {
dir, err := ioutil.TempDir("", "k8s-test-load-cert-key-blocks")
if err != nil {
t.Fatalf("Unable to create the test directory %q: %v", dir, err)
}
defer func() {
if err := os.RemoveAll(dir); err != nil {
t.Errorf("Unable to clean up test directory %q: %v", dir, err)
}
}()
pairFile := filepath.Join(dir, "kubelet-pair.pem")
if _, _, err := loadCertKeyBlocks(pairFile); err == nil {
t.Errorf("Got no error, but expected %q not found.", pairFile)
}
}
func TestLoadCertKeyBlocksEmptyFile(t *testing.T) {
dir, err := ioutil.TempDir("", "k8s-test-load-cert-key-blocks")
if err != nil {
t.Fatalf("Unable to create the test directory %q: %v", dir, err)
}
defer func() {
if err := os.RemoveAll(dir); err != nil {
t.Errorf("Unable to clean up test directory %q: %v", dir, err)
}
}()
pairFile := filepath.Join(dir, "kubelet-pair.pem")
if err := ioutil.WriteFile(pairFile, nil, 0600); err != nil {
t.Fatalf("Unable to create the file %q: %v", pairFile, err)
}
if _, _, err := loadCertKeyBlocks(pairFile); err == nil {
t.Errorf("Got no error, but expected %q not found.", pairFile)
}
}
func TestLoadCertKeyBlocksPartialFile(t *testing.T) {
dir, err := ioutil.TempDir("", "k8s-test-load-cert-key-blocks")
if err != nil {
t.Fatalf("Unable to create the test directory %q: %v", dir, err)
}
defer func() {
if err := os.RemoveAll(dir); err != nil {
t.Errorf("Unable to clean up test directory %q: %v", dir, err)
}
}()
pairFile := filepath.Join(dir, "kubelet-pair.pem")
if err := ioutil.WriteFile(pairFile, storeCertData.certificatePEM, 0600); err != nil {
t.Fatalf("Unable to create the file %q: %v", pairFile, err)
}
if _, _, err := loadCertKeyBlocks(pairFile); err == nil {
t.Errorf("Got no error, but expected %q invalid.", pairFile)
}
}
func TestLoadCertKeyBlocks(t *testing.T) {
dir, err := ioutil.TempDir("", "k8s-test-load-cert-key-blocks")
if err != nil {
t.Fatalf("Unable to create the test directory %q: %v", dir, err)
}
defer func() {
if err := os.RemoveAll(dir); err != nil {
t.Errorf("Unable to clean up test directory %q: %v", dir, err)
}
}()
pairFile := filepath.Join(dir, "kubelet-pair.pem")
data := append(storeCertData.certificatePEM, []byte("\n")...)
data = append(data, storeCertData.keyPEM...)
if err := ioutil.WriteFile(pairFile, data, 0600); err != nil {
t.Fatalf("Unable to create the file %q: %v", pairFile, err)
}
certBlock, keyBlock, err := loadCertKeyBlocks(pairFile)
if err != nil {
t.Errorf("Got %v, but expected no error.", pairFile)
}
if certBlock.Type != cert.CertificateBlockType {
t.Errorf("Got %q loaded from the pair file, expected a %q.", certBlock.Type, cert.CertificateBlockType)
}
if keyBlock.Type != cert.RSAPrivateKeyBlockType {
t.Errorf("Got %q loaded from the pair file, expected a %q.", keyBlock.Type, cert.RSAPrivateKeyBlockType)
}
}
func TestLoadFile(t *testing.T) {
dir, err := ioutil.TempDir("", "k8s-test-load-cert-key-blocks")
if err != nil {
@@ -280,21 +189,30 @@ func TestLoadFile(t *testing.T) {
}()
pairFile := filepath.Join(dir, "kubelet-pair.pem")
data := append(storeCertData.certificatePEM, []byte("\n")...)
data = append(data, storeCertData.keyPEM...)
if err := ioutil.WriteFile(pairFile, data, 0600); err != nil {
t.Fatalf("Unable to create the file %q: %v", pairFile, err)
}
cert, err := loadFile(pairFile)
if err != nil {
t.Fatalf("Could not load certificate from disk: %v", err)
tests := []struct {
desc string
data []byte
}{
{desc: "cert and key", data: bytes.Join([][]byte{storeCertData.certificatePEM, storeCertData.keyPEM}, []byte("\n"))},
{desc: "key and cert", data: bytes.Join([][]byte{storeCertData.keyPEM, storeCertData.certificatePEM}, []byte("\n"))},
}
if cert == nil {
t.Fatalf("There was no error, but no certificate data was returned.")
}
if cert.Leaf == nil {
t.Fatalf("Got an empty leaf, expected private data.")
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
if err := ioutil.WriteFile(pairFile, tt.data, 0600); err != nil {
t.Fatalf("Unable to create the file %q: %v", pairFile, err)
}
cert, err := loadFile(pairFile)
if err != nil {
t.Fatalf("Could not load certificate from disk: %v", err)
}
if cert == nil {
t.Fatalf("There was no error, but no certificate data was returned.")
}
if cert.Leaf == nil {
t.Fatalf("Got an empty leaf, expected private data.")
}
})
}
}

View File

@@ -27,6 +27,8 @@ type DoWorkPieceFunc func(piece int)
// Parallelize is a very simple framework that allows for parallelizing
// N independent pieces of work.
//
// Deprecated: Use ParallelizeUntil instead.
func Parallelize(workers, pieces int, doWorkPiece DoWorkPieceFunc) {
ParallelizeUntil(nil, workers, pieces, doWorkPiece)
}

View File

@@ -20,10 +20,10 @@ package workqueue
type RateLimitingInterface interface {
DelayingInterface
// AddRateLimited adds an item to the workqueue after the rate limiter says its ok
// AddRateLimited adds an item to the workqueue after the rate limiter says it's ok
AddRateLimited(item interface{})
// Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing
// Forget indicates that an item is finished being retried. Doesn't matter whether it's for perm failing
// or for success, we'll stop the rate limiter from tracking it. This only clears the `rateLimiter`, you
// still have to call `Done` on the queue.
Forget(item interface{})
@@ -55,7 +55,7 @@ type rateLimitingType struct {
rateLimiter RateLimiter
}
// AddRateLimited AddAfter's the item based on the time when the rate limiter says its ok
// AddRateLimited AddAfter's the item based on the time when the rate limiter says it's ok
func (q *rateLimitingType) AddRateLimited(item interface{}) {
q.DelayingInterface.AddAfter(item, q.rateLimiter.When(item))
}