diff --git a/controllers/secretproviderclasspodstatus_controller.go b/controllers/secretproviderclasspodstatus_controller.go index e819d96c7..3a3720245 100644 --- a/controllers/secretproviderclasspodstatus_controller.go +++ b/controllers/secretproviderclasspodstatus_controller.go @@ -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 @@ -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{ @@ -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 @@ -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] @@ -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) diff --git a/pkg/rotation/reconciler.go b/pkg/rotation/reconciler.go index 9d437c763..c3190ef17 100644 --- a/pkg/rotation/reconciler.go +++ b/pkg/rotation/reconciler.go @@ -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) diff --git a/pkg/util/secretutil/secret.go b/pkg/util/secretutil/secret.go index a2a59fdca..306706445 100644 --- a/pkg/util/secretutil/secret.go +++ b/pkg/util/secretutil/secret.go @@ -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 @@ -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 diff --git a/pkg/util/spcutil/secret_object_data.go b/pkg/util/spcutil/secret_object_data.go index 231ab7ae4..ab36f2d09 100644 --- a/pkg/util/spcutil/secret_object_data.go +++ b/pkg/util/spcutil/secret_object_data.go @@ -5,18 +5,16 @@ 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 { @@ -24,7 +22,7 @@ func BuildSecretObjectData(files map[string]string, secretObj *v1alpha1.SecretOb var renamedKey string if len(nested) > 0 { - renamedKey = strings.Join(nested, "_") + renamedKey = strings.Join(nested, "-") } if renamedKey == "" { @@ -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) @@ -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, @@ -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 +} diff --git a/test/bats/vault.bats b/test/bats/vault.bats index 992d39c47..70d3d86f6 100644 --- a/test/bats/vault.bats +++ b/test/bats/vault.bats @@ -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')