Skip to content

Commit

Permalink
Merge #328
Browse files Browse the repository at this point in the history
328: Avoid materializing default namespace r=mkmik a=mkmik

Closes #323

Co-authored-by: Marko Mikulicic <mkm@bitnami.com>
  • Loading branch information
bors[bot] and Marko Mikulicic authored Dec 2, 2019
2 parents 1049ebc + 68ff559 commit ad6e649
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 12 deletions.
2 changes: 1 addition & 1 deletion cmd/kubeseal/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func seal(in io.Reader, out io.Writer, codecs runtimeserializer.CodecFactory, pu
secret.Namespace = overrideNamespace
}

if secret.GetNamespace() == "" {
if ssv1alpha1.SecretScope(secret) != ssv1alpha1.ClusterWideScope && secret.GetNamespace() == "" {
ns, _, err := namespaceFromClientConfig()
if clientcmd.IsEmptyConfig(err) {
return fmt.Errorf("input secret has no namespace and cannot infer the namespace automatically when no kube config is available")
Expand Down
85 changes: 85 additions & 0 deletions cmd/kubeseal/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,91 @@ func TestSeal(t *testing.T) {
},
},
},
{
secret: v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
},
Data: map[string][]byte{
"foo": []byte("sekret"),
},
},
want: ssv1alpha1.SealedSecret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
Namespace: "default",
},
},
},
{
secret: v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
Namespace: "",
Annotations: map[string]string{
ssv1alpha1.SealedSecretNamespaceWideAnnotation: "true",
},
},
Data: map[string][]byte{
"foo": []byte("sekret"),
},
},
want: ssv1alpha1.SealedSecret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
Namespace: "default",
Annotations: map[string]string{
ssv1alpha1.SealedSecretNamespaceWideAnnotation: "true",
},
},
},
},
{
secret: v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
Namespace: "",
Annotations: map[string]string{
ssv1alpha1.SealedSecretClusterWideAnnotation: "true",
},
},
Data: map[string][]byte{
"foo": []byte("sekret"),
},
},
want: ssv1alpha1.SealedSecret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
Namespace: "", // <--- we shouldn't force the default namespace for cluster wide secrets ...
Annotations: map[string]string{
ssv1alpha1.SealedSecretClusterWideAnnotation: "true",
},
},
},
},
{
secret: v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
Namespace: "myns",
Annotations: map[string]string{
ssv1alpha1.SealedSecretClusterWideAnnotation: "true",
},
},
Data: map[string][]byte{
"foo": []byte("sekret"),
},
},
want: ssv1alpha1.SealedSecret{
ObjectMeta: metav1.ObjectMeta{
Name: "mysecret",
Namespace: "myns", // <--- ... but we should preserve one if specified.
Annotations: map[string]string{
ssv1alpha1.SealedSecretClusterWideAnnotation: "true",
},
},
},
},
}

for i, tc := range testCases {
Expand Down
30 changes: 19 additions & 11 deletions pkg/apis/sealed-secrets/v1alpha1/sealedsecret_expansion.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,33 @@ func EncryptionLabel(namespace, name string, scope SealingScope) []byte {
return []byte(l)
}

func scopeFromLegacy(clusterWide, namespaceWide bool) (SealingScope, bool, bool) {
if clusterWide {
func scopeFromLegacy(o metav1.Object) (SealingScope, bool, bool) {
if o.GetAnnotations()[SealedSecretClusterWideAnnotation] == "true" {
return ClusterWideScope, true, false
}
if namespaceWide {
if o.GetAnnotations()[SealedSecretNamespaceWideAnnotation] == "true" {
return NamespaceWideScope, false, true
}
return StrictScope, false, false
}

// Returns labels followed by clusterWide followed by namespaceWide.
func labelFor(o metav1.Object) ([]byte, bool, bool) {
scope, clusterWide, namespaceWide := scopeFromLegacy(
o.GetAnnotations()[SealedSecretClusterWideAnnotation] == "true",
o.GetAnnotations()[SealedSecretNamespaceWideAnnotation] == "true",
)
scope, clusterWide, namespaceWide := scopeFromLegacy(o)
return EncryptionLabel(o.GetNamespace(), o.GetName(), scope), clusterWide, namespaceWide
}

// SecretScope returns the scope of a secret to be sealed, as annotated in its metadata.
func SecretScope(o metav1.Object) SealingScope {
scope, _, _ := scopeFromLegacy(o)
return scope
}

// Scope returns the scope of the sealed secret, as annotated in its metadata.
func (s *SealedSecret) Scope() SealingScope {
return SecretScope(&s.Spec.Template)
}

// NewSealedSecretV1 creates a new SealedSecret object wrapping the
// provided secret. This encrypts all the secrets into a single encrypted
// blob and stores it in the `Data` attribute. Keeping this for backward
Expand All @@ -118,8 +126,8 @@ func NewSealedSecretV1(codecs runtimeserializer.CodecFactory, pubKey *rsa.Public
return nil, fmt.Errorf("binary can't serialize JSON")
}

if secret.GetNamespace() == "" {
return nil, fmt.Errorf("Secret must declare a namespace")
if SecretScope(secret) != ClusterWideScope && secret.GetNamespace() == "" {
return nil, fmt.Errorf("secret must declare a namespace")
}

codec := codecs.EncoderForVersion(info.Serializer, v1.SchemeGroupVersion)
Expand Down Expand Up @@ -177,8 +185,8 @@ func StripLastAppliedAnnotations(annotations map[string]string) {
// provided secret. This encrypts only the values of each secrets
// individually, so secrets can be updated one by one.
func NewSealedSecret(codecs runtimeserializer.CodecFactory, pubKey *rsa.PublicKey, secret *v1.Secret) (*SealedSecret, error) {
if secret.GetNamespace() == "" {
return nil, fmt.Errorf("Secret must declare a namespace")
if SecretScope(secret) != ClusterWideScope && secret.GetNamespace() == "" {
return nil, fmt.Errorf("secret must declare a namespace")
}

s := &SealedSecret{
Expand Down

0 comments on commit ad6e649

Please sign in to comment.