Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't provision for PVCs with AccessModes unsupported by plugin #47274

Merged
merged 1 commit into from
Jun 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 2 additions & 19 deletions pkg/controller/volume/persistentvolume/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions pkg/controller/volume/persistentvolume/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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)
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/aws_ebs/aws_ebs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/azure_dd/azure_provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/azure_file/azure_provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/cinder/cinder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions pkg/volume/flocker/flocker_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/gce_pd/gce_pd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/glusterfs/glusterfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/photon_pd/photon_pd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/portworx/portworx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/quobyte/quobyte.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/rbd/rbd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/volume/scaleio/sio_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
3 changes: 3 additions & 0 deletions pkg/volume/storageos/storageos.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
20 changes: 20 additions & 0 deletions pkg/volume/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
4 changes: 4 additions & 0 deletions pkg/volume/vsphere_volume/vsphere_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down