Give nodeup a read-only Keystore

This commit is contained in:
John Gardiner Myers 2022-12-20 09:53:40 -08:00
parent 7abacb9b3b
commit d916596c32
8 changed files with 36 additions and 50 deletions

View File

@ -56,7 +56,7 @@ type NodeupModelContext struct {
Cluster *kops.Cluster
ConfigBase vfs.Path
Distribution distributions.Distribution
KeyStore fi.Keystore
KeyStore fi.KeystoreReader
BootConfig *nodeup.BootConfig
NodeupConfig *nodeup.Config
SecretStore fi.SecretStore

View File

@ -17,18 +17,16 @@ limitations under the License.
package configserver
import (
"crypto/x509"
"fmt"
"k8s.io/kops/pkg/pki"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/util/pkg/vfs"
)
// configserverKeyStore is a KeyStore backed by the config server.
type configserverKeyStore struct{}
func NewKeyStore() fi.CAStore {
func NewKeyStore() fi.KeystoreReader {
return &configserverKeyStore{}
}
@ -41,23 +39,3 @@ func (s *configserverKeyStore) FindPrimaryKeypair(name string) (*pki.Certificate
func (s *configserverKeyStore) FindKeyset(name string) (*fi.Keyset, error) {
return nil, fmt.Errorf("FindKeyset %q not supported by configserverKeyStore", name)
}
// CreateKeypair implements fi.Keystore
func (s *configserverKeyStore) CreateKeypair(signer string, name string, template *x509.Certificate, privateKey *pki.PrivateKey) (*pki.Certificate, error) {
return nil, fmt.Errorf("CreateKeypair not supported by configserverKeyStore")
}
// StoreKeyset implements fi.Keystore
func (s *configserverKeyStore) StoreKeyset(name string, keyset *fi.Keyset) error {
return fmt.Errorf("StoreKeyset not supported by configserverKeyStore")
}
// MirrorTo implements fi.Keystore
func (s *configserverKeyStore) MirrorTo(basedir vfs.Path) error {
return fmt.Errorf("MirrorTo not supported by configserverKeyStore")
}
// ListKeysets implements fi.CAStore
func (s *configserverKeyStore) ListKeysets() (map[string]*fi.Keyset, error) {
return nil, fmt.Errorf("ListKeysets not supported by configserverKeyStore")
}

View File

@ -66,12 +66,18 @@ type KeysetItem struct {
PrivateKey *pki.PrivateKey
}
// Keystore contains just the functions we need to issue keypairs, not to list / manage them
type Keystore interface {
// KeystoreReader contains just the functions we need to consume keypairs, not to update them.
type KeystoreReader interface {
pki.Keystore
// FindKeyset finds a Keyset.
FindKeyset(name string) (*Keyset, error)
}
// Keystore contains just the functions we need to issue keypairs, not to list / manage them
type Keystore interface {
KeystoreReader
// StoreKeyset writes a Keyset to the store.
StoreKeyset(name string, keyset *Keyset) error

View File

@ -33,8 +33,7 @@ import (
type Context[T SubContext] struct {
ctx context.Context
Target Target[T]
Keystore Keystore
Target Target[T]
tasks map[string]Task[T]
warnings []*Warning[T]
@ -55,12 +54,14 @@ type CloudupSubContext struct {
Cluster *kops.Cluster
// TODO: Few places use this. They could instead get it from the cluster spec.
ClusterConfigBase vfs.Path
Keystore Keystore
SecretStore SecretStore
}
type InstallSubContext struct{}
type NodeupSubContext struct {
BootConfig *nodeup.BootConfig
NodeupConfig *nodeup.Config
Keystore KeystoreReader
}
func (c *Context[T]) Context() context.Context {
@ -73,13 +74,12 @@ type Warning[T SubContext] struct {
Message string
}
func newContext[T SubContext](ctx context.Context, target Target[T], keystore Keystore, sub T, tasks map[string]Task[T]) (*Context[T], error) {
func newContext[T SubContext](ctx context.Context, target Target[T], sub T, tasks map[string]Task[T]) (*Context[T], error) {
c := &Context[T]{
ctx: ctx,
Target: target,
Keystore: keystore,
tasks: tasks,
T: sub,
ctx: ctx,
Target: target,
tasks: tasks,
T: sub,
}
return c, nil
@ -87,14 +87,15 @@ func newContext[T SubContext](ctx context.Context, target Target[T], keystore Ke
func NewInstallContext(ctx context.Context, target InstallTarget, tasks map[string]InstallTask) (*InstallContext, error) {
sub := InstallSubContext{}
return newContext[InstallSubContext](ctx, target, nil, sub, tasks)
return newContext[InstallSubContext](ctx, target, sub, tasks)
}
func NewNodeupContext(ctx context.Context, target NodeupTarget, keystore Keystore, bootConfig *nodeup.BootConfig, nodeupConfig *nodeup.Config, tasks map[string]NodeupTask) (*NodeupContext, error) {
func NewNodeupContext(ctx context.Context, target NodeupTarget, keystore KeystoreReader, bootConfig *nodeup.BootConfig, nodeupConfig *nodeup.Config, tasks map[string]NodeupTask) (*NodeupContext, error) {
sub := NodeupSubContext{
BootConfig: bootConfig,
NodeupConfig: nodeupConfig,
Keystore: keystore,
}
return newContext[NodeupSubContext](ctx, target, keystore, sub, tasks)
return newContext[NodeupSubContext](ctx, target, sub, tasks)
}
func NewCloudupContext(ctx context.Context, target CloudupTarget, cluster *kops.Cluster, cloud Cloud, keystore Keystore, secretStore SecretStore, clusterConfigBase vfs.Path, tasks map[string]CloudupTask) (*CloudupContext, error) {
@ -102,9 +103,10 @@ func NewCloudupContext(ctx context.Context, target CloudupTarget, cluster *kops.
Cloud: cloud,
Cluster: cluster,
ClusterConfigBase: clusterConfigBase,
Keystore: keystore,
SecretStore: secretStore,
}
return newContext[CloudupSubContext](ctx, target, keystore, sub, tasks)
return newContext[CloudupSubContext](ctx, target, sub, tasks)
}
func (c *Context[T]) AllTasks() map[string]Task[T] {

View File

@ -74,7 +74,7 @@ func (e *Keypair) Find(c *fi.CloudupContext) (*Keypair, error) {
return nil, nil
}
keyset, err := c.Keystore.FindKeyset(name)
keyset, err := c.T.Keystore.FindKeyset(name)
if err != nil {
return nil, err
}
@ -193,7 +193,7 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error {
if createCertificate {
klog.V(2).Infof("Creating PKI keypair %q", name)
keyset, err := c.Keystore.FindKeyset(name)
keyset, err := c.T.Keystore.FindKeyset(name)
if err != nil {
return err
}
@ -240,7 +240,7 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error {
PrivateKey: privateKey,
Serial: serial,
}
cert, privateKey, _, err := pki.IssueCert(&req, c.Keystore)
cert, privateKey, _, err := pki.IssueCert(&req, c.T.Keystore)
if err != nil {
return err
}
@ -255,7 +255,7 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error {
keyset.LegacyFormat = false
keyset.Items[ki.Id] = ki
keyset.Primary = ki
err = c.Keystore.StoreKeyset(name, keyset)
err = c.T.Keystore.StoreKeyset(name, keyset)
if err != nil {
return err
}
@ -265,7 +265,7 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error {
}
// Make double-sure it round-trips
_, err = c.Keystore.FindKeyset(name)
_, err = c.T.Keystore.FindKeyset(name)
if err != nil {
return err
}
@ -278,12 +278,12 @@ func (_ *Keypair) Render(c *fi.CloudupContext, a, e, changes *Keypair) error {
if changeStoredFormat {
// We fetch and reinsert the same keypair, forcing an update to our preferred format
// TODO: We're assuming that we want to save in the preferred format
keyset, err := c.Keystore.FindKeyset(name)
keyset, err := c.T.Keystore.FindKeyset(name)
if err != nil {
return err
}
keyset.LegacyFormat = false
err = c.Keystore.StoreKeyset(name, keyset)
err = c.T.Keystore.StoreKeyset(name, keyset)
if err != nil {
return err
}

View File

@ -45,7 +45,7 @@ func (e *MirrorKeystore) GetDependencies(tasks map[string]fi.CloudupTask) []fi.C
// Find implements fi.Task::Find
func (e *MirrorKeystore) Find(c *fi.CloudupContext) (*MirrorKeystore, error) {
if vfsKeystore, ok := c.Keystore.(*fi.VFSCAStore); ok {
if vfsKeystore, ok := c.T.Keystore.(*fi.VFSCAStore); ok {
if vfsKeystore.VFSPath().Path() == e.MirrorPath.Path() {
return e, nil
}
@ -73,7 +73,7 @@ func (s *MirrorKeystore) CheckChanges(a, e, changes *MirrorKeystore) error {
// Render implements fi.Task::Render
func (_ *MirrorKeystore) Render(c *fi.CloudupContext, a, e, changes *MirrorKeystore) error {
keystore := c.Keystore
keystore := c.T.Keystore
return keystore.MirrorTo(e.MirrorPath)
}

View File

@ -233,7 +233,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
}
var secretStore fi.SecretStore
var keyStore fi.Keystore
var keyStore fi.KeystoreReader
if nodeConfig != nil {
modelContext.SecretStore = configserver.NewSecretStore(nodeConfig.NodeSecrets)
} else if c.cluster.Spec.SecretStore != "" {

View File

@ -155,7 +155,7 @@ func (e *IssueCert) Run(c *fi.NodeupContext) error {
Validity: time.Hour * time.Duration(validHours),
}
keystore, err := newStaticKeystore(e.Signer, e.KeypairID, c.Keystore)
keystore, err := newStaticKeystore(e.Signer, e.KeypairID, c.T.Keystore)
if err != nil {
return err
}
@ -215,7 +215,7 @@ func (s staticKeystore) FindPrimaryKeypair(name string) (*pki.Certificate, *pki.
return s.certificate, s.key, nil
}
func newStaticKeystore(signer string, keypairID string, keystore fi.Keystore) (pki.Keystore, error) {
func newStaticKeystore(signer string, keypairID string, keystore fi.KeystoreReader) (pki.Keystore, error) {
if signer == "" {
return nil, nil
}