Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apis/core/v1alpha1/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ type SecretKeyReference struct {
// Key is the key within the secret
Key string `json:"key"`
}

// TlsSecretReference identifies a kubernetes.io/tls Secret without selecting
// a specific data key. The consumer owns the key convention (tls.crt and
// tls.key).
type TlsSecretReference struct {
// Empty JSON tag with "inline" attribute is required to properly inline the
// field in JSON output due to k8s apimachinery constraints.
k8scorev1.SecretReference `json:",inline"`
}
33 changes: 33 additions & 0 deletions apis/core/v1alpha1/secret_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 v1alpha1

import (
"encoding/json"
"strings"
"testing"
)

func TestTlsSecretReferenceDoesNotContainKey(t *testing.T) {
ref := TlsSecretReference{}
ref.Name = "tls-secret"

data, err := json.Marshal(ref)
if err != nil {
t.Fatal(err)
}
if strings.Contains(string(data), `"key"`) {
t.Fatalf("secret reference must not expose a key: %s", data)
}
}
36 changes: 36 additions & 0 deletions apis/core/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions pkg/runtime/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,10 @@ func (r *reconciler) SecretValueFromReference(
return "", ackerr.SecretNotFound
}

// Currently we have only Opaque secrets in scope.
if secret.Type != corev1.SecretTypeOpaque {
// ACK secret references support generic Opaque secrets and the standard
// kubernetes.io/tls Secret type. Callers remain responsible for selecting
// an appropriate data key (for example, tls.crt or tls.key).
if secret.Type != corev1.SecretTypeOpaque && secret.Type != corev1.SecretTypeTLS {
return "", ackerr.SecretTypeNotSupported
}

Expand Down
38 changes: 34 additions & 4 deletions pkg/runtime/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2524,23 +2524,35 @@ func secretReconciler(
return r, apiReader
}

// expectSecretGet wires the mocked apiReader to return an Opaque secret with
// the supplied key/value for a Get against the given namespace/name.
func expectSecretGet(
// expectSecretGet wires the mocked apiReader to return a secret with the
// supplied type and key/value for a Get against the given namespace/name.
func expectSecretGetOfType(
apiReader *ctrlrtclientmock.Reader,
namespace, name, key, value string,
secretType corev1.SecretType,
) {
apiReader.On(
"Get", mock.Anything,
types.NamespacedName{Namespace: namespace, Name: name},
mock.AnythingOfType("*v1.Secret"),
).Run(func(args mock.Arguments) {
secret := args.Get(2).(*corev1.Secret)
secret.Type = corev1.SecretTypeOpaque
secret.Type = secretType
secret.Data = map[string][]byte{key: []byte(value)}
}).Return(nil)
}

func expectSecretGet(
apiReader *ctrlrtclientmock.Reader,
namespace, name, key, value string,
) {
expectSecretGetOfType(
apiReader,
namespace, name, key, value,
corev1.SecretTypeOpaque,
)
}

func ctxWithNamespace(ns string) context.Context {
return context.WithValue(context.Background(), "resourceNamespace", ns)
}
Expand Down Expand Up @@ -2591,6 +2603,24 @@ func TestSecretValueFromReference_ExplicitSameNamespace(t *testing.T) {
assert.Equal(t, "value", val)
}

func TestSecretValueFromReference_TLSSecret(t *testing.T) {
r, apiReader := secretReconciler(false)
ctx := ctxWithNamespace("ns-a")
expectSecretGetOfType(
apiReader,
"ns-a", "sec", corev1.TLSCertKey, "certificate",
corev1.SecretTypeTLS,
)

val, err := r.SecretValueFromReference(
ctx,
newSecretRef("", "sec", corev1.TLSCertKey),
)

require.NoError(t, err)
assert.Equal(t, "certificate", val)
}

func TestSecretValueFromReference_CrossNamespace_FlagDisabled(t *testing.T) {
r, _ := secretReconciler(false)
ctx := ctxWithNamespace("ns-a")
Expand Down