mirror of https://github.com/kubernetes/kops.git
Merge pull request #4650 from justinsb/keyset_format
Define KeysetFormat type, embed into keyset
This commit is contained in:
commit
403707c9cc
|
@ -20,7 +20,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/tokens"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/fitasks"
|
||||
|
@ -38,9 +37,9 @@ var _ fi.ModelBuilder = &PKIModelBuilder{}
|
|||
// Build is responsible for generating the various pki assets.
|
||||
func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||
|
||||
// Note: the fitasks.Keypair structs are created with a Format that == fitasks.KeypairType
|
||||
// to denote that these tasks are using the newer Keypar API Type. This value is used
|
||||
// to upgrade a legacy Keypair to the newer Keypair API object.
|
||||
// We specify the KeysetFormatV1Alpha2 format, to upgrade from the legacy representation (separate files)
|
||||
// to the newer keyset.yaml representation.
|
||||
format := string(fi.KeysetFormatV1Alpha2)
|
||||
|
||||
// TODO: Only create the CA via this task
|
||||
defaultCA := &fitasks.Keypair{
|
||||
|
@ -48,8 +47,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Lifecycle: b.Lifecycle,
|
||||
Subject: "cn=kubernetes",
|
||||
Type: "ca",
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(defaultCA)
|
||||
|
||||
|
@ -62,8 +60,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "o=" + user.NodesGroup + ",cn=kubelet",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -77,8 +74,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=kubelet-api",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
})
|
||||
}
|
||||
{
|
||||
|
@ -88,8 +84,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=" + user.KubeScheduler,
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -101,8 +96,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=" + user.KubeProxy,
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -114,8 +108,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=" + user.KubeControllerManager,
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -135,8 +128,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=etcd",
|
||||
Type: "clientServer",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
})
|
||||
c.AddTask(&fitasks.Keypair{
|
||||
Name: fi.String("etcd-client"),
|
||||
|
@ -144,8 +136,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=etcd-client",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
})
|
||||
|
||||
// @check if calico is enabled as the CNI provider
|
||||
|
@ -156,8 +147,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=calico-client",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -168,8 +158,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=" + "system:kube-router",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -181,8 +170,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "o=" + user.SystemPrivilegedGroup + ",cn=kubecfg",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -194,8 +182,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=apiserver-proxy-client",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -206,8 +193,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Lifecycle: b.Lifecycle,
|
||||
Subject: "cn=apiserver-aggregator-ca",
|
||||
Type: "ca",
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(aggregatorCA)
|
||||
|
||||
|
@ -218,8 +204,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "cn=aggregator",
|
||||
Type: "client",
|
||||
Signer: aggregatorCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(aggregator)
|
||||
}
|
||||
|
@ -232,8 +217,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Subject: "o=" + user.SystemPrivilegedGroup + ",cn=kops",
|
||||
Type: "client",
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
@ -271,8 +255,7 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
Type: "server",
|
||||
AlternateNames: alternateNames,
|
||||
Signer: defaultCA,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
|
|
@ -85,24 +85,23 @@ func TestKeypairUpgrade(t *testing.T) {
|
|||
|
||||
// We define a function so we can rebuild the tasks, because we modify in-place when running
|
||||
buildTasks := func() map[string]fi.Task {
|
||||
format := string(fi.KeysetFormatV1Alpha2)
|
||||
|
||||
ca := &fitasks.Keypair{
|
||||
Name: fi.String(fi.CertificateId_CA),
|
||||
Lifecycle: &lifecycle,
|
||||
Subject: "cn=kubernetes",
|
||||
Type: "ca",
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Format: format,
|
||||
}
|
||||
|
||||
kubelet := &fitasks.Keypair{
|
||||
Name: fi.String("kubelet"),
|
||||
Lifecycle: &lifecycle,
|
||||
|
||||
Subject: "o=nodes,cn=kubelet",
|
||||
Type: "client",
|
||||
Signer: ca,
|
||||
|
||||
Format: string(kops.SecretTypeKeypair),
|
||||
Subject: "o=nodes,cn=kubelet",
|
||||
Type: "client",
|
||||
Signer: ca,
|
||||
Format: format,
|
||||
}
|
||||
|
||||
tasks := make(map[string]fi.Task)
|
||||
|
|
|
@ -33,6 +33,13 @@ const (
|
|||
SecretNameSSHPrimary = "admin"
|
||||
)
|
||||
|
||||
type KeysetFormat string
|
||||
|
||||
const (
|
||||
KeysetFormatLegacy KeysetFormat = "legacy"
|
||||
KeysetFormatV1Alpha2 KeysetFormat = "v1alpha2"
|
||||
)
|
||||
|
||||
type KeystoreItem struct {
|
||||
Type kops.KeysetType
|
||||
Name string
|
||||
|
@ -47,7 +54,7 @@ type Keystore interface {
|
|||
// This func returns a cert, private key and a string. The string value is the Format of the keystore which is either
|
||||
// an empty string, which denotes a Legacy Keypair, or a value of "Keypair". This string is used by a keypair
|
||||
// task convert a Legacy Keypair to the new Keypair API format.
|
||||
FindKeypair(name string) (*pki.Certificate, *pki.PrivateKey, string, error)
|
||||
FindKeypair(name string) (*pki.Certificate, *pki.PrivateKey, KeysetFormat, error)
|
||||
|
||||
CreateKeypair(signer string, name string, template *x509.Certificate, privateKey *pki.PrivateKey) (*pki.Certificate, error)
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ func (c *ClientsetCAStore) readCAKeypairs(id string) (*keyset, error) {
|
|||
return cached, nil
|
||||
}
|
||||
|
||||
keyset, _, err := c.loadKeyset(id)
|
||||
keyset, err := c.loadKeyset(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -122,6 +122,7 @@ func (c *ClientsetCAStore) generateCACertificate(id string) (*keyset, error) {
|
|||
|
||||
// keyset is a parsed Keyset
|
||||
type keyset struct {
|
||||
format KeysetFormat
|
||||
items map[string]*keysetItem
|
||||
primary *keysetItem
|
||||
}
|
||||
|
@ -133,7 +134,7 @@ type keysetItem struct {
|
|||
privateKey *pki.PrivateKey
|
||||
}
|
||||
|
||||
func parseKeyset(o *kops.Keyset) (*keyset, string, error) {
|
||||
func parseKeyset(o *kops.Keyset) (*keyset, error) {
|
||||
name := o.Name
|
||||
|
||||
keyset := &keyset{
|
||||
|
@ -148,7 +149,7 @@ func parseKeyset(o *kops.Keyset) (*keyset, string, error) {
|
|||
cert, err := pki.ParsePEMCertificate(key.PublicMaterial)
|
||||
if err != nil {
|
||||
glog.Warningf("key public material was %s", key.PublicMaterial)
|
||||
return nil, "", fmt.Errorf("error loading certificate %s/%s: %v", name, key.Id, err)
|
||||
return nil, fmt.Errorf("error loading certificate %s/%s: %v", name, key.Id, err)
|
||||
}
|
||||
ki.certificate = cert
|
||||
}
|
||||
|
@ -156,7 +157,7 @@ func parseKeyset(o *kops.Keyset) (*keyset, string, error) {
|
|||
if len(key.PrivateMaterial) != 0 {
|
||||
privateKey, err := pki.ParsePEMPrivateKey(key.PrivateMaterial)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error loading private key %s/%s: %v", name, key.Id, err)
|
||||
return nil, fmt.Errorf("error loading private key %s/%s: %v", name, key.Id, err)
|
||||
}
|
||||
ki.privateKey = privateKey
|
||||
}
|
||||
|
@ -166,23 +167,25 @@ func parseKeyset(o *kops.Keyset) (*keyset, string, error) {
|
|||
|
||||
keyset.primary = keyset.findPrimary()
|
||||
|
||||
// This value == Keypair when using the API Keyset. When the keyset is a legacy value the o.Spec.Type value is
|
||||
// not set. The keypair task is using this value to upgrade legacy keysets to keysets that use the API.
|
||||
keypairType := string(o.Spec.Type)
|
||||
return keyset, keypairType, nil
|
||||
return keyset, nil
|
||||
}
|
||||
|
||||
// loadKeyset gets the named keyset and the format of the Keyset.
|
||||
func (c *ClientsetCAStore) loadKeyset(name string) (*keyset, string, error) {
|
||||
func (c *ClientsetCAStore) loadKeyset(name string) (*keyset, error) {
|
||||
o, err := c.clientset.Keysets(c.namespace).Get(name, v1.GetOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, "", nil
|
||||
return nil, nil
|
||||
}
|
||||
return nil, "", fmt.Errorf("error reading keyset %q: %v", name, err)
|
||||
return nil, fmt.Errorf("error reading keyset %q: %v", name, err)
|
||||
}
|
||||
|
||||
return parseKeyset(o)
|
||||
keyset, err := parseKeyset(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyset.format = KeysetFormatV1Alpha2
|
||||
return keyset, nil
|
||||
}
|
||||
|
||||
// findPrimary returns the primary keysetItem in the keyset
|
||||
|
@ -240,14 +243,14 @@ func (c *ClientsetCAStore) CertificatePool(id string, createIfMissing bool) (*Ce
|
|||
}
|
||||
|
||||
// FindKeypair implements CAStore::FindKeypair
|
||||
func (c *ClientsetCAStore) FindKeypair(name string) (*pki.Certificate, *pki.PrivateKey, string, error) {
|
||||
keyset, keysetType, err := c.loadKeyset(name)
|
||||
func (c *ClientsetCAStore) FindKeypair(name string) (*pki.Certificate, *pki.PrivateKey, KeysetFormat, error) {
|
||||
keyset, err := c.loadKeyset(name)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
}
|
||||
|
||||
if keyset != nil && keyset.primary != nil {
|
||||
return keyset.primary.certificate, keyset.primary.privateKey, keysetType, nil
|
||||
return keyset.primary.certificate, keyset.primary.privateKey, keyset.format, nil
|
||||
}
|
||||
|
||||
return nil, nil, "", nil
|
||||
|
@ -255,22 +258,21 @@ func (c *ClientsetCAStore) FindKeypair(name string) (*pki.Certificate, *pki.Priv
|
|||
|
||||
// FindCert implements CAStore::FindCert
|
||||
func (c *ClientsetCAStore) FindCert(name string) (*pki.Certificate, error) {
|
||||
keyset, _, err := c.loadKeyset(name)
|
||||
keyset, err := c.loadKeyset(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cert *pki.Certificate
|
||||
if keyset != nil && keyset.primary != nil {
|
||||
cert = keyset.primary.certificate
|
||||
return keyset.primary.certificate, nil
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// FindCertificatePool implements CAStore::FindCertificatePool
|
||||
func (c *ClientsetCAStore) FindCertificatePool(name string) (*CertificatePool, error) {
|
||||
keyset, _, err := c.loadKeyset(name)
|
||||
keyset, err := c.loadKeyset(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -392,7 +394,7 @@ func (c *ClientsetCAStore) storeAndVerifyKeypair(name string, cert *pki.Certific
|
|||
}
|
||||
|
||||
// Make double-sure it round-trips
|
||||
keyset, _, err := c.loadKeyset(name)
|
||||
keyset, err := c.loadKeyset(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching stored certificate: %v", err)
|
||||
}
|
||||
|
@ -431,7 +433,7 @@ func (c *ClientsetCAStore) AddCert(name string, cert *pki.Certificate) error {
|
|||
|
||||
// FindPrivateKey implements CAStore::FindPrivateKey
|
||||
func (c *ClientsetCAStore) FindPrivateKey(name string) (*pki.PrivateKey, error) {
|
||||
keyset, _, err := c.loadKeyset(name)
|
||||
keyset, err := c.loadKeyset(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ type Keypair struct {
|
|||
Type string `json:"type"`
|
||||
// Format stores the api version of kops.Keyset. We are using this info in order to determine if kops
|
||||
// is accessing legacy secrets that do not use keyset.yaml.
|
||||
Format string `json:"keypairType"`
|
||||
Format string `json:"format"`
|
||||
}
|
||||
|
||||
var _ fi.HasCheckExisting = &Keypair{}
|
||||
|
@ -76,7 +76,7 @@ func (e *Keypair) Find(c *fi.Context) (*Keypair, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
cert, key, keySetType, err := c.Keystore.FindKeypair(name)
|
||||
cert, key, format, err := c.Keystore.FindKeypair(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -100,8 +100,7 @@ func (e *Keypair) Find(c *fi.Context) (*Keypair, error) {
|
|||
AlternateNames: alternateNames,
|
||||
Subject: pkixNameToString(&cert.Subject),
|
||||
Type: buildTypeDescription(cert.Certificate),
|
||||
|
||||
Format: keySetType,
|
||||
Format: string(format),
|
||||
}
|
||||
|
||||
actual.Signer = &Keypair{Subject: pkixNameToString(&cert.Certificate.Issuer)}
|
||||
|
|
|
@ -90,7 +90,7 @@ func (c *KubernetesKeystore) findSecret(id string) (*v1.Secret, error) {
|
|||
return secret, nil
|
||||
}
|
||||
|
||||
func (c *KubernetesKeystore) FindKeypair(id string) (*pki.Certificate, *pki.PrivateKey, string, error) {
|
||||
func (c *KubernetesKeystore) FindKeypair(id string) (*pki.Certificate, *pki.PrivateKey, fi.KeysetFormat, error) {
|
||||
secret, err := c.findSecret(id)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
|
@ -105,10 +105,7 @@ func (c *KubernetesKeystore) FindKeypair(id string) (*pki.Certificate, *pki.Priv
|
|||
return nil, nil, "", fmt.Errorf("error parsing secret %s/%s from kubernetes: %v", c.namespace, id, err)
|
||||
}
|
||||
|
||||
// This value is when using the API Keyset. When the keyset is a legacy value the secret.Type value is
|
||||
// not set. The keypair task is using this value to upgrade legacy keysets to keysets that use the API.
|
||||
keypairType := string(secret.Type)
|
||||
return keypair.Certificate, keypair.PrivateKey, keypairType, nil
|
||||
return keypair.Certificate, keypair.PrivateKey, fi.KeysetFormatV1Alpha2, nil
|
||||
}
|
||||
|
||||
func (c *KubernetesKeystore) CreateKeypair(signer string, id string, template *x509.Certificate, privateKey *pki.PrivateKey) (*pki.Certificate, error) {
|
||||
|
|
|
@ -103,7 +103,7 @@ func (s *VFSCAStore) readCAKeypairs(id string) (*keyset, *keyset, error) {
|
|||
return cached.certificates, cached.privateKeys, nil
|
||||
}
|
||||
|
||||
caCertificates, _, err := s.loadCertificates(s.buildCertificatePoolPath(id), true)
|
||||
caCertificates, err := s.loadCertificates(s.buildCertificatePoolPath(id), true)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ func (c *VFSCAStore) generateCACertificate(name string) (*keyset, *keyset, error
|
|||
}
|
||||
|
||||
// Make double-sure it round-trips
|
||||
certificates, _, err := c.loadCertificates(c.buildCertificatePoolPath(name), true)
|
||||
certificates, err := c.loadCertificates(c.buildCertificatePoolPath(name), true)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ func (c *VFSCAStore) buildPrivateKeyPath(name string, id string) vfs.Path {
|
|||
return c.basedir.Join("private", name, id+".key")
|
||||
}
|
||||
|
||||
func (c *VFSCAStore) parseKeysetYaml(data []byte) (*kops.Keyset, error) {
|
||||
func (c *VFSCAStore) parseKeysetYaml(data []byte) (*kops.Keyset, KeysetFormat, error) {
|
||||
codecs := kopscodecs.Codecs
|
||||
yaml, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), "application/yaml")
|
||||
if !ok {
|
||||
|
@ -226,42 +226,48 @@ func (c *VFSCAStore) parseKeysetYaml(data []byte) (*kops.Keyset, error) {
|
|||
|
||||
defaultReadVersion := v1alpha2.SchemeGroupVersion.WithKind("Keyset")
|
||||
|
||||
object, _, err := decoder.Decode(data, &defaultReadVersion, nil)
|
||||
object, gvk, err := decoder.Decode(data, &defaultReadVersion, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing keyset: %v", err)
|
||||
return nil, "", fmt.Errorf("error parsing keyset: %v", err)
|
||||
}
|
||||
|
||||
keyset, ok := object.(*kops.Keyset)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("object was not a keyset, was a %T", object)
|
||||
return nil, "", fmt.Errorf("object was not a keyset, was a %T", object)
|
||||
}
|
||||
return keyset, nil
|
||||
|
||||
if gvk == nil {
|
||||
return nil, "", fmt.Errorf("object did not have GroupVersionKind: %q", keyset.Name)
|
||||
}
|
||||
|
||||
return keyset, KeysetFormat(gvk.Version), nil
|
||||
}
|
||||
|
||||
// loadCertificatesBundle loads a keyset from the path
|
||||
// Returns (nil, nil) if the file is not found
|
||||
// Bundles avoid the need for a list-files permission, which can be tricky on e.g. GCE
|
||||
func (c *VFSCAStore) loadKeysetBundle(p vfs.Path) (*keyset, string, error) {
|
||||
func (c *VFSCAStore) loadKeysetBundle(p vfs.Path) (*keyset, error) {
|
||||
data, err := p.ReadFile()
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, "", nil
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, "", fmt.Errorf("unable to read bundle %q: %v", p, err)
|
||||
return nil, fmt.Errorf("unable to read bundle %q: %v", p, err)
|
||||
}
|
||||
}
|
||||
|
||||
o, err := c.parseKeysetYaml(data)
|
||||
o, format, err := c.parseKeysetYaml(data)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error parsing bundle %q: %v", p, err)
|
||||
return nil, fmt.Errorf("error parsing bundle %q: %v", p, err)
|
||||
}
|
||||
|
||||
keyset, version, err := parseKeyset(o)
|
||||
keyset, err := parseKeyset(o)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error mapping bundle %q: %v", p, err)
|
||||
return nil, fmt.Errorf("error mapping bundle %q: %v", p, err)
|
||||
}
|
||||
|
||||
return keyset, version, nil
|
||||
keyset.format = format
|
||||
return keyset, nil
|
||||
}
|
||||
|
||||
func (k *keyset) ToAPIObject(name string, includePrivateKeyMaterial bool) (*kops.Keyset, error) {
|
||||
|
@ -362,14 +368,14 @@ func SerializeKeyset(o *kops.Keyset) ([]byte, error) {
|
|||
return objectData.Bytes(), nil
|
||||
}
|
||||
|
||||
func (c *VFSCAStore) loadCertificates(p vfs.Path, useBundle bool) (*keyset, string, error) {
|
||||
func (c *VFSCAStore) loadCertificates(p vfs.Path, useBundle bool) (*keyset, error) {
|
||||
// Attempt to load prebuilt bundle, which avoids having to list files, which is a permission that can be hard to
|
||||
// give on GCE / other clouds
|
||||
if useBundle {
|
||||
bundlePath := p.Join("keyset.yaml")
|
||||
bundle, version, err := c.loadKeysetBundle(bundlePath)
|
||||
bundle, err := c.loadKeysetBundle(bundlePath)
|
||||
if !c.allowList {
|
||||
return bundle, version, err
|
||||
return bundle, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -377,7 +383,7 @@ func (c *VFSCAStore) loadCertificates(p vfs.Path, useBundle bool) (*keyset, stri
|
|||
} else if bundle == nil {
|
||||
glog.V(2).Infof("no certificate bundle %q, falling back to directory-list method", bundlePath)
|
||||
} else {
|
||||
return bundle, version, nil
|
||||
return bundle, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,9 +394,9 @@ func (c *VFSCAStore) loadCertificates(p vfs.Path, useBundle bool) (*keyset, stri
|
|||
files, err := p.ReadDir()
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, "", nil
|
||||
return nil, nil
|
||||
}
|
||||
return nil, "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
|
@ -403,7 +409,7 @@ func (c *VFSCAStore) loadCertificates(p vfs.Path, useBundle bool) (*keyset, stri
|
|||
|
||||
cert, err := c.loadOneCertificate(f)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error loading certificate %q: %v", f, err)
|
||||
return nil, fmt.Errorf("error loading certificate %q: %v", f, err)
|
||||
}
|
||||
|
||||
keyset.items[id] = &keysetItem{
|
||||
|
@ -413,12 +419,13 @@ func (c *VFSCAStore) loadCertificates(p vfs.Path, useBundle bool) (*keyset, stri
|
|||
}
|
||||
|
||||
if len(keyset.items) == 0 {
|
||||
return nil, "", nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
keyset.format = KeysetFormatLegacy
|
||||
keyset.primary = keyset.findPrimary()
|
||||
|
||||
return keyset, "", nil
|
||||
return keyset, nil
|
||||
}
|
||||
|
||||
func (c *VFSCAStore) loadOneCertificate(p vfs.Path) (*pki.Certificate, error) {
|
||||
|
@ -452,8 +459,8 @@ func (c *VFSCAStore) CertificatePool(id string, createIfMissing bool) (*Certific
|
|||
|
||||
}
|
||||
|
||||
func (c *VFSCAStore) FindKeypair(id string) (*pki.Certificate, *pki.PrivateKey, string, error) {
|
||||
cert, keypairType, err := c.findCert(id)
|
||||
func (c *VFSCAStore) FindKeypair(id string) (*pki.Certificate, *pki.PrivateKey, KeysetFormat, error) {
|
||||
cert, certFormat, err := c.findCert(id)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
}
|
||||
|
@ -463,22 +470,21 @@ func (c *VFSCAStore) FindKeypair(id string) (*pki.Certificate, *pki.PrivateKey,
|
|||
return nil, nil, "", err
|
||||
}
|
||||
|
||||
return cert, key, keypairType, nil
|
||||
return cert, key, certFormat, nil
|
||||
}
|
||||
|
||||
func (c *VFSCAStore) findCert(name string) (*pki.Certificate, string, error) {
|
||||
func (c *VFSCAStore) findCert(name string) (*pki.Certificate, KeysetFormat, error) {
|
||||
p := c.buildCertificatePoolPath(name)
|
||||
certs, keypairType, err := c.loadCertificates(p, true)
|
||||
certs, err := c.loadCertificates(p, true)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("error in 'FindCert' attempting to load cert %q: %v", name, err)
|
||||
}
|
||||
|
||||
var cert *pki.Certificate
|
||||
if certs != nil && certs.primary != nil {
|
||||
cert = certs.primary.certificate
|
||||
return certs.primary.certificate, certs.format, nil
|
||||
}
|
||||
|
||||
return cert, keypairType, nil
|
||||
return nil, "", nil
|
||||
}
|
||||
|
||||
func (c *VFSCAStore) FindCert(name string) (*pki.Certificate, error) {
|
||||
|
@ -491,7 +497,7 @@ func (c *VFSCAStore) FindCertificatePool(name string) (*CertificatePool, error)
|
|||
|
||||
var err error
|
||||
p := c.buildCertificatePoolPath(name)
|
||||
certs, _, err = c.loadCertificates(p, true)
|
||||
certs, err = c.loadCertificates(p, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in 'FindCertificatePool' attempting to load cert %q: %v", name, err)
|
||||
}
|
||||
|
@ -518,7 +524,7 @@ func (c *VFSCAStore) FindCertificatePool(name string) (*CertificatePool, error)
|
|||
|
||||
func (c *VFSCAStore) FindCertificateKeyset(name string) (*kops.Keyset, error) {
|
||||
p := c.buildCertificatePoolPath(name)
|
||||
certs, _, err := c.loadCertificates(p, true)
|
||||
certs, err := c.loadCertificates(p, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in 'FindCertificatePool' attempting to load cert %q: %v", name, err)
|
||||
}
|
||||
|
@ -815,7 +821,7 @@ func (c *VFSCAStore) loadPrivateKeys(p vfs.Path, useBundle bool) (*keyset, error
|
|||
// give on GCE / other clouds
|
||||
if useBundle {
|
||||
bundlePath := p.Join("keyset.yaml")
|
||||
bundle, _, err := c.loadKeysetBundle(bundlePath)
|
||||
bundle, err := c.loadKeysetBundle(bundlePath)
|
||||
|
||||
if !c.allowList {
|
||||
return bundle, err
|
||||
|
@ -992,7 +998,7 @@ func (c *VFSCAStore) storeCertificate(name string, ki *keysetItem) error {
|
|||
// Write the bundle
|
||||
{
|
||||
p := c.buildCertificatePoolPath(name)
|
||||
ks, _, err := c.loadCertificates(p, false)
|
||||
ks, err := c.loadCertificates(p, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1060,7 +1066,7 @@ func (c *VFSCAStore) deleteCertificate(name string, id string) (bool, error) {
|
|||
// Update the bundle
|
||||
{
|
||||
p := c.buildPrivateKeyPoolPath(name)
|
||||
ks, _, err := c.loadCertificates(p, false)
|
||||
ks, err := c.loadCertificates(p, false)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue