Skip to content

Commit

Permalink
Refactor StoreKeypair and AddCert
Browse files Browse the repository at this point in the history
  • Loading branch information
johngmyers committed Apr 12, 2021
1 parent 3fdb76e commit 3a61039
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 338 deletions.
15 changes: 14 additions & 1 deletion cmd/kops/create_secret_keypair_ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,20 @@ func RunCreateSecretCaCert(ctx context.Context, f *util.Factory, out io.Writer,
return fmt.Errorf("error loading certificate %q: %v", options.CaCertPath, err)
}

err = keyStore.StoreKeypair(fi.CertificateIDCA, cert, privateKey)
serialString := cert.Certificate.SerialNumber.String()
ki := &fi.KeysetItem{
Id: serialString,
Certificate: cert,
PrivateKey: privateKey,
}

err = keyStore.StoreKeypair(fi.CertificateIDCA, &fi.Keyset{
LegacyFormat: false,
Items: map[string]*fi.KeysetItem{
serialString: ki,
},
Primary: ki,
})
if err != nil {
return fmt.Errorf("error storing user provided keys %q %q: %v", options.CaCertPath, options.CaPrivateKeyPath, err)
}
Expand Down
6 changes: 1 addition & 5 deletions nodeup/pkg/model/fakes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (k fakeKeyStore) CreateKeypair(signer string, name string, template *x509.C
panic("fakeKeyStore does not implement CreateKeypair")
}

func (k fakeKeyStore) StoreKeypair(id string, cert *pki.Certificate, privateKey *pki.PrivateKey) error {
func (k fakeKeyStore) StoreKeypair(id string, keyset *fi.Keyset) error {
panic("fakeKeyStore does not implement StoreKeypair")
}

Expand Down Expand Up @@ -94,10 +94,6 @@ func (k fakeCAStore) ListKeysets() ([]*kops.Keyset, error) {
panic("fakeCAStore does not implement ListKeysets")
}

func (k fakeCAStore) AddCert(name string, cert *pki.Certificate) error {
panic("fakeCAStore does not implement AddCert")
}

func (k fakeCAStore) DeleteKeysetItem(item *kops.Keyset, id string) error {
panic("fakeCAStore does not implement DeleteKeysetItem")
}
7 changes: 1 addition & 6 deletions pkg/configserver/keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (s *configserverKeyStore) CreateKeypair(signer string, name string, templat
}

// StoreKeypair implements fi.Keystore
func (s *configserverKeyStore) StoreKeypair(id string, cert *pki.Certificate, privateKey *pki.PrivateKey) error {
func (s *configserverKeyStore) StoreKeypair(id string, keyset *fi.Keyset) error {
return fmt.Errorf("StoreKeypair not supported by configserverKeyStore")
}

Expand Down Expand Up @@ -109,11 +109,6 @@ func (s *configserverKeyStore) ListKeysets() ([]*kops.Keyset, error) {
return nil, fmt.Errorf("ListKeysets not supported by configserverKeyStore")
}

// AddCert implements fi.CAStore
func (s *configserverKeyStore) AddCert(name string, cert *pki.Certificate) error {
return fmt.Errorf("AddCert not supported by configserverKeyStore")
}

// DeleteKeysetItem implements fi.CAStore
func (s *configserverKeyStore) DeleteKeysetItem(item *kops.Keyset, id string) error {
return fmt.Errorf("DeleteKeysetItem not supported by configserverKeyStore")
Expand Down
8 changes: 4 additions & 4 deletions pkg/kubeconfig/create_kubecfg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ func (f fakeStatusStore) GetApiIngressStatus(cluster *kops.Cluster) ([]kops.ApiI
type fakeKeyStore struct {
FindKeysetFn func(name string) (*fi.Keyset, error)

// StoreKeypair writes the keypair to the store
StoreKeypairFn func(id string, cert *pki.Certificate, privateKey *pki.PrivateKey) error
// StoreKeypair writes the keypair to the store.
StoreKeypairFn func(id string, keyset *fi.Keyset) error

// MirrorTo will copy secrets to a vfs.Path, which is often easier for a machine to read
MirrorToFn func(basedir vfs.Path) error
Expand All @@ -66,8 +66,8 @@ func (f fakeKeyStore) FindKeyset(name string) (*fi.Keyset, error) {
return f.FindKeysetFn(name)
}

func (f fakeKeyStore) StoreKeypair(id string, cert *pki.Certificate, privateKey *pki.PrivateKey) error {
return f.StoreKeypairFn(id, cert, privateKey)
func (f fakeKeyStore) StoreKeypair(id string, keyset *fi.Keyset) error {
return f.StoreKeypairFn(id, keyset)
}

func (f fakeKeyStore) MirrorTo(basedir vfs.Path) error {
Expand Down
1 change: 0 additions & 1 deletion upup/pkg/fi/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 17 additions & 5 deletions upup/pkg/fi/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package fi
import (
"bytes"
"fmt"
"strconv"

"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/pki"
Expand Down Expand Up @@ -65,8 +66,8 @@ type Keystore interface {
// FindKeyset finds a Keyset.
FindKeyset(name string) (*Keyset, error)

// StoreKeypair writes the keypair to the store, making it the primary.
StoreKeypair(id string, cert *pki.Certificate, privateKey *pki.PrivateKey) error
// StoreKeypair writes the keyset to the store.
StoreKeypair(id string, keyset *Keyset) error

// MirrorTo will copy secrets to a vfs.Path, which is often easier for a machine to read
MirrorTo(basedir vfs.Path) error
Expand Down Expand Up @@ -99,9 +100,6 @@ type CAStore interface {
// The key material is not guaranteed to be populated - metadata like the name will be.
ListKeysets() ([]*kops.Keyset, error)

// AddCert adds an alternative certificate to the pool (primarily useful for CAs)
AddCert(name string, cert *pki.Certificate) error

// DeleteKeysetItem will delete the specified item from the Keyset
DeleteKeysetItem(item *kops.Keyset, id string) error
}
Expand Down Expand Up @@ -170,3 +168,17 @@ func FindKeypair(c Keystore, name string) (*pki.Certificate, *pki.PrivateKey, er
}
return keyset.Primary.Certificate, keyset.Primary.PrivateKey, nil
}

// AddCert adds an alternative certificate to the keyset (primarily useful for CAs)
func AddCert(keyset *Keyset, cert *pki.Certificate) {
serial := 0

for keyset.Items[strconv.Itoa(serial)] != nil {
serial++
}

keyset.Items[strconv.Itoa(serial)] = &KeysetItem{
Id: strconv.Itoa(serial),
Certificate: cert,
}
}
83 changes: 34 additions & 49 deletions upup/pkg/fi/clientset_castore.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,25 +258,9 @@ func (c *ClientsetCAStore) ListSSHCredentials() ([]*kops.SSHCredential, error) {
}

// StoreKeypair implements CAStore::StoreKeypair
func (c *ClientsetCAStore) StoreKeypair(name string, cert *pki.Certificate, privateKey *pki.PrivateKey) error {
func (c *ClientsetCAStore) StoreKeypair(name string, keyset *Keyset) error {
ctx := context.TODO()
return c.storeKeypair(ctx, name, cert.Certificate.SerialNumber.String(), cert, privateKey)
}

// AddCert implements CAStore::AddCert
func (c *ClientsetCAStore) AddCert(name string, cert *pki.Certificate) error {
ctx := context.TODO()
klog.Infof("Adding TLS certificate: %q", name)

// We add with a timestamp of zero so this will never be the newest cert
serial := pki.BuildPKISerial(0)

err := c.storeKeypair(ctx, name, serial.String(), cert, nil)
if err != nil {
return err
}

return nil
return c.storeKeyset(ctx, name, keyset, kops.SecretTypeKeypair)
}

// FindPrivateKey implements CAStore::FindPrivateKey
Expand Down Expand Up @@ -306,31 +290,52 @@ func (c *ClientsetCAStore) FindPrivateKeyset(name string) (*kops.Keyset, error)
return o, nil
}

// addKey saves the specified key to the registry
func (c *ClientsetCAStore) addKey(ctx context.Context, name string, keysetType kops.KeysetType, item *kops.KeysetItem) error {
// storeKeyset saves the specified keyset to the registry.
func (c *ClientsetCAStore) storeKeyset(ctx context.Context, name string, keyset *Keyset, keysetType kops.KeysetType) error {
create := false
client := c.clientset.Keysets(c.namespace)
keyset, err := client.Get(ctx, name, metav1.GetOptions{})
kopsKeyset, err := client.Get(ctx, name, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
keyset = nil
kopsKeyset = nil
} else {
return fmt.Errorf("error reading keyset %q: %v", name, err)
}
}
if keyset == nil {
keyset = &kops.Keyset{}
keyset.Name = name
keyset.Spec.Type = keysetType

if kopsKeyset == nil {
kopsKeyset = &kops.Keyset{}
kopsKeyset.Name = name
kopsKeyset.Spec.Type = keysetType
create = true
}
keyset.Spec.Keys = append(keyset.Spec.Keys, *item)

kopsKeyset.Spec.Keys = nil
kopsKeyset.Spec.PrimaryId = keyset.Primary.Id
for _, item := range keyset.Items {
var publicMaterial bytes.Buffer
if _, err := item.Certificate.WriteTo(&publicMaterial); err != nil {
return err
}

var privateMaterial bytes.Buffer
if _, err := item.PrivateKey.WriteTo(&privateMaterial); err != nil {
return err
}

kopsKeyset.Spec.Keys = append(kopsKeyset.Spec.Keys, kops.KeysetItem{
Id: item.Id,
PublicMaterial: publicMaterial.Bytes(),
PrivateMaterial: privateMaterial.Bytes(),
})
}

if create {
if _, err := client.Create(ctx, keyset, metav1.CreateOptions{}); err != nil {
if _, err := client.Create(ctx, kopsKeyset, metav1.CreateOptions{}); err != nil {
return fmt.Errorf("error creating keyset %q: %v", name, err)
}
} else {
if _, err := client.Update(ctx, keyset, metav1.UpdateOptions{}); err != nil {
if _, err := client.Update(ctx, kopsKeyset, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("error updating keyset %q: %v", name, err)
}
}
Expand Down Expand Up @@ -418,26 +423,6 @@ func (c *ClientsetCAStore) deleteSSHCredential(ctx context.Context, name string)
return nil
}

// addKey saves the specified keypair to the registry
func (c *ClientsetCAStore) storeKeypair(ctx context.Context, name string, id string, cert *pki.Certificate, privateKey *pki.PrivateKey) error {
var publicMaterial bytes.Buffer
if _, err := cert.WriteTo(&publicMaterial); err != nil {
return err
}

var privateMaterial bytes.Buffer
if _, err := privateKey.WriteTo(&privateMaterial); err != nil {
return err
}

item := &kops.KeysetItem{
Id: id,
PublicMaterial: publicMaterial.Bytes(),
PrivateMaterial: privateMaterial.Bytes(),
}
return c.addKey(ctx, name, kops.SecretTypeKeypair, item)
}

// AddSSHPublicKey implements CAStore::AddSSHPublicKey
func (c *ClientsetCAStore) AddSSHPublicKey(name string, pubkey []byte) error {
ctx := context.TODO()
Expand Down
19 changes: 17 additions & 2 deletions upup/pkg/fi/fitasks/keypair.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,21 @@ func (_ *Keypair) Render(c *fi.Context, a, e, changes *Keypair) error {
if err != nil {
return err
}
err = c.Keystore.StoreKeypair(name, cert, privateKey)

serialString := cert.Certificate.SerialNumber.String()
ki := &fi.KeysetItem{
Id: serialString,
Certificate: cert,
PrivateKey: privateKey,
}

err = c.Keystore.StoreKeypair(name, &fi.Keyset{
LegacyFormat: false,
Items: map[string]*fi.KeysetItem{
serialString: ki,
},
Primary: ki,
})
if err != nil {
return err
}
Expand All @@ -252,7 +266,8 @@ func (_ *Keypair) Render(c *fi.Context, a, e, changes *Keypair) error {
if err != nil {
return err
}
err = c.Keystore.StoreKeypair(name, keyset.Primary.Certificate, keyset.Primary.PrivateKey)
keyset.LegacyFormat = false
err = c.Keystore.StoreKeypair(name, keyset)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 3a61039

Please sign in to comment.