diff --git a/pkg/api/types.go b/pkg/api/types.go index ed4f75bf133..537d17f01d8 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -220,6 +220,9 @@ type PersistentVolumeSource struct { // This is useful for development and testing only. // on-host storage is not supported in any way HostPath *HostPathVolumeSource `json:"hostPath"` + // ISCSIVolumeSource represents an ISCSI resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi"` // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod Glusterfs *GlusterfsVolumeSource `json:"glusterfs"` // NFS represents an NFS mount on the host that shares a pod's lifetime diff --git a/pkg/api/v1/conversion.go b/pkg/api/v1/conversion.go index 032c5300786..6bde50d5655 100644 --- a/pkg/api/v1/conversion.go +++ b/pkg/api/v1/conversion.go @@ -1606,6 +1606,9 @@ func init() { if err := s.Convert(&in.HostPath, &out.HostPath, 0); err != nil { return err } + if err := s.Convert(&in.ISCSI, &out.ISCSI, 0); err != nil { + return err + } if err := s.Convert(&in.Glusterfs, &out.Glusterfs, 0); err != nil { return err } @@ -1624,6 +1627,9 @@ func init() { if err := s.Convert(&in.HostPath, &out.HostPath, 0); err != nil { return err } + if err := s.Convert(&in.ISCSI, &out.ISCSI, 0); err != nil { + return err + } if err := s.Convert(&in.Glusterfs, &out.Glusterfs, 0); err != nil { return err } diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index baa8b431653..97e3efb8f17 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -245,6 +245,9 @@ type PersistentVolumeSource struct { // This is useful for development and testing only. // on-host storage is not supported in any way. HostPath *HostPathVolumeSource `json:"hostPath" description:"a HostPath provisioned by a developer or tester; for develment use only"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod Glusterfs *GlusterfsVolumeSource `json:"glusterfs" description:"Glusterfs volume resource provisioned by an admin"` // NFS represents an NFS mount on the host diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index de8ada33a15..1c61df2e820 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -143,6 +143,9 @@ type PersistentVolumeSource struct { // This is useful for development and testing only. // on-host storage is not supported in any way. HostPath *HostPathVolumeSource `json:"hostPath" description:"a HostPath provisioned by a developer or tester; for develment use only"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod Glusterfs *GlusterfsVolumeSource `json:"glusterfs" description:"Glusterfs volume resource provisioned by an admin"` // NFS represents an NFS mount on the host diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 6275b6784f2..bc1d15d81ef 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -105,6 +105,9 @@ type PersistentVolumeSource struct { // This is useful for development and testing only. // on-host storage is not supported in any way. HostPath *HostPathVolumeSource `json:"hostPath" description:"a HostPath provisioned by a developer or tester; for develment use only"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod Glusterfs *GlusterfsVolumeSource `json:"glusterfs" description:"Glusterfs volume resource provisioned by an admin"` // NFS represents an NFS mount on the host diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index 4482931d485..b750f2ac7af 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -245,6 +245,9 @@ type PersistentVolumeSource struct { // This is useful for development and testing only. // on-host storage is not supported in any way. HostPath *HostPathVolumeSource `json:"hostPath" description:"a HostPath provisioned by a developer or tester; for develment use only"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` // Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod Glusterfs *GlusterfsVolumeSource `json:"glusterfs" description:"Glusterfs volume resource provisioned by an admin"` // NFS represents an NFS mount on the host diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 2889a91f6c6..8e29503eb52 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -461,6 +461,10 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) errs.ValidationErrorList numVolumes++ allErrs = append(allErrs, validateAWSElasticBlockStoreVolumeSource(pv.Spec.AWSElasticBlockStore).Prefix("awsElasticBlockStore")...) } + if pv.Spec.ISCSI != nil { + numVolumes++ + allErrs = append(allErrs, validateISCSIVolumeSource(pv.Spec.ISCSI).Prefix("iscsi")...) + } if pv.Spec.Glusterfs != nil { numVolumes++ allErrs = append(allErrs, validateGlusterfs(pv.Spec.Glusterfs).Prefix("glusterfs")...) diff --git a/pkg/volume/iscsi/iscsi_test.go b/pkg/volume/iscsi/iscsi_test.go index b3cdf9f494a..82ec3cc5c9d 100644 --- a/pkg/volume/iscsi/iscsi_test.go +++ b/pkg/volume/iscsi/iscsi_test.go @@ -39,6 +39,28 @@ func TestCanSupport(t *testing.T) { } } +func TestGetAccessModes(t *testing.T) { + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + + plug, err := plugMgr.FindPersistentPluginByName("kubernetes.io/iscsi") + if err != nil { + t.Errorf("Can't find the plugin by name") + } + if !contains(plug.GetAccessModes(), api.ReadWriteOnce) || !contains(plug.GetAccessModes(), api.ReadOnlyMany) { + t.Errorf("Expected two AccessModeTypes: %s and %s", api.ReadWriteOnce, api.ReadOnlyMany) + } +} + +func contains(modes []api.AccessModeType, mode api.AccessModeType) bool { + for _, m := range modes { + if m == mode { + return true + } + } + return false +} + type fakeDiskManager struct { attachCalled bool detachCalled bool