mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
Refactor flex pv to allow secret namespace
This commit is contained in:
parent
bba84d785e
commit
d073c10dbc
@ -62,9 +62,17 @@ func VisitPVSecretNames(pv *api.PersistentVolume, visitor Visitor) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case source.FlexVolume != nil:
|
case source.FlexVolume != nil:
|
||||||
if source.FlexVolume.SecretRef != nil && !visitor(getClaimRefNamespace(pv), source.FlexVolume.SecretRef.Name) {
|
if source.FlexVolume.SecretRef != nil {
|
||||||
|
// previously persisted PV objects use claimRef namespace
|
||||||
|
ns := getClaimRefNamespace(pv)
|
||||||
|
if len(source.FlexVolume.SecretRef.Namespace) > 0 {
|
||||||
|
// use the secret namespace if namespace is set
|
||||||
|
ns = source.FlexVolume.SecretRef.Namespace
|
||||||
|
}
|
||||||
|
if !visitor(ns, source.FlexVolume.SecretRef.Name) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case source.RBD != nil:
|
case source.RBD != nil:
|
||||||
if source.RBD.SecretRef != nil {
|
if source.RBD.SecretRef != nil {
|
||||||
// previously persisted PV objects use claimRef namespace
|
// previously persisted PV objects use claimRef namespace
|
||||||
|
@ -61,8 +61,15 @@ func TestPVSecrets(t *testing.T) {
|
|||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: api.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||||
FlexVolume: &api.FlexVolumeSource{
|
FlexVolume: &api.FlexPersistentVolumeSource{
|
||||||
SecretRef: &api.LocalObjectReference{
|
SecretRef: &api.SecretReference{
|
||||||
|
Name: "Spec.PersistentVolumeSource.FlexVolume.SecretRef",
|
||||||
|
Namespace: "flexns"}}}}},
|
||||||
|
{Spec: api.PersistentVolumeSpec{
|
||||||
|
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
|
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||||
|
FlexVolume: &api.FlexPersistentVolumeSource{
|
||||||
|
SecretRef: &api.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.FlexVolume.SecretRef"}}}}},
|
Name: "Spec.PersistentVolumeSource.FlexVolume.SecretRef"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: api.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
@ -160,15 +167,22 @@ func TestPVSecrets(t *testing.T) {
|
|||||||
expectedNamespacedNames := sets.NewString(
|
expectedNamespacedNames := sets.NewString(
|
||||||
"claimrefns/Spec.PersistentVolumeSource.AzureFile.SecretName",
|
"claimrefns/Spec.PersistentVolumeSource.AzureFile.SecretName",
|
||||||
"Spec.PersistentVolumeSource.AzureFile.SecretNamespace/Spec.PersistentVolumeSource.AzureFile.SecretName",
|
"Spec.PersistentVolumeSource.AzureFile.SecretNamespace/Spec.PersistentVolumeSource.AzureFile.SecretName",
|
||||||
|
|
||||||
"claimrefns/Spec.PersistentVolumeSource.CephFS.SecretRef",
|
"claimrefns/Spec.PersistentVolumeSource.CephFS.SecretRef",
|
||||||
"cephfs/Spec.PersistentVolumeSource.CephFS.SecretRef",
|
"cephfs/Spec.PersistentVolumeSource.CephFS.SecretRef",
|
||||||
|
|
||||||
"claimrefns/Spec.PersistentVolumeSource.FlexVolume.SecretRef",
|
"claimrefns/Spec.PersistentVolumeSource.FlexVolume.SecretRef",
|
||||||
|
"flexns/Spec.PersistentVolumeSource.FlexVolume.SecretRef",
|
||||||
|
|
||||||
"claimrefns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
"claimrefns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||||
"rbdns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
"rbdns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||||
|
|
||||||
"claimrefns/Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
"claimrefns/Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
||||||
"scaleions/Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
"scaleions/Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
||||||
|
|
||||||
"claimrefns/Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
"claimrefns/Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
||||||
"iscsi/Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
"iscsi/Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
||||||
|
|
||||||
"storageosns/Spec.PersistentVolumeSource.StorageOS.SecretRef",
|
"storageosns/Spec.PersistentVolumeSource.StorageOS.SecretRef",
|
||||||
)
|
)
|
||||||
if missingNames := expectedNamespacedNames.Difference(extractedNamesWithNamespace); len(missingNames) > 0 {
|
if missingNames := expectedNamespacedNames.Difference(extractedNamesWithNamespace); len(missingNames) > 0 {
|
||||||
|
@ -354,7 +354,7 @@ type PersistentVolumeSource struct {
|
|||||||
// FlexVolume represents a generic volume resource that is
|
// FlexVolume represents a generic volume resource that is
|
||||||
// provisioned/attached using an exec based plugin.
|
// provisioned/attached using an exec based plugin.
|
||||||
// +optional
|
// +optional
|
||||||
FlexVolume *FlexVolumeSource
|
FlexVolume *FlexPersistentVolumeSource
|
||||||
// Cinder represents a cinder volume attached and mounted on kubelets host machine
|
// Cinder represents a cinder volume attached and mounted on kubelets host machine
|
||||||
// +optional
|
// +optional
|
||||||
Cinder *CinderVolumeSource
|
Cinder *CinderVolumeSource
|
||||||
@ -867,6 +867,32 @@ type FCVolumeSource struct {
|
|||||||
WWIDs []string
|
WWIDs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FlexPersistentVolumeSource represents a generic persistent volume resource that is
|
||||||
|
// provisioned/attached using an exec based plugin.
|
||||||
|
type FlexPersistentVolumeSource struct {
|
||||||
|
// Driver is the name of the driver to use for this volume.
|
||||||
|
Driver string
|
||||||
|
// Filesystem type to mount.
|
||||||
|
// Must be a filesystem type supported by the host operating system.
|
||||||
|
// Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script.
|
||||||
|
// +optional
|
||||||
|
FSType string
|
||||||
|
// Optional: SecretRef is reference to the secret object containing
|
||||||
|
// sensitive information to pass to the plugin scripts. This may be
|
||||||
|
// empty if no secret object is specified. If the secret object
|
||||||
|
// contains more than one secret, all secrets are passed to the plugin
|
||||||
|
// scripts.
|
||||||
|
// +optional
|
||||||
|
SecretRef *SecretReference
|
||||||
|
// Optional: Defaults to false (read/write). ReadOnly here will force
|
||||||
|
// the ReadOnly setting in VolumeMounts.
|
||||||
|
// +optional
|
||||||
|
ReadOnly bool
|
||||||
|
// Optional: Extra driver options if any.
|
||||||
|
// +optional
|
||||||
|
Options map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
// FlexVolume represents a generic volume resource that is
|
// FlexVolume represents a generic volume resource that is
|
||||||
// provisioned/attached using an exec based plugin.
|
// provisioned/attached using an exec based plugin.
|
||||||
type FlexVolumeSource struct {
|
type FlexVolumeSource struct {
|
||||||
|
@ -1257,6 +1257,27 @@ func validateFlexVolumeSource(fv *core.FlexVolumeSource, fldPath *field.Path) fi
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateFlexPersistentVolumeSource(fv *core.FlexPersistentVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||||
|
allErrs := field.ErrorList{}
|
||||||
|
if len(fv.Driver) == 0 {
|
||||||
|
allErrs = append(allErrs, field.Required(fldPath.Child("driver"), ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure user-specified options don't use kubernetes namespaces
|
||||||
|
for k := range fv.Options {
|
||||||
|
namespace := k
|
||||||
|
if parts := strings.SplitN(k, "/", 2); len(parts) == 2 {
|
||||||
|
namespace = parts[0]
|
||||||
|
}
|
||||||
|
normalized := "." + strings.ToLower(namespace)
|
||||||
|
if strings.HasSuffix(normalized, ".kubernetes.io") || strings.HasSuffix(normalized, ".k8s.io") {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("options").Key(k), k, "kubernetes.io and k8s.io namespaces are reserved"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allErrs
|
||||||
|
}
|
||||||
|
|
||||||
func validateAzureFile(azure *core.AzureFileVolumeSource, fldPath *field.Path) field.ErrorList {
|
func validateAzureFile(azure *core.AzureFileVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
if azure.SecretName == "" {
|
if azure.SecretName == "" {
|
||||||
@ -1588,7 +1609,7 @@ func ValidatePersistentVolume(pv *core.PersistentVolume) field.ErrorList {
|
|||||||
}
|
}
|
||||||
if pv.Spec.FlexVolume != nil {
|
if pv.Spec.FlexVolume != nil {
|
||||||
numVolumes++
|
numVolumes++
|
||||||
allErrs = append(allErrs, validateFlexVolumeSource(pv.Spec.FlexVolume, specPath.Child("flexVolume"))...)
|
allErrs = append(allErrs, validateFlexPersistentVolumeSource(pv.Spec.FlexVolume, specPath.Child("flexVolume"))...)
|
||||||
}
|
}
|
||||||
if pv.Spec.AzureFile != nil {
|
if pv.Spec.AzureFile != nil {
|
||||||
if numVolumes > 0 {
|
if numVolumes > 0 {
|
||||||
|
@ -469,7 +469,7 @@ func TestValidatePersistentVolumeSourceUpdate(t *testing.T) {
|
|||||||
validPvSourceNoUpdate := validVolume.DeepCopy()
|
validPvSourceNoUpdate := validVolume.DeepCopy()
|
||||||
invalidPvSourceUpdateType := validVolume.DeepCopy()
|
invalidPvSourceUpdateType := validVolume.DeepCopy()
|
||||||
invalidPvSourceUpdateType.Spec.PersistentVolumeSource = core.PersistentVolumeSource{
|
invalidPvSourceUpdateType.Spec.PersistentVolumeSource = core.PersistentVolumeSource{
|
||||||
FlexVolume: &core.FlexVolumeSource{
|
FlexVolume: &core.FlexPersistentVolumeSource{
|
||||||
Driver: "kubernetes.io/blue",
|
Driver: "kubernetes.io/blue",
|
||||||
FSType: "ext4",
|
FSType: "ext4",
|
||||||
},
|
},
|
||||||
|
@ -1076,6 +1076,16 @@ func printAzureFilePersistentVolumeSource(azureFile *api.AzureFilePersistentVolu
|
|||||||
azureFile.SecretName, ns, azureFile.ShareName, azureFile.ReadOnly)
|
azureFile.SecretName, ns, azureFile.ShareName, azureFile.ReadOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printFlexPersistentVolumeSource(flex *api.FlexPersistentVolumeSource, w PrefixWriter) {
|
||||||
|
w.Write(LEVEL_2, "Type:\tFlexVolume (a generic volume resource that is provisioned/attached using an exec based plugin)\n"+
|
||||||
|
" Driver:\t%v\n"+
|
||||||
|
" FSType:\t%v\n"+
|
||||||
|
" SecretRef:\t%v\n"+
|
||||||
|
" ReadOnly:\t%v\n",
|
||||||
|
" Options:\t%v\n",
|
||||||
|
flex.Driver, flex.FSType, flex.SecretRef, flex.ReadOnly, flex.Options)
|
||||||
|
}
|
||||||
|
|
||||||
func printFlexVolumeSource(flex *api.FlexVolumeSource, w PrefixWriter) {
|
func printFlexVolumeSource(flex *api.FlexVolumeSource, w PrefixWriter) {
|
||||||
w.Write(LEVEL_2, "Type:\tFlexVolume (a generic volume resource that is provisioned/attached using an exec based plugin)\n"+
|
w.Write(LEVEL_2, "Type:\tFlexVolume (a generic volume resource that is provisioned/attached using an exec based plugin)\n"+
|
||||||
" Driver:\t%v\n"+
|
" Driver:\t%v\n"+
|
||||||
@ -1184,7 +1194,7 @@ func describePersistentVolume(pv *api.PersistentVolume, events *api.EventList) (
|
|||||||
case pv.Spec.AzureFile != nil:
|
case pv.Spec.AzureFile != nil:
|
||||||
printAzureFilePersistentVolumeSource(pv.Spec.AzureFile, w)
|
printAzureFilePersistentVolumeSource(pv.Spec.AzureFile, w)
|
||||||
case pv.Spec.FlexVolume != nil:
|
case pv.Spec.FlexVolume != nil:
|
||||||
printFlexVolumeSource(pv.Spec.FlexVolume, w)
|
printFlexPersistentVolumeSource(pv.Spec.FlexVolume, w)
|
||||||
case pv.Spec.Flocker != nil:
|
case pv.Spec.Flocker != nil:
|
||||||
printFlockerVolumeSource(pv.Spec.Flocker, w)
|
printFlockerVolumeSource(pv.Spec.Flocker, w)
|
||||||
case pv.Spec.CSI != nil:
|
case pv.Spec.CSI != nil:
|
||||||
|
@ -48,7 +48,16 @@ func (a *attacherDefaults) GetDeviceMountPath(spec *volume.Spec, mountsDir strin
|
|||||||
// MountDevice is part of the volume.Attacher interface
|
// MountDevice is part of the volume.Attacher interface
|
||||||
func (a *attacherDefaults) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string, mounter mount.Interface) error {
|
func (a *attacherDefaults) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string, mounter mount.Interface) error {
|
||||||
glog.Warning(logPrefix(a.plugin.flexVolumePlugin), "using default MountDevice for volume ", spec.Name, ", device ", devicePath, ", deviceMountPath ", deviceMountPath)
|
glog.Warning(logPrefix(a.plugin.flexVolumePlugin), "using default MountDevice for volume ", spec.Name, ", device ", devicePath, ", deviceMountPath ", deviceMountPath)
|
||||||
volSource, readOnly := getVolumeSource(spec)
|
|
||||||
|
volSourceFSType, err := getFSType(spec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
readOnly, err := getReadOnly(spec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
options := make([]string, 0)
|
options := make([]string, 0)
|
||||||
|
|
||||||
@ -60,5 +69,5 @@ func (a *attacherDefaults) MountDevice(spec *volume.Spec, devicePath string, dev
|
|||||||
|
|
||||||
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Exec: a.plugin.host.GetExec(a.plugin.GetPluginName())}
|
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Exec: a.plugin.host.GetExec(a.plugin.GetPluginName())}
|
||||||
|
|
||||||
return diskMounter.FormatAndMount(devicePath, deviceMountPath, volSource.FSType, options)
|
return diskMounter.FormatAndMount(devicePath, deviceMountPath, volSourceFSType, options)
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ func fakePersistentVolumeSpec() *volume.Spec {
|
|||||||
},
|
},
|
||||||
Spec: v1.PersistentVolumeSpec{
|
Spec: v1.PersistentVolumeSpec{
|
||||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
FlexVolume: &v1.FlexVolumeSource{
|
FlexVolume: &v1.FlexPersistentVolumeSource{
|
||||||
Driver: "kubernetes.io/fakeAttacher",
|
Driver: "kubernetes.io/fakeAttacher",
|
||||||
ReadOnly: false,
|
ReadOnly: false,
|
||||||
},
|
},
|
||||||
|
@ -162,10 +162,25 @@ func (dc *DriverCall) Run() (*DriverStatus, error) {
|
|||||||
type OptionsForDriver map[string]string
|
type OptionsForDriver map[string]string
|
||||||
|
|
||||||
func NewOptionsForDriver(spec *volume.Spec, host volume.VolumeHost, extraOptions map[string]string) (OptionsForDriver, error) {
|
func NewOptionsForDriver(spec *volume.Spec, host volume.VolumeHost, extraOptions map[string]string) (OptionsForDriver, error) {
|
||||||
volSource, readOnly := getVolumeSource(spec)
|
|
||||||
|
volSourceFSType, err := getFSType(spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
readOnly, err := getReadOnly(spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
volSourceOptions, err := getOptions(spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
options := map[string]string{}
|
options := map[string]string{}
|
||||||
|
|
||||||
options[optionFSType] = volSource.FSType
|
options[optionFSType] = volSourceFSType
|
||||||
|
|
||||||
if readOnly {
|
if readOnly {
|
||||||
options[optionReadWrite] = "ro"
|
options[optionReadWrite] = "ro"
|
||||||
@ -179,7 +194,7 @@ func NewOptionsForDriver(spec *volume.Spec, host volume.VolumeHost, extraOptions
|
|||||||
options[key] = value
|
options[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, value := range volSource.Options {
|
for key, value := range volSourceOptions {
|
||||||
options[key] = value
|
options[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ func TestCanSupport(t *testing.T) {
|
|||||||
if !plugin.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{FlexVolume: &v1.FlexVolumeSource{Driver: "kubernetes.io/fakeAttacher"}}}}) {
|
if !plugin.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{FlexVolume: &v1.FlexVolumeSource{Driver: "kubernetes.io/fakeAttacher"}}}}) {
|
||||||
t.Errorf("Expected true")
|
t.Errorf("Expected true")
|
||||||
}
|
}
|
||||||
if !plugin.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{FlexVolume: &v1.FlexVolumeSource{Driver: "kubernetes.io/fakeAttacher"}}}}}) {
|
if !plugin.CanSupport(&volume.Spec{PersistentVolume: &v1.PersistentVolume{Spec: v1.PersistentVolumeSpec{PersistentVolumeSource: v1.PersistentVolumeSource{FlexVolume: &v1.FlexPersistentVolumeSource{Driver: "kubernetes.io/fakeAttacher"}}}}}) {
|
||||||
t.Errorf("Expected true")
|
t.Errorf("Expected true")
|
||||||
}
|
}
|
||||||
if plugin.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{}}}) {
|
if plugin.CanSupport(&volume.Spec{Volume: &v1.Volume{VolumeSource: v1.VolumeSource{}}}) {
|
||||||
|
@ -132,8 +132,11 @@ func (plugin *flexVolumePlugin) GetVolumeName(spec *volume.Spec) (string, error)
|
|||||||
|
|
||||||
// CanSupport is part of the volume.VolumePlugin interface.
|
// CanSupport is part of the volume.VolumePlugin interface.
|
||||||
func (plugin *flexVolumePlugin) CanSupport(spec *volume.Spec) bool {
|
func (plugin *flexVolumePlugin) CanSupport(spec *volume.Spec) bool {
|
||||||
source, _ := getVolumeSource(spec)
|
sourceDriver, err := getDriver(spec)
|
||||||
return (source != nil) && (source.Driver == plugin.driverName)
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return sourceDriver == plugin.driverName
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequiresRemount is part of the volume.VolumePlugin interface.
|
// RequiresRemount is part of the volume.VolumePlugin interface.
|
||||||
@ -156,10 +159,19 @@ func (plugin *flexVolumePlugin) NewMounter(spec *volume.Spec, pod *api.Pod, _ vo
|
|||||||
|
|
||||||
// newMounterInternal is the internal mounter routine to build the volume.
|
// newMounterInternal is the internal mounter routine to build the volume.
|
||||||
func (plugin *flexVolumePlugin) newMounterInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, runner exec.Interface) (volume.Mounter, error) {
|
func (plugin *flexVolumePlugin) newMounterInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, runner exec.Interface) (volume.Mounter, error) {
|
||||||
source, readOnly := getVolumeSource(spec)
|
sourceDriver, err := getDriver(spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
readOnly, err := getReadOnly(spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &flexVolumeMounter{
|
return &flexVolumeMounter{
|
||||||
flexVolume: &flexVolume{
|
flexVolume: &flexVolume{
|
||||||
driverName: source.Driver,
|
driverName: sourceDriver,
|
||||||
execPath: plugin.getExecutable(),
|
execPath: plugin.getExecutable(),
|
||||||
mounter: mounter,
|
mounter: mounter,
|
||||||
plugin: plugin,
|
plugin: plugin,
|
||||||
|
@ -22,15 +22,18 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
api "k8s.io/api/core/v1"
|
|
||||||
"k8s.io/kubernetes/pkg/util/mount"
|
"k8s.io/kubernetes/pkg/util/mount"
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
"k8s.io/kubernetes/pkg/volume/util"
|
"k8s.io/kubernetes/pkg/volume/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func addSecretsToOptions(options map[string]string, spec *volume.Spec, namespace string, driverName string, host volume.VolumeHost) error {
|
func addSecretsToOptions(options map[string]string, spec *volume.Spec, namespace string, driverName string, host volume.VolumeHost) error {
|
||||||
fv, _ := getVolumeSource(spec)
|
secretName, secretNamespace, err := getSecretNameAndNamespace(spec, namespace)
|
||||||
if fv.SecretRef == nil {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(secretName) == 0 || len(secretNamespace) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,9 +42,9 @@ func addSecretsToOptions(options map[string]string, spec *volume.Spec, namespace
|
|||||||
return fmt.Errorf("Cannot get kube client")
|
return fmt.Errorf("Cannot get kube client")
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets, err := util.GetSecretForPV(namespace, fv.SecretRef.Name, driverName, host.GetKubeClient())
|
secrets, err := util.GetSecretForPV(secretNamespace, secretName, driverName, host.GetKubeClient())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Couldn't get secret %v/%v err: %v", namespace, fv.SecretRef.Name, err)
|
err = fmt.Errorf("Couldn't get secret %v/%v err: %v", secretNamespace, secretName, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for name, data := range secrets {
|
for name, data := range secrets {
|
||||||
@ -52,15 +55,68 @@ func addSecretsToOptions(options map[string]string, spec *volume.Spec, namespace
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVolumeSource(spec *volume.Spec) (volumeSource *api.FlexVolumeSource, readOnly bool) {
|
var notFlexVolume = fmt.Errorf("not a flex volume")
|
||||||
|
|
||||||
|
func getDriver(spec *volume.Spec) (string, error) {
|
||||||
if spec.Volume != nil && spec.Volume.FlexVolume != nil {
|
if spec.Volume != nil && spec.Volume.FlexVolume != nil {
|
||||||
volumeSource = spec.Volume.FlexVolume
|
return spec.Volume.FlexVolume.Driver, nil
|
||||||
readOnly = volumeSource.ReadOnly
|
|
||||||
} else if spec.PersistentVolume != nil {
|
|
||||||
volumeSource = spec.PersistentVolume.Spec.FlexVolume
|
|
||||||
readOnly = spec.ReadOnly
|
|
||||||
}
|
}
|
||||||
return
|
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FlexVolume != nil {
|
||||||
|
return spec.PersistentVolume.Spec.FlexVolume.Driver, nil
|
||||||
|
}
|
||||||
|
return "", notFlexVolume
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFSType(spec *volume.Spec) (string, error) {
|
||||||
|
if spec.Volume != nil && spec.Volume.FlexVolume != nil {
|
||||||
|
return spec.Volume.FlexVolume.FSType, nil
|
||||||
|
}
|
||||||
|
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FlexVolume != nil {
|
||||||
|
return spec.PersistentVolume.Spec.FlexVolume.FSType, nil
|
||||||
|
}
|
||||||
|
return "", notFlexVolume
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSecretNameAndNamespace(spec *volume.Spec, podNamespace string) (string, string, error) {
|
||||||
|
if spec.Volume != nil && spec.Volume.FlexVolume != nil {
|
||||||
|
if spec.Volume.FlexVolume.SecretRef == nil {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
return spec.Volume.FlexVolume.SecretRef.Name, podNamespace, nil
|
||||||
|
}
|
||||||
|
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FlexVolume != nil {
|
||||||
|
if spec.PersistentVolume.Spec.FlexVolume.SecretRef == nil {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
secretName := spec.PersistentVolume.Spec.FlexVolume.SecretRef.Name
|
||||||
|
secretNamespace := spec.PersistentVolume.Spec.FlexVolume.SecretRef.Namespace
|
||||||
|
if len(secretNamespace) == 0 {
|
||||||
|
secretNamespace = podNamespace
|
||||||
|
}
|
||||||
|
return secretName, secretNamespace, nil
|
||||||
|
}
|
||||||
|
return "", "", notFlexVolume
|
||||||
|
}
|
||||||
|
|
||||||
|
func getReadOnly(spec *volume.Spec) (bool, error) {
|
||||||
|
if spec.Volume != nil && spec.Volume.FlexVolume != nil {
|
||||||
|
return spec.Volume.FlexVolume.ReadOnly, nil
|
||||||
|
}
|
||||||
|
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FlexVolume != nil {
|
||||||
|
// ReadOnly is specified at the PV level
|
||||||
|
return spec.ReadOnly, nil
|
||||||
|
}
|
||||||
|
return false, notFlexVolume
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOptions(spec *volume.Spec) (map[string]string, error) {
|
||||||
|
if spec.Volume != nil && spec.Volume.FlexVolume != nil {
|
||||||
|
return spec.Volume.FlexVolume.Options, nil
|
||||||
|
}
|
||||||
|
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.FlexVolume != nil {
|
||||||
|
return spec.PersistentVolume.Spec.FlexVolume.Options, nil
|
||||||
|
}
|
||||||
|
return nil, notFlexVolume
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareForMount(mounter mount.Interface, deviceMountPath string) (bool, error) {
|
func prepareForMount(mounter mount.Interface, deviceMountPath string) (bool, error) {
|
||||||
|
@ -410,7 +410,7 @@ func generate(opts sampleDataOpts) ([]*api.Pod, []*api.PersistentVolume) {
|
|||||||
for i := 0; i < opts.uniquePVCsPerPod; i++ {
|
for i := 0; i < opts.uniquePVCsPerPod; i++ {
|
||||||
pv := &api.PersistentVolume{}
|
pv := &api.PersistentVolume{}
|
||||||
pv.Name = fmt.Sprintf("pv%d-%s-%s", i, pod.Name, pod.Namespace)
|
pv.Name = fmt.Sprintf("pv%d-%s-%s", i, pod.Name, pod.Namespace)
|
||||||
pv.Spec.FlexVolume = &api.FlexVolumeSource{SecretRef: &api.LocalObjectReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
pv.Spec.FlexVolume = &api.FlexPersistentVolumeSource{SecretRef: &api.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||||
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
|
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
|
||||||
pvs = append(pvs, pv)
|
pvs = append(pvs, pv)
|
||||||
|
|
||||||
@ -421,7 +421,7 @@ func generate(opts sampleDataOpts) ([]*api.Pod, []*api.PersistentVolume) {
|
|||||||
for i := 0; i < opts.sharedPVCsPerPod; i++ {
|
for i := 0; i < opts.sharedPVCsPerPod; i++ {
|
||||||
pv := &api.PersistentVolume{}
|
pv := &api.PersistentVolume{}
|
||||||
pv.Name = fmt.Sprintf("pv%d-shared-%s", i, pod.Namespace)
|
pv.Name = fmt.Sprintf("pv%d-shared-%s", i, pod.Namespace)
|
||||||
pv.Spec.FlexVolume = &api.FlexVolumeSource{SecretRef: &api.LocalObjectReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
pv.Spec.FlexVolume = &api.FlexPersistentVolumeSource{SecretRef: &api.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||||
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
|
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
|
||||||
pvs = append(pvs, pv)
|
pvs = append(pvs, pv)
|
||||||
|
|
||||||
|
@ -418,7 +418,7 @@ type PersistentVolumeSource struct {
|
|||||||
// FlexVolume represents a generic volume resource that is
|
// FlexVolume represents a generic volume resource that is
|
||||||
// provisioned/attached using an exec based plugin.
|
// provisioned/attached using an exec based plugin.
|
||||||
// +optional
|
// +optional
|
||||||
FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty" protobuf:"bytes,12,opt,name=flexVolume"`
|
FlexVolume *FlexPersistentVolumeSource `json:"flexVolume,omitempty" protobuf:"bytes,12,opt,name=flexVolume"`
|
||||||
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
|
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
|
||||||
// +optional
|
// +optional
|
||||||
AzureFile *AzureFilePersistentVolumeSource `json:"azureFile,omitempty" protobuf:"bytes,13,opt,name=azureFile"`
|
AzureFile *AzureFilePersistentVolumeSource `json:"azureFile,omitempty" protobuf:"bytes,13,opt,name=azureFile"`
|
||||||
@ -1081,6 +1081,32 @@ type QuobyteVolumeSource struct {
|
|||||||
Group string `json:"group,omitempty" protobuf:"bytes,5,opt,name=group"`
|
Group string `json:"group,omitempty" protobuf:"bytes,5,opt,name=group"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FlexPersistentVolumeSource represents a generic persistent volume resource that is
|
||||||
|
// provisioned/attached using an exec based plugin.
|
||||||
|
type FlexPersistentVolumeSource struct {
|
||||||
|
// Driver is the name of the driver to use for this volume.
|
||||||
|
Driver string `json:"driver" protobuf:"bytes,1,opt,name=driver"`
|
||||||
|
// Filesystem type to mount.
|
||||||
|
// Must be a filesystem type supported by the host operating system.
|
||||||
|
// Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script.
|
||||||
|
// +optional
|
||||||
|
FSType string `json:"fsType,omitempty" protobuf:"bytes,2,opt,name=fsType"`
|
||||||
|
// Optional: SecretRef is reference to the secret object containing
|
||||||
|
// sensitive information to pass to the plugin scripts. This may be
|
||||||
|
// empty if no secret object is specified. If the secret object
|
||||||
|
// contains more than one secret, all secrets are passed to the plugin
|
||||||
|
// scripts.
|
||||||
|
// +optional
|
||||||
|
SecretRef *SecretReference `json:"secretRef,omitempty" protobuf:"bytes,3,opt,name=secretRef"`
|
||||||
|
// Optional: Defaults to false (read/write). ReadOnly here will force
|
||||||
|
// the ReadOnly setting in VolumeMounts.
|
||||||
|
// +optional
|
||||||
|
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,4,opt,name=readOnly"`
|
||||||
|
// Optional: Extra command options if any.
|
||||||
|
// +optional
|
||||||
|
Options map[string]string `json:"options,omitempty" protobuf:"bytes,5,rep,name=options"`
|
||||||
|
}
|
||||||
|
|
||||||
// FlexVolume represents a generic volume resource that is
|
// FlexVolume represents a generic volume resource that is
|
||||||
// provisioned/attached using an exec based plugin.
|
// provisioned/attached using an exec based plugin.
|
||||||
type FlexVolumeSource struct {
|
type FlexVolumeSource struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user