From 1dd73c59f3311b1a0d8ca0c97db2d1a54b823424 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Thu, 27 Oct 2016 02:21:36 -0400 Subject: [PATCH] Require PV provisioner secrets to match type --- pkg/volume/glusterfs/glusterfs.go | 2 +- pkg/volume/glusterfs/glusterfs_test.go | 1 + pkg/volume/quobyte/quobyte.go | 5 +++-- pkg/volume/rbd/rbd.go | 25 +++++++++++++++++++------ pkg/volume/util/util.go | 26 ++++++++++++++++++++++---- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/pkg/volume/glusterfs/glusterfs.go b/pkg/volume/glusterfs/glusterfs.go index 41bae67b1b1..833db859a8f 100644 --- a/pkg/volume/glusterfs/glusterfs.go +++ b/pkg/volume/glusterfs/glusterfs.go @@ -623,7 +623,7 @@ func (d *glusterfsVolumeDeleter) deleteEndpointService(namespace string, epServi // parseSecret finds a given Secret instance and reads user password from it. func parseSecret(namespace, secretName string, kubeClient clientset.Interface) (string, error) { - secretMap, err := volutil.GetSecret(namespace, secretName, kubeClient) + secretMap, err := volutil.GetSecretForPV(namespace, secretName, glusterfsPluginName, kubeClient) if err != nil { glog.Errorf("failed to get secret from [%q/%q]", namespace, secretName) return "", fmt.Errorf("failed to get secret from [%q/%q]", namespace, secretName) diff --git a/pkg/volume/glusterfs/glusterfs_test.go b/pkg/volume/glusterfs/glusterfs_test.go index c720799f433..f9baef9731c 100644 --- a/pkg/volume/glusterfs/glusterfs_test.go +++ b/pkg/volume/glusterfs/glusterfs_test.go @@ -242,6 +242,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { func TestParseClassParameters(t *testing.T) { secret := api.Secret{ + Type: "kubernetes.io/glusterfs", Data: map[string][]byte{ "data": []byte("mypassword"), }, diff --git a/pkg/volume/quobyte/quobyte.go b/pkg/volume/quobyte/quobyte.go index 345fbbae03d..4e218f12143 100644 --- a/pkg/volume/quobyte/quobyte.go +++ b/pkg/volume/quobyte/quobyte.go @@ -371,7 +371,7 @@ func (provisioner *quobyteVolumeProvisioner) Provision() (*api.PersistentVolume, } } - secretMap, err := util.GetSecret(adminSecretNamespace, adminSecretName, provisioner.plugin.host.GetKubeClient()) + secretMap, err := util.GetSecretForPV(adminSecretNamespace, adminSecretName, quobytePluginName, provisioner.plugin.host.GetKubeClient()) if err != nil { return nil, err } @@ -444,9 +444,10 @@ func (deleter *quobyteVolumeDeleter) Delete() error { return err } - secretMap, err := util.GetSecret( + secretMap, err := util.GetSecretForPV( annotations[annotationQuobyteAPISecretNamespace], annotations[annotationQuobyteAPISecret], + quobytePluginName, deleter.plugin.host.GetKubeClient()) if err != nil { diff --git a/pkg/volume/rbd/rbd.go b/pkg/volume/rbd/rbd.go index 1c603988db8..7fd453fbe58 100644 --- a/pkg/volume/rbd/rbd.go +++ b/pkg/volume/rbd/rbd.go @@ -99,7 +99,7 @@ func (plugin *rbdPlugin) NewMounter(spec *volume.Spec, pod *api.Pod, _ volume.Vo source, _ := plugin.getRBDVolumeSource(spec) if source.SecretRef != nil { - if secret, err = parseSecret(pod.Namespace, source.SecretRef.Name, plugin.host.GetKubeClient()); err != nil { + if secret, err = parsePodSecret(pod, source.SecretRef.Name, plugin.host.GetKubeClient()); err != nil { glog.Errorf("Couldn't get secret from %v/%v", pod.Namespace, source.SecretRef) return nil, err } @@ -199,7 +199,7 @@ func (plugin *rbdPlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) { } } - secret, err := parseSecret(adminSecretNamespace, adminSecretName, plugin.host.GetKubeClient()) + secret, err := parsePVSecret(adminSecretNamespace, adminSecretName, plugin.host.GetKubeClient()) if err != nil { // log error but don't return yet glog.Errorf("failed to get admin secret from [%q/%q]: %v", adminSecretNamespace, adminSecretName, err) @@ -281,7 +281,7 @@ func (r *rbdVolumeProvisioner) Provision() (*api.PersistentVolume, error) { if adminSecretName == "" { return nil, fmt.Errorf("missing Ceph admin secret name") } - if secret, err = parseSecret(adminSecretNamespace, adminSecretName, r.plugin.host.GetKubeClient()); err != nil { + if secret, err = parsePVSecret(adminSecretNamespace, adminSecretName, r.plugin.host.GetKubeClient()); err != nil { // log error but don't return yet glog.Errorf("failed to get admin secret from [%q/%q]", adminSecretNamespace, adminSecretName) } @@ -428,13 +428,26 @@ func getVolumeSource( return nil, false, fmt.Errorf("Spec does not reference a RBD volume type") } -// parseSecretMap locates the secret by key name. -func parseSecret(namespace, secretName string, kubeClient clientset.Interface) (string, error) { - secretMap, err := volutil.GetSecret(namespace, secretName, kubeClient) +func parsePodSecret(pod *api.Pod, secretName string, kubeClient clientset.Interface) (string, error) { + secret, err := volutil.GetSecretForPod(pod, secretName, kubeClient) + if err != nil { + glog.Errorf("failed to get secret from [%q/%q]", pod.Namespace, secretName) + return "", fmt.Errorf("failed to get secret from [%q/%q]", pod.Namespace, secretName) + } + return parseSecretMap(secret) +} + +func parsePVSecret(namespace, secretName string, kubeClient clientset.Interface) (string, error) { + secret, err := volutil.GetSecretForPV(namespace, secretName, rbdPluginName, kubeClient) if err != nil { glog.Errorf("failed to get secret from [%q/%q]", namespace, secretName) return "", fmt.Errorf("failed to get secret from [%q/%q]", namespace, secretName) } + return parseSecretMap(secret) +} + +// parseSecretMap locates the secret by key name. +func parseSecretMap(secretMap map[string]string) (string, error) { if len(secretMap) == 0 { return "", fmt.Errorf("empty secret map") } diff --git a/pkg/volume/util/util.go b/pkg/volume/util/util.go index 95aa4aa6edf..2311a6d4633 100644 --- a/pkg/volume/util/util.go +++ b/pkg/volume/util/util.go @@ -112,14 +112,13 @@ func PathExists(path string) (bool, error) { } } -// GetSecret locates secret by name and namespace and returns secret map -func GetSecret(namespace, secretName string, kubeClient clientset.Interface) (map[string]string, error) { +// GetSecretForPod locates secret by name in the pod's namespace and returns secret map +func GetSecretForPod(pod *api.Pod, secretName string, kubeClient clientset.Interface) (map[string]string, error) { secret := make(map[string]string) if kubeClient == nil { return secret, fmt.Errorf("Cannot get kube client") } - - secrets, err := kubeClient.Core().Secrets(namespace).Get(secretName) + secrets, err := kubeClient.Core().Secrets(pod.Namespace).Get(secretName) if err != nil { return secret, err } @@ -129,6 +128,25 @@ func GetSecret(namespace, secretName string, kubeClient clientset.Interface) (ma return secret, nil } +// GetSecretForPV locates secret by name and namespace, verifies the secret type, and returns secret map +func GetSecretForPV(secretNamespace, secretName, volumePluginName string, kubeClient clientset.Interface) (map[string]string, error) { + secret := make(map[string]string) + if kubeClient == nil { + return secret, fmt.Errorf("Cannot get kube client") + } + secrets, err := kubeClient.Core().Secrets(secretNamespace).Get(secretName) + if err != nil { + return secret, err + } + if secrets.Type != api.SecretType(volumePluginName) { + return secret, fmt.Errorf("Cannot get secret of type %s", volumePluginName) + } + for name, data := range secrets.Data { + secret[name] = string(data) + } + return secret, nil +} + // AddVolumeAnnotations adds a golang Map as annotation to a PersistentVolume func AddVolumeAnnotations(pv *api.PersistentVolume, annotations map[string]string) { if pv.Annotations == nil {