Introduce kubeapiserver.config.k8s.io/v1 with EncryptionConfiguration and use a standard method for parsing config file.

Co-authored-by: Stanislav Laznicka <slaznick@redhat.com>
This commit is contained in:
Slava Semushin 2018-05-02 18:21:38 +02:00 committed by Stanislav Laznicka
parent e0ce8478b2
commit c21cb548e6
No known key found for this signature in database
GPG Key ID: C98C414936B1A7F3
11 changed files with 365 additions and 80 deletions

View File

@ -216,8 +216,8 @@ fi
ENCRYPTION_PROVIDER_CONFIG="${ENCRYPTION_PROVIDER_CONFIG:-}" ENCRYPTION_PROVIDER_CONFIG="${ENCRYPTION_PROVIDER_CONFIG:-}"
if [[ -z "${ENCRYPTION_PROVIDER_CONFIG}" ]]; then if [[ -z "${ENCRYPTION_PROVIDER_CONFIG}" ]]; then
ENCRYPTION_PROVIDER_CONFIG=$(cat << EOM | base64 | tr -d '\r\n' ENCRYPTION_PROVIDER_CONFIG=$(cat << EOM | base64 | tr -d '\r\n'
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets

View File

@ -0,0 +1,53 @@
/*
Copyright 2018 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 (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
var (
// SchemeBuilder points to a list of functions added to Scheme.
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
// AddToScheme adds this group to a scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
// GroupName is the group name use in this package.
const GroupName = "apiserver.config.k8s.io"
// SchemeGroupVersion is group version used to register these objects.
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns a Group qualified GroupKind.
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource.
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
func addKnownTypes(scheme *runtime.Scheme) error {
// TODO this will get cleaned up with the scheme types are fixed
scheme.AddKnownTypes(SchemeGroupVersion,
&EncryptionConfiguration{},
)
return nil
}

View File

@ -56,3 +56,71 @@ type DebuggingConfiguration struct {
// enableProfiling is true. // enableProfiling is true.
EnableContentionProfiling bool EnableContentionProfiling bool
} }
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// EncryptionConfiguration stores the complete configuration for encryption providers.
type EncryptionConfiguration struct {
metav1.TypeMeta
// resources is a list containing resources, and their corresponding encryption providers.
Resources []ResourceConfiguration
}
// ResourceConfiguration stores per resource configuration.
type ResourceConfiguration struct {
// resources is a list of kubernetes resources which have to be encrypted.
Resources []string
// providers is a list of transformers to be used for reading and writing the resources to disk.
// eg: aesgcm, aescbc, secretbox, identity.
Providers []ProviderConfiguration
}
// ProviderConfiguration stores the provided configuration for an encryption provider.
type ProviderConfiguration struct {
// aesgcm is the configuration for the AES-GCM transformer.
AESGCM *AESConfiguration
// aescbc is the configuration for the AES-CBC transformer.
AESCBC *AESConfiguration
// secretbox is the configuration for the Secretbox based transformer.
Secretbox *SecretboxConfiguration
// identity is the (empty) configuration for the identity transformer.
Identity *IdentityConfiguration
// kms contains the name, cache size and path to configuration file for a KMS based envelope transformer.
KMS *KMSConfiguration
}
// AESConfiguration contains the API configuration for an AES transformer.
type AESConfiguration struct {
// keys is a list of keys to be used for creating the AES transformer.
// Each key has to be 32 bytes long for AES-CBC and 16, 24 or 32 bytes for AES-GCM.
Keys []Key
}
// SecretboxConfiguration contains the API configuration for an Secretbox transformer.
type SecretboxConfiguration struct {
// keys is a list of keys to be used for creating the Secretbox transformer.
// Each key has to be 32 bytes long.
Keys []Key
}
// Key contains name and secret of the provided key for a transformer.
type Key struct {
// name is the name of the key to be used while storing data to disk.
Name string
// secret is the actual key, encoded in base64.
Secret string
}
// IdentityConfiguration is an empty struct to allow identity transformer in provider configuration.
type IdentityConfiguration struct{}
// KMSConfiguration contains the name, cache size and path to configuration file for a KMS based envelope transformer.
type KMSConfiguration struct {
// name is the name of the KMS plugin to be used.
Name string
// cacheSize is the maximum number of secrets which are cached in memory. The default value is 1000.
// +optional
CacheSize int32
// endpoint is the gRPC server listening address, for example "unix:///var/run/kms-provider.sock".
Endpoint string
}

View File

@ -0,0 +1,23 @@
/*
Copyright 2018 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.
*/
// +k8s:conversion-gen=k8s.io/apiserver/pkg/apis/config
// +k8s:deepcopy-gen=package
// +k8s:defaulter-gen=TypeMeta
// +groupName=apiserver.config.k8s.io
// Package v1 is the v1 version of the API.
package v1

View File

@ -0,0 +1,52 @@
/*
Copyright 2018 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 v1
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package.
const GroupName = "apiserver.config.k8s.io"
// SchemeGroupVersion is group version used to register these objects.
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
var (
// SchemeBuilder points to a list of functions added to Scheme.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
// AddToScheme adds this group to a scheme.
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes)
}
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&EncryptionConfiguration{},
)
// also register into the v1 group as EncryptionConfig (due to a docs bug)
scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "EncryptionConfig"}, &EncryptionConfiguration{})
return nil
}

View File

@ -14,50 +14,51 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package encryptionconfig package v1
// EncryptionConfig stores the complete configuration for encryption providers. import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
type EncryptionConfig struct {
// kind is the type of configuration file. // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Kind string `json:"kind"`
// apiVersion is the API version this file has to be parsed as. // EncryptionConfiguration stores the complete configuration for encryption providers.
APIVersion string `json:"apiVersion"` type EncryptionConfiguration struct {
metav1.TypeMeta
// resources is a list containing resources, and their corresponding encryption providers. // resources is a list containing resources, and their corresponding encryption providers.
Resources []ResourceConfig `json:"resources"` Resources []ResourceConfiguration `json:"resources"`
} }
// ResourceConfig stores per resource configuration. // ResourceConfiguration stores per resource configuration.
type ResourceConfig struct { type ResourceConfiguration struct {
// resources is a list of kubernetes resources which have to be encrypted. // resources is a list of kubernetes resources which have to be encrypted.
Resources []string `json:"resources"` Resources []string `json:"resources"`
// providers is a list of transformers to be used for reading and writing the resources to disk. // providers is a list of transformers to be used for reading and writing the resources to disk.
// eg: aesgcm, aescbc, secretbox, identity. // eg: aesgcm, aescbc, secretbox, identity.
Providers []ProviderConfig `json:"providers"` Providers []ProviderConfiguration `json:"providers"`
} }
// ProviderConfig stores the provided configuration for an encryption provider. // ProviderConfiguration stores the provided configuration for an encryption provider.
type ProviderConfig struct { type ProviderConfiguration struct {
// aesgcm is the configuration for the AES-GCM transformer. // aesgcm is the configuration for the AES-GCM transformer.
AESGCM *AESConfig `json:"aesgcm,omitempty"` AESGCM *AESConfiguration `json:"aesgcm,omitempty"`
// aescbc is the configuration for the AES-CBC transformer. // aescbc is the configuration for the AES-CBC transformer.
AESCBC *AESConfig `json:"aescbc,omitempty"` AESCBC *AESConfiguration `json:"aescbc,omitempty"`
// secretbox is the configuration for the Secretbox based transformer. // secretbox is the configuration for the Secretbox based transformer.
Secretbox *SecretboxConfig `json:"secretbox,omitempty"` Secretbox *SecretboxConfiguration `json:"secretbox,omitempty"`
// identity is the (empty) configuration for the identity transformer. // identity is the (empty) configuration for the identity transformer.
Identity *IdentityConfig `json:"identity,omitempty"` Identity *IdentityConfiguration `json:"identity,omitempty"`
// kms contains the name, cache size and path to configuration file for a KMS based envelope transformer. // kms contains the name, cache size and path to configuration file for a KMS based envelope transformer.
KMS *KMSConfig `json:"kms,omitempty"` KMS *KMSConfiguration `json:"kms,omitempty"`
} }
// AESConfig contains the API configuration for an AES transformer. // AESConfiguration contains the API configuration for an AES transformer.
type AESConfig struct { type AESConfiguration struct {
// keys is a list of keys to be used for creating the AES transformer. // keys is a list of keys to be used for creating the AES transformer.
// Each key has to be 32 bytes long for AES-CBC and 16, 24 or 32 bytes for AES-GCM. // Each key has to be 32 bytes long for AES-CBC and 16, 24 or 32 bytes for AES-GCM.
Keys []Key `json:"keys"` Keys []Key `json:"keys"`
} }
// SecretboxConfig contains the API configuration for an Secretbox transformer. // SecretboxConfiguration contains the API configuration for an Secretbox transformer.
type SecretboxConfig struct { type SecretboxConfiguration struct {
// keys is a list of keys to be used for creating the Secretbox transformer. // keys is a list of keys to be used for creating the Secretbox transformer.
// Each key has to be 32 bytes long. // Each key has to be 32 bytes long.
Keys []Key `json:"keys"` Keys []Key `json:"keys"`
@ -71,16 +72,16 @@ type Key struct {
Secret string `json:"secret"` Secret string `json:"secret"`
} }
// IdentityConfig is an empty struct to allow identity transformer in provider configuration. // IdentityConfiguration is an empty struct to allow identity transformer in provider configuration.
type IdentityConfig struct{} type IdentityConfiguration struct{}
// KMSConfig contains the name, cache size and path to configuration file for a KMS based envelope transformer. // KMSConfiguration contains the name, cache size and path to configuration file for a KMS based envelope transformer.
type KMSConfig struct { type KMSConfiguration struct {
// name is the name of the KMS plugin to be used. // name is the name of the KMS plugin to be used.
Name string `json:"name"` Name string `json:"name"`
// cacheSize is the maximum number of secrets which are cached in memory. The default value is 1000. // cacheSize is the maximum number of secrets which are cached in memory. The default value is 1000.
// +optional // +optional
CacheSize int `json:"cachesize,omitempty"` CacheSize int32 `json:"cachesize,omitempty"`
// the gRPC server listening address, for example "unix:///var/run/kms-provider.sock". // endpoint is the gRPC server listening address, for example "unix:///var/run/kms-provider.sock".
Endpoint string `json:"endpoint"` Endpoint string `json:"endpoint"`
} }

View File

@ -26,9 +26,11 @@ import (
"os" "os"
"time" "time"
yaml "sigs.k8s.io/yaml" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
apiserverconfig "k8s.io/apiserver/pkg/apis/config"
apiserverconfigv1 "k8s.io/apiserver/pkg/apis/config/v1"
"k8s.io/apiserver/pkg/storage/value" "k8s.io/apiserver/pkg/storage/value"
aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes"
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope"
@ -66,20 +68,11 @@ func ParseEncryptionConfiguration(f io.Reader) (map[schema.GroupResource]value.T
return nil, fmt.Errorf("could not read contents: %v", err) return nil, fmt.Errorf("could not read contents: %v", err)
} }
var config EncryptionConfig config, err := loadConfig(configFileContents)
err = yaml.Unmarshal(configFileContents, &config)
if err != nil { if err != nil {
return nil, fmt.Errorf("error while parsing file: %v", err) return nil, fmt.Errorf("error while parsing file: %v", err)
} }
if config.Kind == "" {
return nil, fmt.Errorf("invalid configuration file, missing Kind")
}
if config.Kind != "EncryptionConfig" {
return nil, fmt.Errorf("invalid configuration kind %q provided", config.Kind)
}
// TODO config.APIVersion is unchecked
resourceToPrefixTransformer := map[schema.GroupResource][]value.PrefixTransformer{} resourceToPrefixTransformer := map[schema.GroupResource][]value.PrefixTransformer{}
// For each entry in the configuration // For each entry in the configuration
@ -102,13 +95,32 @@ func ParseEncryptionConfiguration(f io.Reader) (map[schema.GroupResource]value.T
result[gr] = value.NewMutableTransformer(value.NewPrefixTransformers(fmt.Errorf("no matching prefix found"), transList...)) result[gr] = value.NewMutableTransformer(value.NewPrefixTransformers(fmt.Errorf("no matching prefix found"), transList...))
} }
return result, nil return result, nil
}
// loadConfig decodes data as a EncryptionConfiguration object.
func loadConfig(data []byte) (*apiserverconfig.EncryptionConfiguration, error) {
scheme := runtime.NewScheme()
codecs := serializer.NewCodecFactory(scheme)
apiserverconfig.AddToScheme(scheme)
apiserverconfigv1.AddToScheme(scheme)
configObj, gvk, err := codecs.UniversalDecoder().Decode(data, nil, nil)
if err != nil {
return nil, err
}
config, ok := configObj.(*apiserverconfig.EncryptionConfiguration)
if !ok {
return nil, fmt.Errorf("got unexpected config type: %v", gvk)
}
return config, nil
} }
// The factory to create kms service. This is to make writing test easier. // The factory to create kms service. This is to make writing test easier.
var envelopeServiceFactory = envelope.NewGRPCService var envelopeServiceFactory = envelope.NewGRPCService
// GetPrefixTransformers constructs and returns the appropriate prefix transformers for the passed resource using its configuration // GetPrefixTransformers constructs and returns the appropriate prefix transformers for the passed resource using its configuration.
func GetPrefixTransformers(config *ResourceConfig) ([]value.PrefixTransformer, error) { func GetPrefixTransformers(config *apiserverconfig.ResourceConfiguration) ([]value.PrefixTransformer, error) {
var result []value.PrefixTransformer var result []value.PrefixTransformer
for _, provider := range config.Providers { for _, provider := range config.Providers {
found := false found := false
@ -188,7 +200,7 @@ type BlockTransformerFunc func(cipher.Block) value.Transformer
// GetAESPrefixTransformer returns a prefix transformer from the provided configuration. // GetAESPrefixTransformer returns a prefix transformer from the provided configuration.
// Returns an AES transformer based on the provided prefix and block transformer. // Returns an AES transformer based on the provided prefix and block transformer.
func GetAESPrefixTransformer(config *AESConfig, fn BlockTransformerFunc, prefix string) (value.PrefixTransformer, error) { func GetAESPrefixTransformer(config *apiserverconfig.AESConfiguration, fn BlockTransformerFunc, prefix string) (value.PrefixTransformer, error) {
var result value.PrefixTransformer var result value.PrefixTransformer
if len(config.Keys) == 0 { if len(config.Keys) == 0 {
@ -236,7 +248,7 @@ func GetAESPrefixTransformer(config *AESConfig, fn BlockTransformerFunc, prefix
} }
// GetSecretboxPrefixTransformer returns a prefix transformer from the provided configuration // GetSecretboxPrefixTransformer returns a prefix transformer from the provided configuration
func GetSecretboxPrefixTransformer(config *SecretboxConfig) (value.PrefixTransformer, error) { func GetSecretboxPrefixTransformer(config *apiserverconfig.SecretboxConfiguration) (value.PrefixTransformer, error) {
var result value.PrefixTransformer var result value.PrefixTransformer
if len(config.Keys) == 0 { if len(config.Keys) == 0 {
@ -288,8 +300,8 @@ func GetSecretboxPrefixTransformer(config *SecretboxConfig) (value.PrefixTransfo
// getEnvelopePrefixTransformer returns a prefix transformer from the provided config. // getEnvelopePrefixTransformer returns a prefix transformer from the provided config.
// envelopeService is used as the root of trust. // envelopeService is used as the root of trust.
func getEnvelopePrefixTransformer(config *KMSConfig, envelopeService envelope.Service, prefix string) (value.PrefixTransformer, error) { func getEnvelopePrefixTransformer(config *apiserverconfig.KMSConfiguration, envelopeService envelope.Service, prefix string) (value.PrefixTransformer, error) {
envelopeTransformer, err := envelope.NewEnvelopeTransformer(envelopeService, config.CacheSize, aestransformer.NewCBCTransformer) envelopeTransformer, err := envelope.NewEnvelopeTransformer(envelopeService, int(config.CacheSize), aestransformer.NewCBCTransformer)
if err != nil { if err != nil {
return value.PrefixTransformer{}, err return value.PrefixTransformer{}, err
} }

View File

@ -19,11 +19,14 @@ package encryptionconfig
import ( import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"reflect"
"strings" "strings"
"testing" "testing"
"time" "time"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff"
apiserverconfig "k8s.io/apiserver/pkg/apis/config"
"k8s.io/apiserver/pkg/storage/value" "k8s.io/apiserver/pkg/storage/value"
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope"
) )
@ -33,9 +36,40 @@ const (
sampleContextText = "0123456789" sampleContextText = "0123456789"
legacyV1Config = `
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
- namespaces
providers:
- identity: {}
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- kms:
name: testprovider
endpoint: unix:///tmp/testprovider.sock
cachesize: 10
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
`
correctConfigWithIdentityFirst = ` correctConfigWithIdentityFirst = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -65,8 +99,8 @@ resources:
` `
correctConfigWithAesGcmFirst = ` correctConfigWithAesGcmFirst = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -95,8 +129,8 @@ resources:
` `
correctConfigWithAesCbcFirst = ` correctConfigWithAesCbcFirst = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -125,8 +159,8 @@ resources:
` `
correctConfigWithSecretboxFirst = ` correctConfigWithSecretboxFirst = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -155,8 +189,8 @@ resources:
` `
correctConfigWithKMSFirst = ` correctConfigWithKMSFirst = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -185,8 +219,8 @@ resources:
` `
incorrectConfigNoSecretForKey = ` incorrectConfigNoSecretForKey = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- namespaces - namespaces
@ -198,8 +232,8 @@ resources:
` `
incorrectConfigInvalidKey = ` incorrectConfigInvalidKey = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- namespaces - namespaces
@ -214,8 +248,8 @@ resources:
` `
incorrectConfigNoEndpointForKMS = ` incorrectConfigNoEndpointForKMS = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -244,6 +278,48 @@ func newMockEnvelopeService(endpoint string, timeout time.Duration) (envelope.Se
return &testEnvelopeService{}, nil return &testEnvelopeService{}, nil
} }
func TestLegacyConfig(t *testing.T) {
legacyConfigObject, err := loadConfig([]byte(legacyV1Config))
if err != nil {
t.Fatalf("error while parsing configuration file: %s.\nThe file was:\n%s", err, legacyV1Config)
}
expected := &apiserverconfig.EncryptionConfiguration{
Resources: []apiserverconfig.ResourceConfiguration{
{
Resources: []string{"secrets", "namespaces"},
Providers: []apiserverconfig.ProviderConfiguration{
{Identity: &apiserverconfig.IdentityConfiguration{}},
{AESGCM: &apiserverconfig.AESConfiguration{
Keys: []apiserverconfig.Key{
{Name: "key1", Secret: "c2VjcmV0IGlzIHNlY3VyZQ=="},
{Name: "key2", Secret: "dGhpcyBpcyBwYXNzd29yZA=="},
},
}},
{KMS: &apiserverconfig.KMSConfiguration{
Name: "testprovider",
Endpoint: "unix:///tmp/testprovider.sock",
CacheSize: 10,
}},
{AESCBC: &apiserverconfig.AESConfiguration{
Keys: []apiserverconfig.Key{
{Name: "key1", Secret: "c2VjcmV0IGlzIHNlY3VyZQ=="},
{Name: "key2", Secret: "dGhpcyBpcyBwYXNzd29yZA=="},
},
}},
{Secretbox: &apiserverconfig.SecretboxConfiguration{
Keys: []apiserverconfig.Key{
{Name: "key1", Secret: "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY="},
},
}},
},
},
},
}
if !reflect.DeepEqual(legacyConfigObject, expected) {
t.Fatal(diff.ObjectReflectDiff(expected, legacyConfigObject))
}
}
func TestEncryptionProviderConfigCorrect(t *testing.T) { func TestEncryptionProviderConfigCorrect(t *testing.T) {
// Set factory for mock envelope service // Set factory for mock envelope service
factory := envelopeServiceFactory factory := envelopeServiceFactory

View File

@ -39,8 +39,8 @@ const (
dekKeySizeLen = 2 dekKeySizeLen = 2
kmsConfigYAML = ` kmsConfigYAML = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets

View File

@ -23,7 +23,7 @@ import (
"fmt" "fmt"
"testing" "testing"
"k8s.io/apiserver/pkg/server/options/encryptionconfig" apiserverconfigv1 "k8s.io/apiserver/pkg/apis/config/v1"
"k8s.io/apiserver/pkg/storage/value" "k8s.io/apiserver/pkg/storage/value"
aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes"
) )
@ -33,8 +33,8 @@ const (
aesCBCPrefix = "k8s:enc:aescbc:v1:key1:" aesCBCPrefix = "k8s:enc:aescbc:v1:key1:"
aesGCMConfigYAML = ` aesGCMConfigYAML = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -46,8 +46,8 @@ resources:
` `
aesCBCConfigYAML = ` aesCBCConfigYAML = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -59,8 +59,8 @@ resources:
` `
identityConfigYAML = ` identityConfigYAML = `
kind: EncryptionConfig kind: EncryptionConfiguration
apiVersion: v1 apiVersion: apiserver.config.k8s.io/v1
resources: resources:
- resources: - resources:
- secrets - secrets
@ -72,7 +72,7 @@ resources:
// TestSecretsShouldBeEnveloped is an integration test between KubeAPI and etcd that checks: // TestSecretsShouldBeEnveloped is an integration test between KubeAPI and etcd that checks:
// 1. Secrets are encrypted on write // 1. Secrets are encrypted on write
// 2. Secrets are decrypted on read // 2. Secrets are decrypted on read
// when EncryptionConfig is passed to KubeAPI server. // when EncryptionConfiguration is passed to KubeAPI server.
func TestSecretsShouldBeTransformed(t *testing.T) { func TestSecretsShouldBeTransformed(t *testing.T) {
var testCases = []struct { var testCases = []struct {
transformerConfigContent string transformerConfigContent string
@ -128,7 +128,7 @@ func runBenchmark(b *testing.B, transformerConfig string) {
} }
func unSealWithGCMTransformer(cipherText []byte, ctx value.Context, func unSealWithGCMTransformer(cipherText []byte, ctx value.Context,
transformerConfig encryptionconfig.ProviderConfig) ([]byte, error) { transformerConfig apiserverconfigv1.ProviderConfiguration) ([]byte, error) {
block, err := newAESCipher(transformerConfig.AESGCM.Keys[0].Secret) block, err := newAESCipher(transformerConfig.AESGCM.Keys[0].Secret)
if err != nil { if err != nil {
@ -146,7 +146,7 @@ func unSealWithGCMTransformer(cipherText []byte, ctx value.Context,
} }
func unSealWithCBCTransformer(cipherText []byte, ctx value.Context, func unSealWithCBCTransformer(cipherText []byte, ctx value.Context,
transformerConfig encryptionconfig.ProviderConfig) ([]byte, error) { transformerConfig apiserverconfigv1.ProviderConfiguration) ([]byte, error) {
block, err := newAESCipher(transformerConfig.AESCBC.Keys[0].Secret) block, err := newAESCipher(transformerConfig.AESCBC.Keys[0].Secret)
if err != nil { if err != nil {

View File

@ -33,7 +33,7 @@ import (
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/server/options/encryptionconfig" apiserverconfigv1 "k8s.io/apiserver/pkg/apis/config/v1"
"k8s.io/apiserver/pkg/storage/storagebackend" "k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/apiserver/pkg/storage/value" "k8s.io/apiserver/pkg/storage/value"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
@ -51,7 +51,7 @@ const (
metricsPrefix = "apiserver_storage_" metricsPrefix = "apiserver_storage_"
) )
type unSealSecret func(cipherText []byte, ctx value.Context, config encryptionconfig.ProviderConfig) ([]byte, error) type unSealSecret func(cipherText []byte, ctx value.Context, config apiserverconfigv1.ProviderConfiguration) ([]byte, error)
type transformTest struct { type transformTest struct {
logger kubeapiservertesting.Logger logger kubeapiservertesting.Logger
@ -186,8 +186,8 @@ func (e *transformTest) createEncryptionConfig() (string, error) {
return tempDir, nil return tempDir, nil
} }
func (e *transformTest) getEncryptionConfig() (*encryptionconfig.ProviderConfig, error) { func (e *transformTest) getEncryptionConfig() (*apiserverconfigv1.ProviderConfiguration, error) {
var config encryptionconfig.EncryptionConfig var config apiserverconfigv1.EncryptionConfiguration
err := yaml.Unmarshal([]byte(e.transformerConfig), &config) err := yaml.Unmarshal([]byte(e.transformerConfig), &config)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to extract transformer key: %v", err) return nil, fmt.Errorf("failed to extract transformer key: %v", err)