From f328c43295541dd2c855e493abd1e746216f9b24 Mon Sep 17 00:00:00 2001 From: "uday.ruddarraju" Date: Fri, 4 Sep 2020 00:45:09 -0700 Subject: [PATCH] Adding encryption config to airshipctl config Design document: https://docs.google.com/document/d/1EjiCuXoiy8DEEXe15KxVJ4iWrwogCyG113_0LdzcWzQ/edit?usp=drive_web&ouid=102644738301620637153 This patchset comprises of: - airship config now supports encryption configs to store encryption and decryption keys from local file system or the kubernetes api server that will be used to encrypt and decrypt secrets in a future patchset This is the first of multiple patchsets to support encryption and decryption in airshipctl Complete feature: https://review.opendev.org/#/c/742695/ Change-Id: I195e8e254b7cc6b3e04e45d67e0a0e3797183816 --- pkg/config/config.go | 57 ++++++++++++ pkg/config/config_helper.go | 31 +++++++ pkg/config/config_helper_test.go | 56 +++++++++++ pkg/config/config_test.go | 51 +++++++++- pkg/config/context.go | 6 +- pkg/config/encryption_config.go | 49 ++++++++++ pkg/config/encryption_config_test.go | 93 +++++++++++++++++++ pkg/config/errors.go | 46 +++++++++ pkg/config/options.go | 68 ++++++++++++-- pkg/config/testdata/config-string.yaml | 5 + pkg/config/testdata/context-string.yaml | 1 + .../testdata/encryption-config-string.yaml | 2 + testutil/testconfig.go | 27 ++++++ 13 files changed, 478 insertions(+), 14 deletions(-) create mode 100644 pkg/config/encryption_config.go create mode 100644 pkg/config/encryption_config_test.go create mode 100644 pkg/config/testdata/encryption-config-string.yaml diff --git a/pkg/config/config.go b/pkg/config/config.go index b9e98cb2a..7d4995e13 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -62,6 +62,9 @@ type Config struct { // Manifests is a map of referenceable names to documents Manifests map[string]*Manifest `json:"manifests"` + // EncryptionConfigs is a map of referenceable names to encryption configs + EncryptionConfigs map[string]*EncryptionConfig `json:"encryptionConfigs"` + // CurrentContext is the name of the context that you would like to use by default CurrentContext string `json:"currentContext"` @@ -732,6 +735,9 @@ func (c *Config) ModifyContext(context *Context, theContext *ContextOptions) { if theContext.Manifest != "" { context.Manifest = theContext.Manifest } + if theContext.EncryptionConfig != "" { + context.EncryptionConfig = theContext.EncryptionConfig + } if theContext.Namespace != "" { kubeContext.Namespace = theContext.Namespace } @@ -1105,6 +1111,57 @@ func (c *Config) ModifyRepository(repository *Repository, theManifest *ManifestO return nil } +// GetEncryptionConfigs returns all the encryption configs associated with the Config sorted by name +func (c *Config) GetEncryptionConfigs() []*EncryptionConfig { + keys := make([]string, 0, len(c.EncryptionConfigs)) + for name := range c.EncryptionConfigs { + keys = append(keys, name) + } + sort.Strings(keys) + + encryptionConfigs := make([]*EncryptionConfig, 0, len(c.EncryptionConfigs)) + for _, name := range keys { + encryptionConfigs = append(encryptionConfigs, c.EncryptionConfigs[name]) + } + return encryptionConfigs +} + +// AddEncryptionConfig creates a new encryption config +func (c *Config) AddEncryptionConfig(options *EncryptionConfigOptions) *EncryptionConfig { + encryptionConfig := &EncryptionConfig{ + EncryptionKeyFileSource: EncryptionKeyFileSource{ + EncryptionKeyPath: options.EncryptionKeyPath, + DecryptionKeyPath: options.DecryptionKeyPath, + }, + EncryptionKeySecretSource: EncryptionKeySecretSource{ + KeySecretName: options.KeySecretName, + KeySecretNamespace: options.KeySecretNamespace, + }, + } + if c.EncryptionConfigs == nil { + c.EncryptionConfigs = make(map[string]*EncryptionConfig) + } + c.EncryptionConfigs[options.Name] = encryptionConfig + return encryptionConfig +} + +// ModifyEncryptionConfig sets existing values to existing encryption config +func (c *Config) ModifyEncryptionConfig(encryptionConfig *EncryptionConfig, options *EncryptionConfigOptions) { + if options.EncryptionKeyPath != "" { + encryptionConfig.EncryptionKeyPath = options.EncryptionKeyPath + } + if options.DecryptionKeyPath != "" { + encryptionConfig.DecryptionKeyPath = options.DecryptionKeyPath + } + if options.KeySecretName != "" { + encryptionConfig.KeySecretName = options.KeySecretName + } + if options.KeySecretNamespace != "" { + encryptionConfig.KeySecretNamespace = options.KeySecretNamespace + } + return +} + // CurrentContextManagementConfig returns the management options for the current context func (c *Config) CurrentContextManagementConfig() (*ManagementConfiguration, error) { currentCluster, err := c.CurrentContextCluster() diff --git a/pkg/config/config_helper.go b/pkg/config/config_helper.go index eb69191ad..4e9be8193 100644 --- a/pkg/config/config_helper.go +++ b/pkg/config/config_helper.go @@ -197,3 +197,34 @@ func RunSetManifest(o *ManifestOptions, airconfig *Config, writeToStorage bool) return modified, nil } + +// RunSetEncryptionConfig validates the given command line options +// and invokes AddEncryptionConfig/ModifyEncryptionConfig +func RunSetEncryptionConfig(o *EncryptionConfigOptions, airconfig *Config, writeToStorage bool) (bool, error) { + modified := false + err := o.Validate() + if err != nil { + return modified, err + } + + encryptionConfig, exists := airconfig.EncryptionConfigs[o.Name] + if !exists { + // encryption config didn't exist, create it + // ignoring the returned added encryption config + airconfig.AddEncryptionConfig(o) + modified = true + } else { + // encryption config exists, lets update + airconfig.ModifyEncryptionConfig(encryptionConfig, o) + modified = true + } + // Update configuration file just in time persistence approach + if writeToStorage { + if err := airconfig.PersistConfig(false); err != nil { + // Error that it didnt persist the changes + return modified, ErrConfigFailed{} + } + } + + return modified, nil +} diff --git a/pkg/config/config_helper_test.go b/pkg/config/config_helper_test.go index 46e521a1f..6d4272a3a 100644 --- a/pkg/config/config_helper_test.go +++ b/pkg/config/config_helper_test.go @@ -140,3 +140,59 @@ func TestRunSetManifest(t *testing.T) { assert.Equal(t, "/tmp/default", conf.Manifests["dummy_manifest"].TargetPath) }) } + +func TestRunSetEncryptionConfigLocalFile(t *testing.T) { + t.Run("testAddEncryptionConfig", func(t *testing.T) { + conf := testutil.DummyConfig() + dummyEncryptionConfig := testutil.DummyEncryptionConfigOptions() + dummyEncryptionConfig.Name = "test_encryption_config" + + modified, err := config.RunSetEncryptionConfig(dummyEncryptionConfig, conf, false) + assert.Error(t, err) + assert.False(t, modified) + }) + + t.Run("testModifyEncryptionConfig", func(t *testing.T) { + conf := testutil.DummyConfig() + dummyEncryptionConfigOptions := &config.EncryptionConfigOptions{ + Name: "testModifyEncryptionConfig", + EncryptionKeyPath: "testdata/ca.crt", + DecryptionKeyPath: "testdata/test-key.pem", + } + + modified, err := config.RunSetEncryptionConfig(dummyEncryptionConfigOptions, conf, false) + assert.NoError(t, err) + assert.True(t, modified) + assert.Equal(t, "testdata/ca.crt", conf.EncryptionConfigs["testModifyEncryptionConfig"].EncryptionKeyPath) + assert.Equal(t, "testdata/test-key.pem", conf.EncryptionConfigs["testModifyEncryptionConfig"].DecryptionKeyPath) + }) +} + +func TestRunSetEncryptionConfigAPIBackend(t *testing.T) { + t.Run("testAddEncryptionConfig", func(t *testing.T) { + conf := testutil.DummyConfig() + dummyEncryptionConfig := testutil.DummyEncryptionConfigOptions() + dummyEncryptionConfig.Name = "test_encryption_config" + + modified, err := config.RunSetEncryptionConfig(dummyEncryptionConfig, conf, false) + assert.Error(t, err) + assert.False(t, modified) + }) + + t.Run("testModifyEncryptionConfig", func(t *testing.T) { + conf := testutil.DummyConfig() + dummyEncryptionConfigOptions := &config.EncryptionConfigOptions{ + Name: "testModifyEncryptionConfig", + KeySecretName: "dummySecret", + KeySecretNamespace: "dummyNamespace", + EncryptionKeyPath: "", + DecryptionKeyPath: "", + } + + modified, err := config.RunSetEncryptionConfig(dummyEncryptionConfigOptions, conf, false) + assert.NoError(t, err) + assert.True(t, modified) + assert.Equal(t, "dummySecret", conf.EncryptionConfigs["testModifyEncryptionConfig"].KeySecretName) + assert.Equal(t, "dummyNamespace", conf.EncryptionConfigs["testModifyEncryptionConfig"].KeySecretNamespace) + }) +} diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 331725271..8e5fb1bef 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -84,6 +84,10 @@ func TestString(t *testing.T) { name: "managementconfiguration", stringer: testutil.DummyManagementConfiguration(), }, + { + name: "encryption-config", + stringer: testutil.DummyEncryptionConfig(), + }, } for _, tt := range tests { @@ -219,11 +223,12 @@ func TestEnsureComplete(t *testing.T) { { name: "complete config", config: config.Config{ - Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, - AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, - Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, - Manifests: map[string]*config.Manifest{"testManifest": {}}, - CurrentContext: "testContext", + Clusters: map[string]*config.ClusterPurpose{"testCluster": {}}, + AuthInfos: map[string]*config.AuthInfo{"testAuthInfo": {}}, + Contexts: map[string]*config.Context{"testContext": {Manifest: "testManifest"}}, + Manifests: map[string]*config.Manifest{"testManifest": {}}, + EncryptionConfigs: map[string]*config.EncryptionConfig{"testEncryptionConfig": {}}, + CurrentContext: "testContext", }, expectedErr: nil, }, @@ -844,3 +849,39 @@ func TestModifyManifests(t *testing.T) { err = conf.ModifyManifest(manifest, mo) require.Error(t, err) } + +func TestGetDefaultEncryptionConfigs(t *testing.T) { + conf, cleanup := testutil.InitConfig(t) + defer cleanup(t) + + encryptionConfigs := conf.GetEncryptionConfigs() + require.NotNil(t, encryptionConfigs) + // by default, we dont expect any encryption configs + assert.Equal(t, 0, len(encryptionConfigs)) +} + +func TestModifyEncryptionConfigs(t *testing.T) { + conf, cleanup := testutil.InitConfig(t) + defer cleanup(t) + + eco := testutil.DummyEncryptionConfigOptions() + encryptionConfig := conf.AddEncryptionConfig(eco) + require.NotNil(t, encryptionConfig) + + eco.KeySecretName += stringDelta + conf.ModifyEncryptionConfig(encryptionConfig, eco) + modifiedConfig := conf.EncryptionConfigs[eco.Name] + assert.Equal(t, eco.KeySecretName, modifiedConfig.KeySecretName) + + eco.KeySecretNamespace += stringDelta + conf.ModifyEncryptionConfig(encryptionConfig, eco) + assert.Equal(t, eco.KeySecretNamespace, modifiedConfig.KeySecretNamespace) + + eco.EncryptionKeyPath += stringDelta + conf.ModifyEncryptionConfig(encryptionConfig, eco) + assert.Equal(t, eco.EncryptionKeyPath, modifiedConfig.EncryptionKeyPath) + + eco.DecryptionKeyPath += stringDelta + conf.ModifyEncryptionConfig(encryptionConfig, eco) + assert.Equal(t, eco.DecryptionKeyPath, modifiedConfig.DecryptionKeyPath) +} diff --git a/pkg/config/context.go b/pkg/config/context.go index 2d916e0dd..2af9dbd65 100644 --- a/pkg/config/context.go +++ b/pkg/config/context.go @@ -29,10 +29,14 @@ type Context struct { // NameInKubeconf is the Context name in kubeconf NameInKubeconf string `json:"contextKubeconf"` - // Manifest is the default manifest to be use with this context + // Manifest is the default manifest to be used with this context // +optional Manifest string `json:"manifest,omitempty"` + // EncryptionConfig is the default encryption config to be used with this context + // +optional + EncryptionConfig string `json:"encryptionConfig,omitempty"` + // KubeConfig Context Object context *api.Context } diff --git a/pkg/config/encryption_config.go b/pkg/config/encryption_config.go new file mode 100644 index 000000000..aab3527e3 --- /dev/null +++ b/pkg/config/encryption_config.go @@ -0,0 +1,49 @@ +/* +Copyright 2014 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 config + +import "sigs.k8s.io/yaml" + +// EncryptionConfig holds the public and private key information +// used to encrypt and decrypt secrets +type EncryptionConfig struct { + EncryptionKeyFileSource `json:",inline"` + EncryptionKeySecretSource `json:",inline"` +} + +// EncryptionKeyFileSource hold the local file information for the public and private +// keys used for encryption and decryption +type EncryptionKeyFileSource struct { + EncryptionKeyPath string `json:"encryptionKeyPath,omitempty"` + DecryptionKeyPath string `json:"decryptionKeyPath,omitempty"` +} + +// EncryptionKeySecretSource holds the secret information for the public and private +// keys used for encryption and decryption +type EncryptionKeySecretSource struct { + KeySecretName string `json:"keySecretName,omitempty"` + KeySecretNamespace string `json:"keySecretNamespace,omitempty"` +} + +// String returns the encryption config in yaml format +func (ec *EncryptionConfig) String() string { + yamlData, err := yaml.Marshal(&ec) + if err != nil { + return "" + } + return string(yamlData) +} diff --git a/pkg/config/encryption_config_test.go b/pkg/config/encryption_config_test.go new file mode 100644 index 000000000..1b14b9729 --- /dev/null +++ b/pkg/config/encryption_config_test.go @@ -0,0 +1,93 @@ +/* +Copyright 2014 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 config + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEncryptionConfigOutputString(t *testing.T) { + expectedEncryptionConfigYaml := `decryptionKeyPath: /tmp/decryption.pub +encryptionKeyPath: /tmp/encryption.key +` + encryptionConfig := &EncryptionConfig{ + EncryptionKeyFileSource: EncryptionKeyFileSource{ + EncryptionKeyPath: "/tmp/encryption.key", + DecryptionKeyPath: "/tmp/decryption.pub", + }, + } + + assert.Equal(t, expectedEncryptionConfigYaml, encryptionConfig.String()) +} + +func TestValidateEncryptionConfigInvalid(t *testing.T) { + encryptionConfig := &EncryptionConfigOptions{} + err := encryptionConfig.Validate() + assert.Error(t, err) +} + +func TestValidateEncryptionConfigInvalidOnlyEncKey(t *testing.T) { + encryptionConfig := &EncryptionConfigOptions{ + EncryptionKeyPath: "/tmp/encryption.key", + } + err := encryptionConfig.Validate() + assert.Error(t, err) +} + +func TestValidateEncryptionConfigInvalidOnlyDecKey(t *testing.T) { + encryptionConfig := &EncryptionConfigOptions{ + DecryptionKeyPath: "/tmp/decryption.pub", + } + err := encryptionConfig.Validate() + assert.Error(t, err) +} + +func TestValidateEncryptionConfigInvalidOnlySecretName(t *testing.T) { + encryptionConfig := &EncryptionConfigOptions{ + KeySecretName: "secretName", + } + err := encryptionConfig.Validate() + assert.Error(t, err) +} + +func TestValidateEncryptionConfigInvalidOnlySecretNamespace(t *testing.T) { + encryptionConfig := &EncryptionConfigOptions{ + KeySecretNamespace: "secretNamespace", + } + err := encryptionConfig.Validate() + assert.Error(t, err) +} + +func TestValidateEncryptionConfigValidWithSecret(t *testing.T) { + encryptionConfig := &EncryptionConfigOptions{ + KeySecretName: "secretName", + KeySecretNamespace: "secretNamespace", + } + err := encryptionConfig.Validate() + assert.Error(t, err) +} + +func TestValidateEncryptionConfigValidWithFile(t *testing.T) { + encryptionConfig := &EncryptionConfigOptions{ + EncryptionKeyPath: "/tmp/encryption.key", + DecryptionKeyPath: "/tmp/decryption.pub", + } + err := encryptionConfig.Validate() + assert.Error(t, err) +} diff --git a/pkg/config/errors.go b/pkg/config/errors.go index 2339b72db..c910ac05b 100644 --- a/pkg/config/errors.go +++ b/pkg/config/errors.go @@ -143,6 +143,16 @@ func (e ErrManagementConfigurationNotFound) Error() string { return fmt.Sprintf("Unknown management configuration '%s'.", e.Name) } +// ErrEncryptionConfigurationNotFound describes a situation in which a user has attempted to reference an encryption +// configuration that cannot be referenced. +type ErrEncryptionConfigurationNotFound struct { + Name string +} + +func (e ErrEncryptionConfigurationNotFound) Error() string { + return fmt.Sprintf("Unknown encryption configuration '%s'.", e.Name) +} + // ErrMissingCurrentContext returned in case --current used without setting current-context type ErrMissingCurrentContext struct { } @@ -248,6 +258,42 @@ func (e ErrMissingManifestName) Error() string { return "missing manifest name" } +// ErrMissingEncryptionConfigName is returned when encryption config name is empty +type ErrMissingEncryptionConfigName struct { +} + +func (e ErrMissingEncryptionConfigName) Error() string { + return "missing encryption config name" +} + +// ErrMutuallyExclusiveEncryptionConfigType is returned when encryption config specifies both +// local key files and secret information for keys stored as secrets in the apiserver +type ErrMutuallyExclusiveEncryptionConfigType struct { +} + +func (e ErrMutuallyExclusiveEncryptionConfigType) Error() string { + return "Specify mutually exclusive encryption config sources, use either: " + + "--decryption-key-path/--decryption-key-path or --secret-name/--secret-namespace." +} + +// ErrInvalidEncryptionKeyPath is returned when encryption config specifies only one of +// encryption and decryption keys +type ErrInvalidEncryptionKeyPath struct { +} + +func (e ErrInvalidEncryptionKeyPath) Error() string { + return "Specify both encryption and decryption keys when setting encryption config" +} + +// ErrInvalidEncryptionKey is returned when encryption config specifies only one of +// encryption keys secret name and namespace +type ErrInvalidEncryptionKey struct { +} + +func (e ErrInvalidEncryptionKey) Error() string { + return "Specify both secret name and namespace when setting encryption config" +} + // ErrMissingFlag is returned when flag is not provided type ErrMissingFlag struct { FlagName string diff --git a/pkg/config/options.go b/pkg/config/options.go index 356098d87..f3e0913f4 100644 --- a/pkg/config/options.go +++ b/pkg/config/options.go @@ -36,14 +36,15 @@ type AuthInfoOptions struct { // ContextOptions holds all configurable options for context type ContextOptions struct { - Name string - ClusterType string - CurrentContext bool - Cluster string - AuthInfo string - Manifest string - Namespace string - Current bool + Name string + ClusterType string + CurrentContext bool + Cluster string + AuthInfo string + Manifest string + EncryptionConfig string + Namespace string + Current bool } // ClusterOptions holds all configurable options for cluster configuration @@ -71,6 +72,15 @@ type ManifestOptions struct { TargetPath string } +// EncryptionConfigOptions holds all configurable options for encryption configuration +type EncryptionConfigOptions struct { + Name string + EncryptionKeyPath string + DecryptionKeyPath string + KeySecretName string + KeySecretNamespace string +} + // TODO(howell): The following functions are tightly coupled with flags passed // on the command line. We should find a way to remove this coupling, since it // is possible to create (and validate) these objects without using the command @@ -195,3 +205,45 @@ func (o *ManifestOptions) Validate() error { } return nil } + +// Validate checks for the possible errors with encryption config +// Error when invalid value, incompatible choice of values given or if the +// key file paths do not exist in the file system +func (o *EncryptionConfigOptions) Validate() error { + switch { + case o.Name == "": + return ErrMissingEncryptionConfigName{} + + case o.backedByFileSystem() == o.backedByAPIServer(): + return ErrMutuallyExclusiveEncryptionConfigType{} + + case o.backedByFileSystem(): + if o.EncryptionKeyPath == "" || o.DecryptionKeyPath == "" { + return ErrInvalidEncryptionKeyPath{} + } + + case o.backedByAPIServer(): + if o.KeySecretName == "" || o.KeySecretNamespace == "" { + return ErrInvalidEncryptionKey{} + } + } + + if o.backedByFileSystem() { + if err := checkExists("encryption-key-path", o.EncryptionKeyPath); err != nil { + return err + } + if err := checkExists("decryption-key-path", o.EncryptionKeyPath); err != nil { + return err + } + } + + return nil +} + +func (o EncryptionConfigOptions) backedByFileSystem() bool { + return o.EncryptionKeyPath != "" || o.DecryptionKeyPath != "" +} + +func (o EncryptionConfigOptions) backedByAPIServer() bool { + return o.KeySecretName != "" || o.KeySecretNamespace != "" +} diff --git a/pkg/config/testdata/config-string.yaml b/pkg/config/testdata/config-string.yaml index b4a3a65a7..5fcd1f976 100644 --- a/pkg/config/testdata/config-string.yaml +++ b/pkg/config/testdata/config-string.yaml @@ -11,8 +11,13 @@ clusters: contexts: dummy_context: contextKubeconf: dummy_cluster_ephemeral + encryptionConfig: dummy_encryption_config manifest: dummy_manifest currentContext: dummy_context +encryptionConfigs: + dummy_encryption_config: + decryptionKeyPath: /tmp/decryption.pub + encryptionKeyPath: /tmp/encryption.key kind: Config managementConfiguration: dummy_management_config: diff --git a/pkg/config/testdata/context-string.yaml b/pkg/config/testdata/context-string.yaml index 0f0c5975a..60b77d672 100644 --- a/pkg/config/testdata/context-string.yaml +++ b/pkg/config/testdata/context-string.yaml @@ -1,4 +1,5 @@ contextKubeconf: dummy_cluster_ephemeral +encryptionConfig: dummy_encryption_config manifest: dummy_manifest LocationOfOrigin: "" diff --git a/pkg/config/testdata/encryption-config-string.yaml b/pkg/config/testdata/encryption-config-string.yaml new file mode 100644 index 000000000..461287a2d --- /dev/null +++ b/pkg/config/testdata/encryption-config-string.yaml @@ -0,0 +1,2 @@ +decryptionKeyPath: /tmp/decryption.pub +encryptionKeyPath: /tmp/encryption.key diff --git a/testutil/testconfig.go b/testutil/testconfig.go index 44428242b..81b950d98 100644 --- a/testutil/testconfig.go +++ b/testutil/testconfig.go @@ -55,6 +55,9 @@ func DummyConfig() *config.Config { ManagementConfiguration: map[string]*config.ManagementConfiguration{ "dummy_management_config": DummyManagementConfiguration(), }, + EncryptionConfigs: map[string]*config.EncryptionConfig{ + "dummy_encryption_config": DummyEncryptionConfig(), + }, CurrentContext: "dummy_context", } conf.SetKubeConfig(kubeconfig.NewConfig()) @@ -74,6 +77,7 @@ func DummyContext() *config.Context { context.Namespace = "dummy_namespace" context.AuthInfo = "dummy_user" context.Cluster = "dummy_cluster_ephemeral" + c.EncryptionConfig = "dummy_encryption_config" c.SetKubeContext(context) return c @@ -207,6 +211,7 @@ func DummyContextOptions() *config.ContextOptions { co.AuthInfo = "dummy_user" co.CurrentContext = false co.Namespace = "dummy_namespace" + co.EncryptionConfig = "dummy_encryption_config" return co } @@ -223,6 +228,27 @@ func DummyAuthInfoOptions() *config.AuthInfoOptions { return authinfo } +// DummyEncryptionConfig creates EncryptionConfigOptions object +// for unit testing +func DummyEncryptionConfig() *config.EncryptionConfig { + return &config.EncryptionConfig{ + EncryptionKeyFileSource: config.EncryptionKeyFileSource{ + EncryptionKeyPath: "/tmp/encryption.key", + DecryptionKeyPath: "/tmp/decryption.pub", + }, + } +} + +// DummyEncryptionConfigOptions creates ManifestOptions config object +// for unit testing +func DummyEncryptionConfigOptions() *config.EncryptionConfigOptions { + return &config.EncryptionConfigOptions{ + Name: "dummy_encryption_config", + EncryptionKeyPath: "/tmp/encryption.key", + DecryptionKeyPath: "/tmp/decryption.pub", + } +} + // DummyManagementConfiguration creates a management configuration for unit testing func DummyManagementConfiguration() *config.ManagementConfiguration { return &config.ManagementConfiguration{ @@ -281,6 +307,7 @@ contexts: contextKubeconf: def_target onlyink: contextKubeconf: onlyinkubeconf_target +encryptionConfigs: {} currentContext: "" kind: Config manifests: {}