Skip to content

Commit

Permalink
secrets synced with syncAll/syncOptions.syncAll are now delete on pod…
Browse files Browse the repository at this point in the history
… deletion via ownerReference
  • Loading branch information
manedurphy committed Aug 15, 2021
1 parent c9b40d8 commit 5ba6d82
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 39 deletions.
19 changes: 15 additions & 4 deletions controllers/secretproviderclasspodstatus_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (r *SecretProviderClassPodStatusReconciler) Patcher(ctx context.Context) er
}

spcPodStatuses := spcPodStatusList.Items
for i := range spcPodStatuses {
for i, spcPodStatus := range spcPodStatuses {
spcName := spcPodStatuses[i].Status.SecretProviderClassName
spc := &v1alpha1.SecretProviderClass{}
namespace := spcPodStatuses[i].Namespace
Expand All @@ -140,6 +140,7 @@ func (r *SecretProviderClassPodStatusReconciler) Patcher(ctx context.Context) er
if err != nil {
return fmt.Errorf("failed to fetch pod during patching, err: %+v", err)
}

var ownerRefs []metav1.OwnerReference
for _, ownerRef := range pod.GetOwnerReferences() {
ownerRefs = append(ownerRefs, metav1.OwnerReference{
Expand All @@ -149,6 +150,7 @@ func (r *SecretProviderClassPodStatusReconciler) Patcher(ctx context.Context) er
Name: ownerRef.Name,
})
}

// If a pod has no owner references, then it's a static pod and
// doesn't belong to a replicaset. In this case, use the spcps as
// owner reference just like we do it today
Expand All @@ -167,6 +169,15 @@ func (r *SecretProviderClassPodStatusReconciler) Patcher(ctx context.Context) er
ownerRefs = append(ownerRefs, ref)
}

if spc.Spec.SyncOptions.SyncAll {
files, err := fileutil.GetMountedFiles(spcPodStatus.Status.TargetPath)
if err != nil {
klog.ErrorS(err, "failed to get mounted files", "spc", klog.KObj(spc), "pod", klog.KObj(pod), "spcps", klog.KObj(&spcPodStatus))
} else {
spc.Spec.SecretObjects = spcutil.BuildSecretObjects(files, secretutil.GetSecretType(strings.TrimSpace(spc.Spec.SyncOptions.Type)))
}
}

for _, secret := range spc.Spec.SecretObjects {
key := types.NamespacedName{Name: secret.SecretName, Namespace: namespace}
val, exists := secretOwnerMap[key]
Expand Down Expand Up @@ -286,13 +297,13 @@ func (r *SecretProviderClassPodStatusReconciler) Reconcile(ctx context.Context,
files, err := fileutil.GetMountedFiles(spcPodStatus.Status.TargetPath)

if spc.Spec.SyncOptions.SyncAll {
spc.Spec.SecretObjects = spcutil.BuildSecretObjects(files, spc.Spec.SyncOptions.Type)
spc.Spec.SecretObjects = spcutil.BuildSecretObjects(files, secretutil.GetSecretType(strings.TrimSpace(spc.Spec.SyncOptions.Type)))
}

for _, secretObj := range spc.Spec.SecretObjects {
if secretObj.SyncAll {
if secretutil.GetSecretType(strings.TrimSpace(secretObj.Type)) != corev1.SecretTypeOpaque && secretutil.GetSecretType(strings.TrimSpace(secretObj.Type)) != corev1.SecretTypeBasicAuth {
return ctrl.Result{}, fmt.Errorf("secret provider class %s/%s cannot use syncAll for non-opaque secrets", spc.Namespace, spc.Name)
if secretutil.GetSecretType(strings.TrimSpace(secretObj.Type)) != corev1.SecretTypeOpaque {
return ctrl.Result{}, fmt.Errorf("secret provider class %s/%s cannot use secretObjects[*].syncAll for non-opaque secrets", spc.Namespace, spc.Name)
}

spcutil.BuildSecretObjectData(files, secretObj)
Expand Down
4 changes: 2 additions & 2 deletions pkg/rotation/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,13 @@ func (r *Reconciler) reconcile(ctx context.Context, spcps *v1alpha1.SecretProvid
files, err := fileutil.GetMountedFiles(spcps.Status.TargetPath)

if spc.Spec.SyncOptions.SyncAll {
spc.Spec.SecretObjects = spcutil.BuildSecretObjects(files, spc.Spec.SyncOptions.Type)
spc.Spec.SecretObjects = spcutil.BuildSecretObjects(files, secretutil.GetSecretType(strings.TrimSpace(spc.Spec.SyncOptions.Type)))
}

for _, secretObj := range spc.Spec.SecretObjects {
if secretObj.SyncAll {
if secretutil.GetSecretType(strings.TrimSpace(secretObj.Type)) != v1.SecretTypeOpaque {
return fmt.Errorf("secret provider class %s/%s cannot use syncAll for non-opaque secrets", spc.Namespace, spc.Name)
return fmt.Errorf("secret provider class %s/%s cannot use secretObjects[*].syncAll for non-opaque secrets", spc.Namespace, spc.Name)
}

spcutil.BuildSecretObjectData(files, secretObj)
Expand Down
6 changes: 4 additions & 2 deletions pkg/util/secretutil/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const (
privateKeyType = "PRIVATE KEY"
privateKeyTypeRSA = "RSA PRIVATE KEY"
privateKeyTypeEC = "EC PRIVATE KEY"
basicAuthUsername = "username"
basicAuthPassword = "password"
)

// getCertPart returns the certificate or the private key part of the cert
Expand Down Expand Up @@ -207,8 +209,8 @@ func GetSecretData(secretObjData []*v1alpha1.SecretObjectData, secretType corev1
credentials := getCredentials(content)
delete(datamap, dataKey)

datamap["username"] = []byte(credentials.Username)
datamap["password"] = []byte(credentials.Password)
datamap[basicAuthUsername] = []byte(credentials.Username)
datamap[basicAuthPassword] = []byte(credentials.Password)
}
}
return datamap, nil
Expand Down
93 changes: 63 additions & 30 deletions pkg/util/spcutil/secret_object_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,24 @@ import (

corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/secrets-store-csi-driver/apis/v1alpha1"
"sigs.k8s.io/secrets-store-csi-driver/pkg/util/secretutil"
)

const (
tlsKey = "tls.key"
tlsCert = "tls.crt"
dockerConfigJsonKey = ".dockerconfigjson"
basicAuthUsername = "username"
basicAuthPassword = "password"
sshPrivateKey = "ssh-privatekey"
)

// builds the data field of a SecretObject when syncAll is true
// BuildSecretObjectData builds the .Spec.SecretObjects[*].Data list of a SecretObject when SyncAll is true
func BuildSecretObjectData(files map[string]string, secretObj *v1alpha1.SecretObject) {

for key := range files {
nested := strings.Split(key, "/")
var renamedKey string

if len(nested) > 0 {
renamedKey = strings.Join(nested, "_")
renamedKey = strings.Join(nested, "-")
}

if renamedKey == "" {
Expand All @@ -42,21 +40,24 @@ func BuildSecretObjectData(files map[string]string, secretObj *v1alpha1.SecretOb
}
}

func BuildSecretObjects(files map[string]string, secretType string) []*v1alpha1.SecretObject {
// BuildSecretObjects build the .Spec.SecretObjects list of a SecretProviderClass with .SyncOptions.SyncAll is true
func BuildSecretObjects(files map[string]string, secretType corev1.SecretType) []*v1alpha1.SecretObject {
secretObjects := []*v1alpha1.SecretObject{}

var secretObject *v1alpha1.SecretObject
for key := range files {

switch {
case secretutil.GetSecretType(strings.TrimSpace(secretType)) == corev1.SecretTypeOpaque:
secretObject = buildOpaqueSecretDataObject(key, secretType)
case secretutil.GetSecretType(strings.TrimSpace(secretType)) == corev1.SecretTypeTLS:
secretObject = buildTLSSecretDataObject(key, secretType)
case secretutil.GetSecretType(strings.TrimSpace(secretType)) == corev1.SecretTypeDockerConfigJson:
secretObject = buildDockerConfigJsonSecretDataObject(key, secretType)
case secretutil.GetSecretType(strings.TrimSpace(secretType)) == corev1.SecretTypeBasicAuth:
secretObject = buildBasicAuthSecretDataObject(key, secretType)
switch secretType {
case corev1.SecretTypeOpaque:
secretObject = createOpaqueSecretDataObject(key)
case corev1.SecretTypeTLS:
secretObject = createTLSSecretDataObject(key)
case corev1.SecretTypeDockerConfigJson:
secretObject = createDockerConfigJsonSecretDataObject(key)
case corev1.SecretTypeBasicAuth:
secretObject = createBasicAuthSecretDataObject(key)
case corev1.SecretTypeSSHAuth:
secretObject = createSSHSecretDataObject(key)
}

secretObjects = append(secretObjects, secretObject)
Expand All @@ -65,23 +66,23 @@ func BuildSecretObjects(files map[string]string, secretType string) []*v1alpha1.
return secretObjects
}

func buildOpaqueSecretDataObject(key string, secretType string) *v1alpha1.SecretObject {
func createOpaqueSecretDataObject(key string) *v1alpha1.SecretObject {
return &v1alpha1.SecretObject{
SecretName: key,
Type: secretType,
SecretName: setSecretName(key),
Type: string(corev1.SecretTypeOpaque),
Data: []*v1alpha1.SecretObjectData{
{
ObjectName: key,
Key: key,
Key: setKey(key),
},
},
}
}

func buildTLSSecretDataObject(key string, secretType string) *v1alpha1.SecretObject {
func createTLSSecretDataObject(key string) *v1alpha1.SecretObject {
return &v1alpha1.SecretObject{
SecretName: key,
Type: secretType,
SecretName: setSecretName(key),
Type: string(corev1.SecretTypeTLS),
Data: []*v1alpha1.SecretObjectData{
{
ObjectName: key,
Expand All @@ -95,29 +96,61 @@ func buildTLSSecretDataObject(key string, secretType string) *v1alpha1.SecretObj
}
}

func buildDockerConfigJsonSecretDataObject(key string, secretType string) *v1alpha1.SecretObject {
func createDockerConfigJsonSecretDataObject(key string) *v1alpha1.SecretObject {
return &v1alpha1.SecretObject{
SecretName: key,
Type: secretType,
SecretName: setSecretName(key),
Type: string(corev1.SecretTypeDockerConfigJson),
Data: []*v1alpha1.SecretObjectData{
{
ObjectName: key,
ObjectName: setKey(key),
Key: dockerConfigJsonKey,
},
},
}
}

func buildBasicAuthSecretDataObject(key string, secretType string) *v1alpha1.SecretObject {
func createBasicAuthSecretDataObject(key string) *v1alpha1.SecretObject {
return &v1alpha1.SecretObject{
SecretName: setSecretName(key),
Type: string(corev1.SecretTypeBasicAuth),
Data: []*v1alpha1.SecretObjectData{
{
ObjectName: key,
Key: setKey(key),
},
},
}
}

func createSSHSecretDataObject(key string) *v1alpha1.SecretObject {
return &v1alpha1.SecretObject{
SecretName: key,
Type: secretType,
SecretName: setSecretName(key),
Type: string(corev1.SecretTypeSSHAuth),
Data: []*v1alpha1.SecretObjectData{
{
ObjectName: key,
Key: key,
Key: sshPrivateKey,
},
},
}
}

func setKey(key string) string {
nested := strings.Split(key, "/")

if len(nested) > 0 {
return strings.Join(nested, "-")
}

return key
}

func setSecretName(key string) string {
nested := strings.Split(key, "/")

if len(nested) > 0 {
return nested[len(nested)-1]
}

return key
}
2 changes: 1 addition & 1 deletion test/bats/vault.bats
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ EOF
result=$(kubectl get secret foosecret -o jsonpath="{.data.bar1}" | base64 -d)
[[ "$result" == "hello1" ]]

result=$(kubectl get secret foosecret -o jsonpath="{.data.nested_bar}" | base64 -d)
result=$(kubectl get secret foosecret -o jsonpath="{.data.nested-bar}" | base64 -d)
[[ "$result" == "hello" ]]

result=$(kubectl exec $POD -- printenv | grep SECRET_USERNAME | awk -F"=" '{ print $2 }' | tr -d '\r\n')
Expand Down

0 comments on commit 5ba6d82

Please sign in to comment.