ContainerImage.Pinniped/internal/controller/supervisorconfig/generator/secret_helper_test.go
2021-01-07 15:25:47 -08:00

224 lines
6.5 KiB
Go

// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package generator
import (
"strings"
"testing"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
configv1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/config/v1alpha1"
)
const keyWith32Bytes = "0123456789abcdef0123456789abcdef"
func TestSymmetricSecretHelper(t *testing.T) {
t.Parallel()
tests := []struct {
name string
secretUsage SecretUsage
wantSecretType corev1.SecretType
wantSetFederationDomainField func(*configv1alpha1.FederationDomain) string
}{
{
name: "token signing key",
secretUsage: SecretUsageTokenSigningKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-token-signing-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.TokenSigningKey.Name
},
},
{
name: "state signing key",
secretUsage: SecretUsageStateSigningKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-state-signing-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateSigningKey.Name
},
},
{
name: "state encryption key",
secretUsage: SecretUsageStateEncryptionKey,
wantSecretType: "secrets.pinniped.dev/federation-domain-state-encryption-key",
wantSetFederationDomainField: func(federationDomain *configv1alpha1.FederationDomain) string {
return federationDomain.Status.Secrets.StateEncryptionKey.Name
},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
labels := map[string]string{
"some-label-key-1": "some-label-value-1",
"some-label-key-2": "some-label-value-2",
}
randSource := strings.NewReader(keyWith32Bytes)
var federationDomainIssuerValue string
var symmetricKeyValue []byte
h := NewSymmetricSecretHelper(
"some-name-prefix-",
labels,
randSource,
test.secretUsage,
func(federationDomainIssuer string, symmetricKey []byte) {
require.True(t, federationDomainIssuer == "" && symmetricKeyValue == nil, "expected notify func not to have been called yet")
federationDomainIssuerValue = federationDomainIssuer
symmetricKeyValue = symmetricKey
},
)
parent := &configv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
UID: "some-uid",
Namespace: "some-namespace",
},
}
child, err := h.Generate(parent)
require.NoError(t, err)
require.Equal(t, child, &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "some-name-prefix-some-uid",
Namespace: "some-namespace",
Labels: labels,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
}),
},
},
Type: test.wantSecretType,
Data: map[string][]byte{
"key": []byte(keyWith32Bytes),
},
})
require.True(t, h.IsValid(parent, child))
h.ObserveActiveSecretAndUpdateParentFederationDomain(parent, child)
require.Equal(t, parent.Spec.Issuer, federationDomainIssuerValue)
require.Equal(t, child.Name, test.wantSetFederationDomainField(parent))
require.Equal(t, child.Data["key"], symmetricKeyValue)
require.True(t, h.Handles(child))
wrongTypedChild := child.DeepCopy()
wrongTypedChild.Type = "the-wrong-type"
require.False(t, h.Handles(wrongTypedChild))
wrongOwnerKindChild := child.DeepCopy()
wrongOwnerKindChild.OwnerReferences[0].Kind = "WrongKind"
require.False(t, h.Handles(wrongOwnerKindChild))
})
}
}
func TestSymmetricSecretHelperIsValid(t *testing.T) {
tests := []struct {
name string
secretUsage SecretUsage
child func(*corev1.Secret)
parent func(*configv1alpha1.FederationDomain)
want bool
}{
{
name: "wrong type",
secretUsage: SecretUsageTokenSigningKey,
child: func(s *corev1.Secret) {
s.Type = "wrong"
},
want: false,
},
{
name: "empty type",
secretUsage: SecretUsageTokenSigningKey,
child: func(s *corev1.Secret) {
s.Type = ""
},
want: false,
},
{
name: "data key is too short",
secretUsage: SecretUsageTokenSigningKey,
child: func(s *corev1.Secret) {
s.Type = FederationDomainTokenSigningKeyType
s.Data["key"] = []byte("short")
},
want: false,
},
{
name: "data key does not exist",
secretUsage: SecretUsageTokenSigningKey,
child: func(s *corev1.Secret) {
s.Type = FederationDomainTokenSigningKeyType
delete(s.Data, "key")
},
want: false,
},
{
name: "child not owned by parent",
secretUsage: SecretUsageTokenSigningKey,
child: func(s *corev1.Secret) {
s.Type = FederationDomainTokenSigningKeyType
},
parent: func(federationDomain *configv1alpha1.FederationDomain) {
federationDomain.UID = "wrong"
},
want: false,
},
{
name: "happy path",
secretUsage: SecretUsageTokenSigningKey,
child: func(s *corev1.Secret) {
s.Type = FederationDomainTokenSigningKeyType
}, want: true,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
h := NewSymmetricSecretHelper("none of these args matter", nil, nil, test.secretUsage, nil)
parent := &configv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{
Name: "some-parent-name",
Namespace: "some-namespace",
UID: "some-parent-uid",
},
}
child := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "some-name-prefix-some-uid",
Namespace: "some-namespace",
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(parent, schema.GroupVersionKind{
Group: configv1alpha1.SchemeGroupVersion.Group,
Version: configv1alpha1.SchemeGroupVersion.Version,
Kind: "FederationDomain",
}),
},
},
Type: "invalid default",
Data: map[string][]byte{
"key": []byte(keyWith32Bytes),
},
}
if test.child != nil {
test.child(child)
}
if test.parent != nil {
test.parent(parent)
}
require.Equalf(t, test.want, h.IsValid(parent, child), "child: %#v", child)
})
}
}