diff --git a/nodeup/pkg/model/context.go b/nodeup/pkg/model/context.go index b1466b4c8f..560a40eca3 100644 --- a/nodeup/pkg/model/context.go +++ b/nodeup/pkg/model/context.go @@ -60,7 +60,7 @@ type NodeupModelContext struct { KeyStore fi.KeystoreReader BootConfig *nodeup.BootConfig NodeupConfig *nodeup.Config - SecretStore fi.SecretStore + SecretStore fi.SecretStoreReader // IsMaster is true if the InstanceGroup has a role of master (populated by Init) IsMaster bool diff --git a/pkg/configserver/secretstore.go b/pkg/configserver/secretstore.go index 641717995b..f79faf52df 100644 --- a/pkg/configserver/secretstore.go +++ b/pkg/configserver/secretstore.go @@ -17,11 +17,9 @@ limitations under the License. package configserver import ( - "context" "fmt" "k8s.io/kops/upup/pkg/fi" - "k8s.io/kops/util/pkg/vfs" ) // configserverSecretStore is a SecretStore backed by the config server. @@ -29,13 +27,13 @@ type configserverSecretStore struct { nodeSecrets map[string][]byte } -func NewSecretStore(nodeSecrets map[string][]byte) fi.SecretStore { +func NewSecretStore(nodeSecrets map[string][]byte) fi.SecretStoreReader { return &configserverSecretStore{ nodeSecrets: nodeSecrets, } } -// Secret implements fi.SecretStore +// Secret implements fi.SecretStoreReader func (s *configserverSecretStore) Secret(id string) (*fi.Secret, error) { secret, err := s.FindSecret(id) if err != nil { @@ -47,12 +45,7 @@ func (s *configserverSecretStore) Secret(id string) (*fi.Secret, error) { return secret, nil } -// DeleteSecret implements fi.SecretStore -func (s *configserverSecretStore) DeleteSecret(id string) error { - return fmt.Errorf("DeleteSecret not supported by configserverSecretStore") -} - -// FindSecret implements fi.SecretStore +// FindSecret implements fi.SecretStoreReader func (s *configserverSecretStore) FindSecret(id string) (*fi.Secret, error) { secretBytes, ok := s.nodeSecrets[id] if !ok { @@ -63,23 +56,3 @@ func (s *configserverSecretStore) FindSecret(id string) (*fi.Secret, error) { } return secret, nil } - -// GetOrCreateSecret implements fi.SecretStore -func (s *configserverSecretStore) GetOrCreateSecret(ctx context.Context, id string, secret *fi.Secret) (current *fi.Secret, created bool, err error) { - return nil, false, fmt.Errorf("GetOrCreateSecret not supported by configserverSecretStore") -} - -// ReplaceSecret implements fi.SecretStore -func (s *configserverSecretStore) ReplaceSecret(id string, secret *fi.Secret) (current *fi.Secret, err error) { - return nil, fmt.Errorf("ReplaceSecret not supported by configserverSecretStore") -} - -// ListSecrets implements fi.SecretStore -func (s *configserverSecretStore) ListSecrets() ([]string, error) { - return nil, fmt.Errorf("ListSecrets not supported by configserverSecretStore") -} - -// MirrorTo implements fi.SecretStore -func (s *configserverSecretStore) MirrorTo(ctx context.Context, basedir vfs.Path) error { - return fmt.Errorf("MirrorTo not supported by configserverSecretStore") -} diff --git a/upup/pkg/fi/nodeup/command.go b/upup/pkg/fi/nodeup/command.go index 301f251d05..00e1e0154f 100644 --- a/upup/pkg/fi/nodeup/command.go +++ b/upup/pkg/fi/nodeup/command.go @@ -227,7 +227,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error { NodeupConfig: &nodeupConfig, } - var secretStore fi.SecretStore + var secretStore fi.SecretStoreReader var keyStore fi.KeystoreReader if nodeConfig != nil { modelContext.SecretStore = configserver.NewSecretStore(nodeConfig.NodeSecrets) @@ -238,7 +238,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error { return fmt.Errorf("error building secret store path: %v", err) } - secretStore = secrets.NewVFSSecretStore(c.cluster, p) + secretStore = secrets.NewVFSSecretStoreReader(p) modelContext.SecretStore = secretStore } else { return fmt.Errorf("SecretStore not set") diff --git a/upup/pkg/fi/secrets.go b/upup/pkg/fi/secrets.go index 38f8976557..440e390868 100644 --- a/upup/pkg/fi/secrets.go +++ b/upup/pkg/fi/secrets.go @@ -26,13 +26,17 @@ import ( "k8s.io/kops/util/pkg/vfs" ) -type SecretStore interface { +type SecretStoreReader interface { // Secret returns a secret. Returns an error if not found Secret(id string) (*Secret, error) - // DeleteSecret deletes the specified secret - DeleteSecret(id string) error // FindSecret finds a secret, if exists. Returns nil,nil if not found FindSecret(id string) (*Secret, error) +} + +type SecretStore interface { + SecretStoreReader + // DeleteSecret deletes the specified secret + DeleteSecret(id string) error // GetOrCreateSecret creates a secret GetOrCreateSecret(ctx context.Context, id string, secret *Secret) (current *Secret, created bool, err error) // ReplaceSecret will forcefully update an existing secret if it exists diff --git a/upup/pkg/fi/secrets/vfs_secretstore.go b/upup/pkg/fi/secrets/vfs_secretstore.go index ea8643c8b3..95d5e574ed 100644 --- a/upup/pkg/fi/secrets/vfs_secretstore.go +++ b/upup/pkg/fi/secrets/vfs_secretstore.go @@ -31,24 +31,22 @@ import ( ) type VFSSecretStore struct { + VFSSecretStoreReader cluster *kops.Cluster - basedir vfs.Path } var _ fi.SecretStore = &VFSSecretStore{} func NewVFSSecretStore(cluster *kops.Cluster, basedir vfs.Path) fi.SecretStore { c := &VFSSecretStore{ + VFSSecretStoreReader: VFSSecretStoreReader{ + basedir: basedir, + }, cluster: cluster, - basedir: basedir, } return c } -func (c *VFSSecretStore) VFSPath() vfs.Path { - return c.basedir -} - func (c *VFSSecretStore) MirrorTo(ctx context.Context, basedir vfs.Path) error { if basedir.Path() == c.basedir.Path() { klog.V(2).Infof("Skipping mirror of secret store from %q to %q (same path)", c.basedir, basedir) @@ -89,25 +87,6 @@ func (c *VFSSecretStore) MirrorTo(ctx context.Context, basedir vfs.Path) error { return nil } -func BuildVfsSecretPath(basedir vfs.Path, name string) vfs.Path { - return basedir.Join(name) -} - -func (c *VFSSecretStore) buildSecretPath(name string) vfs.Path { - return BuildVfsSecretPath(c.basedir, name) -} - -func (c *VFSSecretStore) FindSecret(id string) (*fi.Secret, error) { - ctx := context.TODO() - - p := c.buildSecretPath(id) - s, err := c.loadSecret(ctx, p) - if err != nil { - return nil, err - } - return s, nil -} - // DeleteSecret implements fi.SecretStore DeleteSecret func (c *VFSSecretStore) DeleteSecret(name string) error { p := c.buildSecretPath(name) @@ -130,17 +109,6 @@ func (c *VFSSecretStore) ListSecrets() ([]string, error) { return ids, nil } -func (c *VFSSecretStore) Secret(id string) (*fi.Secret, error) { - s, err := c.FindSecret(id) - if err != nil { - return nil, err - } - if s == nil { - return nil, fmt.Errorf("secret %q not found", id) - } - return s, nil -} - func (c *VFSSecretStore) GetOrCreateSecret(ctx context.Context, id string, secret *fi.Secret) (*fi.Secret, bool, error) { p := c.buildSecretPath(id) @@ -206,21 +174,6 @@ func (c *VFSSecretStore) ReplaceSecret(id string, secret *fi.Secret) (*fi.Secret return s, nil } -func (c *VFSSecretStore) loadSecret(ctx context.Context, p vfs.Path) (*fi.Secret, error) { - data, err := p.ReadFile(ctx) - if err != nil { - if os.IsNotExist(err) { - return nil, nil - } - } - s := &fi.Secret{} - err = json.Unmarshal(data, s) - if err != nil { - return nil, fmt.Errorf("error parsing secret from %q: %v", p, err) - } - return s, nil -} - // createSecret will create the Secret, overwriting an existing secret if replace is true func createSecret(ctx context.Context, s *fi.Secret, p vfs.Path, acl vfs.ACL, replace bool) error { data, err := json.Marshal(s) diff --git a/upup/pkg/fi/secrets/vfs_secretstorereader.go b/upup/pkg/fi/secrets/vfs_secretstorereader.go new file mode 100644 index 0000000000..3cb8edc589 --- /dev/null +++ b/upup/pkg/fi/secrets/vfs_secretstorereader.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package secrets + +import ( + "context" + "encoding/json" + "fmt" + "os" + + "k8s.io/kops/upup/pkg/fi" + "k8s.io/kops/util/pkg/vfs" +) + +type VFSSecretStoreReader struct { + basedir vfs.Path +} + +var _ fi.SecretStoreReader = &VFSSecretStoreReader{} + +func NewVFSSecretStoreReader(basedir vfs.Path) fi.SecretStoreReader { + c := &VFSSecretStoreReader{ + basedir: basedir, + } + return c +} + +func (c *VFSSecretStoreReader) VFSPath() vfs.Path { + return c.basedir +} + +func BuildVfsSecretPath(basedir vfs.Path, name string) vfs.Path { + return basedir.Join(name) +} + +func (c *VFSSecretStoreReader) buildSecretPath(name string) vfs.Path { + return BuildVfsSecretPath(c.basedir, name) +} + +func (c *VFSSecretStoreReader) FindSecret(id string) (*fi.Secret, error) { + ctx := context.TODO() + + p := c.buildSecretPath(id) + s, err := c.loadSecret(ctx, p) + if err != nil { + return nil, err + } + return s, nil +} + +func (c *VFSSecretStoreReader) Secret(id string) (*fi.Secret, error) { + s, err := c.FindSecret(id) + if err != nil { + return nil, err + } + if s == nil { + return nil, fmt.Errorf("secret %q not found", id) + } + return s, nil +} + +func (c *VFSSecretStoreReader) loadSecret(ctx context.Context, p vfs.Path) (*fi.Secret, error) { + data, err := p.ReadFile(ctx) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } + } + s := &fi.Secret{} + err = json.Unmarshal(data, s) + if err != nil { + return nil, fmt.Errorf("parsing secret from %q: %v", p, err) + } + return s, nil +}