mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Don't provision for PVCs with AccessModes unsupported by plugin
This commit is contained in:
		@@ -25,6 +25,7 @@ import (
 | 
			
		||||
	"k8s.io/client-go/tools/cache"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
	v1helper "k8s.io/kubernetes/pkg/api/v1/helper"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/volume"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// persistentVolumeOrderedIndex is a cache.Store that keeps persistent volumes
 | 
			
		||||
@@ -206,7 +207,7 @@ func (pvIndex *persistentVolumeOrderedIndex) allPossibleMatchingAccessModes(requ
 | 
			
		||||
	keys := pvIndex.store.ListIndexFuncValues("accessmodes")
 | 
			
		||||
	for _, key := range keys {
 | 
			
		||||
		indexedModes := v1helper.GetAccessModesFromString(key)
 | 
			
		||||
		if containedInAll(indexedModes, requestedModes) {
 | 
			
		||||
		if volume.AccessModesContainedInAll(indexedModes, requestedModes) {
 | 
			
		||||
			matchedModes = append(matchedModes, indexedModes)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -218,24 +219,6 @@ func (pvIndex *persistentVolumeOrderedIndex) allPossibleMatchingAccessModes(requ
 | 
			
		||||
	return matchedModes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
 | 
			
		||||
	for _, m := range modes {
 | 
			
		||||
		if m == mode {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func containedInAll(indexedModes []v1.PersistentVolumeAccessMode, requestedModes []v1.PersistentVolumeAccessMode) bool {
 | 
			
		||||
	for _, mode := range requestedModes {
 | 
			
		||||
		if !contains(indexedModes, mode) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// byAccessModes is used to order access modes by size, with the fewest modes first
 | 
			
		||||
type byAccessModes struct {
 | 
			
		||||
	modes [][]v1.PersistentVolumeAccessMode
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/testapi"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1/ref"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/volume"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func makePVC(size string, modfn func(*v1.PersistentVolumeClaim)) *v1.PersistentVolumeClaim {
 | 
			
		||||
@@ -257,7 +258,7 @@ func TestAllPossibleAccessModes(t *testing.T) {
 | 
			
		||||
		t.Errorf("Expected 3 arrays of modes that match RWO, but got %v", len(possibleModes))
 | 
			
		||||
	}
 | 
			
		||||
	for _, m := range possibleModes {
 | 
			
		||||
		if !contains(m, v1.ReadWriteOnce) {
 | 
			
		||||
		if !volume.AccessModesContains(m, v1.ReadWriteOnce) {
 | 
			
		||||
			t.Errorf("AccessModes does not contain %s", v1.ReadWriteOnce)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -266,7 +267,7 @@ func TestAllPossibleAccessModes(t *testing.T) {
 | 
			
		||||
	if len(possibleModes) != 1 {
 | 
			
		||||
		t.Errorf("Expected 1 array of modes that match RWX, but got %v", len(possibleModes))
 | 
			
		||||
	}
 | 
			
		||||
	if !contains(possibleModes[0], v1.ReadWriteMany) {
 | 
			
		||||
	if !volume.AccessModesContains(possibleModes[0], v1.ReadWriteMany) {
 | 
			
		||||
		t.Errorf("AccessModes does not contain %s", v1.ReadWriteOnce)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -430,6 +430,10 @@ type awsElasticBlockStoreProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &awsElasticBlockStoreProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (c *awsElasticBlockStoreProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	volumeID, sizeGB, labels, err := c.manager.CreateVolume(c)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		glog.Errorf("Provision failed: %v", err)
 | 
			
		||||
 
 | 
			
		||||
@@ -107,6 +107,10 @@ type azureDiskProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &azureDiskProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (a *azureDiskProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(a.plugin.GetAccessModes(), a.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", a.options.PVC.Spec.AccessModes, a.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var sku, location, account string
 | 
			
		||||
 | 
			
		||||
	// maxLength = 79 - (4 for ".vhd") = 75
 | 
			
		||||
 
 | 
			
		||||
@@ -132,6 +132,10 @@ type azureFileProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &azureFileProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (a *azureFileProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(a.plugin.GetAccessModes(), a.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", a.options.PVC.Spec.AccessModes, a.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var sku, location, account string
 | 
			
		||||
 | 
			
		||||
	name := volume.GenerateVolumeName(a.options.ClusterName, a.options.PVName, 75)
 | 
			
		||||
 
 | 
			
		||||
@@ -482,6 +482,10 @@ type cinderVolumeProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &cinderVolumeProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (c *cinderVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	volumeID, sizeGB, labels, err := c.manager.CreateVolume(c)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,9 @@ type flockerVolumeProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &flockerVolumeProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (c *flockerVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.options.Parameters) > 0 {
 | 
			
		||||
		return nil, fmt.Errorf("Provisioning failed: Specified at least one unsupported parameter")
 | 
			
		||||
 
 | 
			
		||||
@@ -375,6 +375,10 @@ type gcePersistentDiskProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &gcePersistentDiskProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (c *gcePersistentDiskProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	volumeID, sizeGB, labels, err := c.manager.CreateVolume(c)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
@@ -788,6 +788,10 @@ func (d *glusterfsVolumeDeleter) Delete() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *glusterfsVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(p.plugin.GetAccessModes(), p.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", p.options.PVC.Spec.AccessModes, p.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	if p.options.PVC.Spec.Selector != nil {
 | 
			
		||||
		glog.V(4).Infof("glusterfs: not able to parse your claim Selector")
 | 
			
		||||
 
 | 
			
		||||
@@ -343,6 +343,10 @@ func (plugin *photonPersistentDiskPlugin) newProvisionerInternal(options volume.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *photonPersistentDiskProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(p.plugin.GetAccessModes(), p.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", p.options.PVC.Spec.AccessModes, p.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pdID, sizeGB, fstype, err := p.manager.CreateVolume(p)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
@@ -351,6 +351,10 @@ type portworxVolumeProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &portworxVolumeProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (c *portworxVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	volumeID, sizeGB, labels, err := c.manager.CreateVolume(c)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
@@ -356,6 +356,10 @@ type quobyteVolumeProvisioner struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (provisioner *quobyteVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(provisioner.plugin.GetAccessModes(), provisioner.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", provisioner.options.PVC.Spec.AccessModes, provisioner.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if provisioner.options.PVC.Spec.Selector != nil {
 | 
			
		||||
		return nil, fmt.Errorf("claim Selector is not supported")
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -255,6 +255,10 @@ type rbdVolumeProvisioner struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *rbdVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(r.plugin.GetAccessModes(), r.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", r.options.PVC.Spec.AccessModes, r.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if r.options.PVC.Spec.Selector != nil {
 | 
			
		||||
		return nil, fmt.Errorf("claim Selector is not supported")
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -236,6 +236,10 @@ var _ volume.Provisioner = &sioVolume{}
 | 
			
		||||
func (v *sioVolume) Provision() (*api.PersistentVolume, error) {
 | 
			
		||||
	glog.V(4).Info(log("attempting to dynamically provision pvc %v", v.options.PVName))
 | 
			
		||||
 | 
			
		||||
	if !volume.AccessModesContainedInAll(v.plugin.GetAccessModes(), v.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", v.options.PVC.Spec.AccessModes, v.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// setup volume attrributes
 | 
			
		||||
	name := v.generateVolName()
 | 
			
		||||
	capacity := v.options.PVC.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)]
 | 
			
		||||
 
 | 
			
		||||
@@ -553,6 +553,9 @@ type storageosProvisioner struct {
 | 
			
		||||
var _ volume.Provisioner = &storageosProvisioner{}
 | 
			
		||||
 | 
			
		||||
func (c *storageosProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(c.plugin.GetAccessModes(), c.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", c.options.PVC.Spec.AccessModes, c.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var adminSecretName, adminSecretNamespace string
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -434,3 +434,23 @@ func ValidateZone(zone string) error {
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AccessModesContains returns whether the requested mode is contained by modes
 | 
			
		||||
func AccessModesContains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
 | 
			
		||||
	for _, m := range modes {
 | 
			
		||||
		if m == mode {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AccessModesContainedInAll returns whether all of the requested modes are contained by modes
 | 
			
		||||
func AccessModesContainedInAll(indexedModes []v1.PersistentVolumeAccessMode, requestedModes []v1.PersistentVolumeAccessMode) bool {
 | 
			
		||||
	for _, mode := range requestedModes {
 | 
			
		||||
		if !AccessModesContains(indexedModes, mode) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -345,6 +345,10 @@ func (plugin *vsphereVolumePlugin) newProvisionerInternal(options volume.VolumeO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *vsphereVolumeProvisioner) Provision() (*v1.PersistentVolume, error) {
 | 
			
		||||
	if !volume.AccessModesContainedInAll(v.plugin.GetAccessModes(), v.options.PVC.Spec.AccessModes) {
 | 
			
		||||
		return nil, fmt.Errorf("invalid AccessModes %v: only AccessModes %v are supported", v.options.PVC.Spec.AccessModes, v.plugin.GetAccessModes())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	volSpec, err := v.manager.CreateVolume(v)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user