mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
ScaleIO - API source code update
This commit tracks all human-generated code for API source updates.
This commit is contained in:
parent
7b588817ca
commit
3fb3cc7122
@ -410,14 +410,16 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
}
|
||||
},
|
||||
func(sio *api.ScaleIOVolumeSource, c fuzz.Continue) {
|
||||
sio.ProtectionDomain = c.RandString()
|
||||
if sio.ProtectionDomain == "" {
|
||||
sio.ProtectionDomain = "default"
|
||||
sio.StorageMode = c.RandString()
|
||||
if sio.StorageMode == "" {
|
||||
sio.StorageMode = "ThinProvisioned"
|
||||
}
|
||||
sio.StoragePool = c.RandString()
|
||||
if sio.StoragePool == "" {
|
||||
sio.StoragePool = "default"
|
||||
sio.FSType = c.RandString()
|
||||
if sio.FSType == "" {
|
||||
sio.FSType = "xfs"
|
||||
}
|
||||
},
|
||||
func(sio *api.ScaleIOPersistentVolumeSource, c fuzz.Continue) {
|
||||
sio.StorageMode = c.RandString()
|
||||
if sio.StorageMode == "" {
|
||||
sio.StorageMode = "ThinProvisioned"
|
||||
|
@ -76,8 +76,14 @@ func VisitPVSecretNames(pv *api.PersistentVolume, visitor Visitor) bool {
|
||||
}
|
||||
}
|
||||
case source.ScaleIO != nil:
|
||||
if source.ScaleIO.SecretRef != nil && !visitor(getClaimRefNamespace(pv), source.ScaleIO.SecretRef.Name) {
|
||||
return false
|
||||
if source.ScaleIO.SecretRef != nil {
|
||||
ns := getClaimRefNamespace(pv)
|
||||
if source.ScaleIO.SecretRef != nil && len(source.ScaleIO.SecretRef.Namespace) > 0 {
|
||||
ns = source.ScaleIO.SecretRef.Namespace
|
||||
}
|
||||
if !visitor(ns, source.ScaleIO.SecretRef.Name) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
case source.ISCSI != nil:
|
||||
if source.ISCSI.SecretRef != nil && !visitor(getClaimRefNamespace(pv), source.ISCSI.SecretRef.Name) {
|
||||
|
@ -78,9 +78,16 @@ func TestPVSecrets(t *testing.T) {
|
||||
{Spec: api.PersistentVolumeSpec{
|
||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
ScaleIO: &api.ScaleIOVolumeSource{
|
||||
SecretRef: &api.LocalObjectReference{
|
||||
ScaleIO: &api.ScaleIOPersistentVolumeSource{
|
||||
SecretRef: &api.SecretReference{
|
||||
Name: "Spec.PersistentVolumeSource.ScaleIO.SecretRef"}}}}},
|
||||
{Spec: api.PersistentVolumeSpec{
|
||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
ScaleIO: &api.ScaleIOPersistentVolumeSource{
|
||||
SecretRef: &api.SecretReference{
|
||||
Name: "Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
||||
Namespace: "scaleions"}}}}},
|
||||
{Spec: api.PersistentVolumeSpec{
|
||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
@ -150,6 +157,7 @@ func TestPVSecrets(t *testing.T) {
|
||||
"claimrefns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||
"rbdns/Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||
"claimrefns/Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
||||
"scaleions/Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
||||
"claimrefns/Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
||||
"storageosns/Spec.PersistentVolumeSource.StorageOS.SecretRef",
|
||||
)
|
||||
|
@ -383,7 +383,7 @@ type PersistentVolumeSource struct {
|
||||
PortworxVolume *PortworxVolumeSource
|
||||
// ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
|
||||
// +optional
|
||||
ScaleIO *ScaleIOVolumeSource
|
||||
ScaleIO *ScaleIOPersistentVolumeSource
|
||||
// Local represents directly-attached storage with node affinity
|
||||
// +optional
|
||||
Local *LocalVolumeSource
|
||||
@ -1285,13 +1285,13 @@ type ScaleIOVolumeSource struct {
|
||||
// Flag to enable/disable SSL communication with Gateway, default false
|
||||
// +optional
|
||||
SSLEnabled bool
|
||||
// The name of the Protection Domain for the configured storage (defaults to "default").
|
||||
// The name of the ScaleIO Protection Domain for the configured storage.
|
||||
// +optional
|
||||
ProtectionDomain string
|
||||
// The Storage Pool associated with the protection domain (defaults to "default").
|
||||
// The ScaleIO Storage Pool associated with the protection domain.
|
||||
// +optional
|
||||
StoragePool string
|
||||
// Indicates whether the storage for a volume should be thick or thin (defaults to "thin").
|
||||
// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
|
||||
// +optional
|
||||
StorageMode string
|
||||
// The name of a volume already created in the ScaleIO system
|
||||
@ -1308,6 +1308,42 @@ type ScaleIOVolumeSource struct {
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
// ScaleIOPersistentVolumeSource represents a persistent ScaleIO volume that can be defined
|
||||
// by a an admin via a storage class, for instance.
|
||||
type ScaleIOPersistentVolumeSource struct {
|
||||
// The host address of the ScaleIO API Gateway.
|
||||
Gateway string
|
||||
// The name of the storage system as configured in ScaleIO.
|
||||
System string
|
||||
// SecretRef references to the secret for ScaleIO user and other
|
||||
// sensitive information. If this is not provided, Login operation will fail.
|
||||
SecretRef *SecretReference
|
||||
// Flag to enable/disable SSL communication with Gateway, default false
|
||||
// +optional
|
||||
SSLEnabled bool
|
||||
// The name of the ScaleIO Protection Domain for the configured storage.
|
||||
// +optional
|
||||
ProtectionDomain string
|
||||
// The ScaleIO Storage Pool associated with the protection domain.
|
||||
// +optional
|
||||
StoragePool string
|
||||
// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
|
||||
// +optional
|
||||
StorageMode string
|
||||
// The name of a volume created in the ScaleIO system
|
||||
// that is associated with this volume source.
|
||||
VolumeName string
|
||||
// Filesystem type to mount.
|
||||
// Must be a filesystem type supported by the host operating system.
|
||||
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// +optional
|
||||
FSType string
|
||||
// Defaults to false (read/write). ReadOnly here will force
|
||||
// the ReadOnly setting in VolumeMounts.
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
// Represents a StorageOS persistent volume resource.
|
||||
type StorageOSVolumeSource struct {
|
||||
// VolumeName is the human-readable name of the StorageOS volume. Volume
|
||||
|
@ -381,12 +381,15 @@ func SetDefaults_RBDPersistentVolumeSource(obj *v1.RBDPersistentVolumeSource) {
|
||||
}
|
||||
|
||||
func SetDefaults_ScaleIOVolumeSource(obj *v1.ScaleIOVolumeSource) {
|
||||
if obj.ProtectionDomain == "" {
|
||||
obj.ProtectionDomain = "default"
|
||||
if obj.StorageMode == "" {
|
||||
obj.StorageMode = "ThinProvisioned"
|
||||
}
|
||||
if obj.StoragePool == "" {
|
||||
obj.StoragePool = "default"
|
||||
if obj.FSType == "" {
|
||||
obj.FSType = "xfs"
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_ScaleIOPersistentVolumeSource(obj *v1.ScaleIOPersistentVolumeSource) {
|
||||
if obj.StorageMode == "" {
|
||||
obj.StorageMode = "ThinProvisioned"
|
||||
}
|
||||
|
@ -1245,6 +1245,20 @@ func validateScaleIOVolumeSource(sio *api.ScaleIOVolumeSource, fldPath *field.Pa
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateScaleIOPersistentVolumeSource(sio *api.ScaleIOPersistentVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if sio.Gateway == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("gateway"), ""))
|
||||
}
|
||||
if sio.System == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("system"), ""))
|
||||
}
|
||||
if sio.VolumeName == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("volumeName"), ""))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateLocalVolumeSource(ls *api.LocalVolumeSource, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if ls.Path == "" {
|
||||
@ -1489,7 +1503,7 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) field.ErrorList {
|
||||
allErrs = append(allErrs, field.Forbidden(specPath.Child("scaleIO"), "may not specify more than 1 volume type"))
|
||||
} else {
|
||||
numVolumes++
|
||||
allErrs = append(allErrs, validateScaleIOVolumeSource(pv.Spec.ScaleIO, specPath.Child("scaleIO"))...)
|
||||
allErrs = append(allErrs, validateScaleIOPersistentVolumeSource(pv.Spec.ScaleIO, specPath.Child("scaleIO"))...)
|
||||
}
|
||||
}
|
||||
if pv.Spec.Local != nil {
|
||||
|
@ -970,6 +970,26 @@ func printScaleIOVolumeSource(sio *api.ScaleIOVolumeSource, w PrefixWriter) {
|
||||
sio.Gateway, sio.System, sio.ProtectionDomain, sio.StoragePool, sio.StorageMode, sio.VolumeName, sio.FSType, sio.ReadOnly)
|
||||
}
|
||||
|
||||
func printScaleIOPersistentVolumeSource(sio *api.ScaleIOPersistentVolumeSource, w PrefixWriter) {
|
||||
var secretNS, secretName string
|
||||
if sio.SecretRef != nil {
|
||||
secretName = sio.SecretRef.Name
|
||||
secretNS = sio.SecretRef.Namespace
|
||||
}
|
||||
w.Write(LEVEL_2, "Type:\tScaleIO (a persistent volume backed by a block device in ScaleIO)\n"+
|
||||
" Gateway:\t%v\n"+
|
||||
" System:\t%v\n"+
|
||||
" Protection Domain:\t%v\n"+
|
||||
" Storage Pool:\t%v\n"+
|
||||
" Storage Mode:\t%v\n"+
|
||||
" VolumeName:\t%v\n"+
|
||||
" SecretName:\t%v\n"+
|
||||
" SecretNamespace:\t%v\n"+
|
||||
" FSType:\t%v\n"+
|
||||
" ReadOnly:\t%v\n",
|
||||
sio.Gateway, sio.System, sio.ProtectionDomain, sio.StoragePool, sio.StorageMode, sio.VolumeName, secretName, secretNS, sio.FSType, sio.ReadOnly)
|
||||
}
|
||||
|
||||
func printLocalVolumeSource(ls *api.LocalVolumeSource, w PrefixWriter) {
|
||||
w.Write(LEVEL_2, "Type:\tLocalVolume (a persistent volume backed by local storage on a node)\n"+
|
||||
" Path:\t%v\n",
|
||||
@ -1135,7 +1155,7 @@ func describePersistentVolume(pv *api.PersistentVolume, events *api.EventList) (
|
||||
case pv.Spec.PortworxVolume != nil:
|
||||
printPortworxVolumeSource(pv.Spec.PortworxVolume, w)
|
||||
case pv.Spec.ScaleIO != nil:
|
||||
printScaleIOVolumeSource(pv.Spec.ScaleIO, w)
|
||||
printScaleIOPersistentVolumeSource(pv.Spec.ScaleIO, w)
|
||||
case pv.Spec.Local != nil:
|
||||
printLocalVolumeSource(pv.Spec.Local, w)
|
||||
case pv.Spec.CephFS != nil:
|
||||
|
@ -37,7 +37,7 @@ var (
|
||||
confKey.sslEnabled: "false",
|
||||
confKey.system: "scaleio",
|
||||
confKey.volumeName: "sio-0001",
|
||||
confKey.secretRef: "sio-secret",
|
||||
confKey.secretName: "sio-secret",
|
||||
confKey.username: "c2lvdXNlcgo=", // siouser
|
||||
confKey.password: "c2lvcGFzc3dvcmQK", // siopassword
|
||||
}
|
||||
|
@ -60,12 +60,11 @@ func (p *sioPlugin) GetPluginName() string {
|
||||
}
|
||||
|
||||
func (p *sioPlugin) GetVolumeName(spec *volume.Spec) (string, error) {
|
||||
source, err := getVolumeSourceFromSpec(spec)
|
||||
attribs, err := getVolumeSourceAttribs(spec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return source.VolumeName, nil
|
||||
return attribs.volName, nil
|
||||
}
|
||||
|
||||
func (p *sioPlugin) CanSupport(spec *volume.Spec) bool {
|
||||
@ -81,29 +80,33 @@ func (p *sioPlugin) NewMounter(
|
||||
spec *volume.Spec,
|
||||
pod *api.Pod,
|
||||
_ volume.VolumeOptions) (volume.Mounter, error) {
|
||||
sioSource, err := getVolumeSourceFromSpec(spec)
|
||||
|
||||
// extract source info from either ScaleIOVolumeSource or ScaleIOPersistentVolumeSource type
|
||||
attribs, err := getVolumeSourceAttribs(spec)
|
||||
if err != nil {
|
||||
glog.Error(log("failed to extract ScaleIOVolumeSource from spec: %v", err))
|
||||
return nil, err
|
||||
return nil, errors.New(log("mounter failed to extract volume attributes from spec: %v", err))
|
||||
}
|
||||
|
||||
secretName, secretNS, err := getSecretAndNamespaceFromSpec(spec, pod)
|
||||
if err != nil {
|
||||
return nil, errors.New(log("failed to get secret name or secretNamespace: %v", err))
|
||||
}
|
||||
|
||||
return &sioVolume{
|
||||
pod: pod,
|
||||
spec: spec,
|
||||
source: sioSource,
|
||||
namespace: pod.Namespace,
|
||||
volSpecName: spec.Name(),
|
||||
volName: sioSource.VolumeName,
|
||||
podUID: pod.UID,
|
||||
readOnly: sioSource.ReadOnly,
|
||||
fsType: sioSource.FSType,
|
||||
plugin: p,
|
||||
pod: pod,
|
||||
spec: spec,
|
||||
secretName: secretName,
|
||||
secretNamespace: secretNS,
|
||||
volSpecName: spec.Name(),
|
||||
volName: attribs.volName,
|
||||
podUID: pod.UID,
|
||||
readOnly: attribs.readOnly,
|
||||
fsType: attribs.fsType,
|
||||
plugin: p,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewUnmounter creates a representation of the volume to unmount
|
||||
// The specName param can be used to carry the namespace value (if needed) using format:
|
||||
// specName = [<namespace>nsSep]<somevalue> where the specname is pre-pended with the namespace
|
||||
func (p *sioPlugin) NewUnmounter(specName string, podUID types.UID) (volume.Unmounter, error) {
|
||||
glog.V(4).Info(log("Unmounter for %s", specName))
|
||||
|
||||
@ -156,22 +159,25 @@ func (p *sioPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
|
||||
var _ volume.DeletableVolumePlugin = &sioPlugin{}
|
||||
|
||||
func (p *sioPlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) {
|
||||
sioSource, err := getVolumeSourceFromSpec(spec)
|
||||
attribs, err := getVolumeSourceAttribs(spec)
|
||||
if err != nil {
|
||||
glog.Error(log("deleter failed to extract source from spec: %v", err))
|
||||
glog.Error(log("deleter failed to extract volume attributes from spec: %v", err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
namespace := spec.PersistentVolume.Spec.ClaimRef.Namespace
|
||||
secretName, secretNS, err := getSecretAndNamespaceFromSpec(spec, nil)
|
||||
if err != nil {
|
||||
return nil, errors.New(log("failed to get secret name or secretNamespace: %v", err))
|
||||
}
|
||||
|
||||
return &sioVolume{
|
||||
spec: spec,
|
||||
source: sioSource,
|
||||
namespace: namespace,
|
||||
volSpecName: spec.Name(),
|
||||
volName: sioSource.VolumeName,
|
||||
plugin: p,
|
||||
readOnly: sioSource.ReadOnly,
|
||||
spec: spec,
|
||||
secretName: secretName,
|
||||
secretNamespace: secretNS,
|
||||
volSpecName: spec.Name(),
|
||||
volName: attribs.volName,
|
||||
plugin: p,
|
||||
readOnly: attribs.readOnly,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -189,13 +195,26 @@ func (p *sioPlugin) NewProvisioner(options volume.VolumeOptions) (volume.Provisi
|
||||
return nil, errors.New("option parameters missing")
|
||||
}
|
||||
|
||||
namespace := options.PVC.Namespace
|
||||
// Supports ref of name of secret a couple of ways:
|
||||
// options.Parameters["secretRef"] for backward compat, or
|
||||
// options.Parameters["secretName"]
|
||||
secretName := configData[confKey.secretName]
|
||||
if secretName == "" {
|
||||
secretName = configData["secretName"]
|
||||
configData[confKey.secretName] = secretName
|
||||
}
|
||||
|
||||
secretNS := configData[confKey.secretNamespace]
|
||||
if secretNS == "" {
|
||||
secretNS = options.PVC.Namespace
|
||||
}
|
||||
|
||||
return &sioVolume{
|
||||
configData: configData,
|
||||
plugin: p,
|
||||
options: options,
|
||||
namespace: namespace,
|
||||
volSpecName: options.PVName,
|
||||
configData: configData,
|
||||
plugin: p,
|
||||
options: options,
|
||||
secretName: secretName,
|
||||
secretNamespace: secretNS,
|
||||
volSpecName: options.PVName,
|
||||
}, nil
|
||||
}
|
||||
|
@ -31,11 +31,17 @@ import (
|
||||
volutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
type volSourceAttribs struct {
|
||||
volName,
|
||||
fsType string
|
||||
readOnly bool
|
||||
}
|
||||
|
||||
var (
|
||||
confKey = struct {
|
||||
gateway,
|
||||
sslEnabled,
|
||||
secretRef,
|
||||
secretName,
|
||||
system,
|
||||
protectionDomain,
|
||||
storagePool,
|
||||
@ -47,12 +53,13 @@ var (
|
||||
readOnly,
|
||||
username,
|
||||
password,
|
||||
namespace,
|
||||
secretNamespace,
|
||||
sdcGuid string
|
||||
}{
|
||||
gateway: "gateway",
|
||||
sslEnabled: "sslEnabled",
|
||||
secretRef: "secretRef",
|
||||
secretName: "secretRef",
|
||||
secretNamespace: "secretNamespace",
|
||||
system: "system",
|
||||
protectionDomain: "protectionDomain",
|
||||
storagePool: "storagePool",
|
||||
@ -64,7 +71,6 @@ var (
|
||||
readOnly: "readOnly",
|
||||
username: "username",
|
||||
password: "password",
|
||||
namespace: "namespace",
|
||||
sdcGuid: "sdcGuid",
|
||||
}
|
||||
sdcGuidLabelName = "scaleio.sdcGuid"
|
||||
@ -79,23 +85,32 @@ var (
|
||||
protectionDomainNotProvidedErr = errors.New("ScaleIO protection domain not provided")
|
||||
)
|
||||
|
||||
// mapScaleIOVolumeSource maps attributes from a ScaleIOVolumeSource to config
|
||||
func mapVolumeSource(config map[string]string, source *api.ScaleIOVolumeSource) {
|
||||
config[confKey.gateway] = source.Gateway
|
||||
config[confKey.secretRef] = func() string {
|
||||
if source.SecretRef != nil {
|
||||
return string(source.SecretRef.Name)
|
||||
}
|
||||
return ""
|
||||
}()
|
||||
config[confKey.system] = source.System
|
||||
config[confKey.volumeName] = source.VolumeName
|
||||
config[confKey.sslEnabled] = strconv.FormatBool(source.SSLEnabled)
|
||||
config[confKey.protectionDomain] = source.ProtectionDomain
|
||||
config[confKey.storagePool] = source.StoragePool
|
||||
config[confKey.storageMode] = source.StorageMode
|
||||
config[confKey.fsType] = source.FSType
|
||||
config[confKey.readOnly] = strconv.FormatBool(source.ReadOnly)
|
||||
// mapVolumeSpec maps attributes from either ScaleIOVolumeSource or ScaleIOPersistentVolumeSource to config
|
||||
func mapVolumeSpec(config map[string]string, spec *volume.Spec) {
|
||||
|
||||
if source, err := getScaleIOPersistentVolumeSourceFromSpec(spec); err == nil {
|
||||
config[confKey.gateway] = source.Gateway
|
||||
config[confKey.system] = source.System
|
||||
config[confKey.volumeName] = source.VolumeName
|
||||
config[confKey.sslEnabled] = strconv.FormatBool(source.SSLEnabled)
|
||||
config[confKey.protectionDomain] = source.ProtectionDomain
|
||||
config[confKey.storagePool] = source.StoragePool
|
||||
config[confKey.storageMode] = source.StorageMode
|
||||
config[confKey.fsType] = source.FSType
|
||||
config[confKey.readOnly] = strconv.FormatBool(source.ReadOnly)
|
||||
}
|
||||
|
||||
if source, err := getScaleIOVolumeSourceFromSpec(spec); err == nil {
|
||||
config[confKey.gateway] = source.Gateway
|
||||
config[confKey.system] = source.System
|
||||
config[confKey.volumeName] = source.VolumeName
|
||||
config[confKey.sslEnabled] = strconv.FormatBool(source.SSLEnabled)
|
||||
config[confKey.protectionDomain] = source.ProtectionDomain
|
||||
config[confKey.storagePool] = source.StoragePool
|
||||
config[confKey.storageMode] = source.StorageMode
|
||||
config[confKey.fsType] = source.FSType
|
||||
config[confKey.readOnly] = strconv.FormatBool(source.ReadOnly)
|
||||
}
|
||||
|
||||
//optionals
|
||||
applyConfigDefaults(config)
|
||||
@ -105,7 +120,7 @@ func validateConfigs(config map[string]string) error {
|
||||
if config[confKey.gateway] == "" {
|
||||
return gatewayNotProvidedErr
|
||||
}
|
||||
if config[confKey.secretRef] == "" {
|
||||
if config[confKey.secretName] == "" {
|
||||
return secretRefNotProvidedErr
|
||||
}
|
||||
if config[confKey.system] == "" {
|
||||
@ -202,7 +217,7 @@ func saveConfig(configName string, data map[string]string) error {
|
||||
// attachSecret loads secret object and attaches to configData
|
||||
func attachSecret(plug *sioPlugin, namespace string, configData map[string]string) error {
|
||||
// load secret
|
||||
secretRefName := configData[confKey.secretRef]
|
||||
secretRefName := configData[confKey.secretName]
|
||||
kubeClient := plug.host.GetKubeClient()
|
||||
secretMap, err := volutil.GetSecretForPV(namespace, secretRefName, sioPluginName, kubeClient)
|
||||
if err != nil {
|
||||
@ -244,8 +259,8 @@ func getSdcGuidLabel(plug *sioPlugin) (string, error) {
|
||||
return label, nil
|
||||
}
|
||||
|
||||
// getVolumeSourceFromSpec safely extracts ScaleIOVolumeSource from spec
|
||||
func getVolumeSourceFromSpec(spec *volume.Spec) (*api.ScaleIOVolumeSource, error) {
|
||||
// getVolumeSourceFromSpec safely extracts ScaleIOVolumeSource or ScaleIOPersistentVolumeSource from spec
|
||||
func getVolumeSourceFromSpec(spec *volume.Spec) (interface{}, error) {
|
||||
if spec.Volume != nil && spec.Volume.ScaleIO != nil {
|
||||
return spec.Volume.ScaleIO, nil
|
||||
}
|
||||
@ -257,6 +272,66 @@ func getVolumeSourceFromSpec(spec *volume.Spec) (*api.ScaleIOVolumeSource, error
|
||||
return nil, fmt.Errorf("ScaleIO not defined in spec")
|
||||
}
|
||||
|
||||
func getVolumeSourceAttribs(spec *volume.Spec) (*volSourceAttribs, error) {
|
||||
attribs := new(volSourceAttribs)
|
||||
if pvSource, err := getScaleIOPersistentVolumeSourceFromSpec(spec); err == nil {
|
||||
attribs.volName = pvSource.VolumeName
|
||||
attribs.fsType = pvSource.FSType
|
||||
attribs.readOnly = pvSource.ReadOnly
|
||||
} else if pSource, err := getScaleIOVolumeSourceFromSpec(spec); err == nil {
|
||||
attribs.volName = pSource.VolumeName
|
||||
attribs.fsType = pSource.FSType
|
||||
attribs.readOnly = pSource.ReadOnly
|
||||
} else {
|
||||
msg := log("failed to get ScaleIOVolumeSource or ScaleIOPersistentVolumeSource from spec")
|
||||
glog.Error(msg)
|
||||
return nil, errors.New(msg)
|
||||
}
|
||||
return attribs, nil
|
||||
}
|
||||
|
||||
func getScaleIOPersistentVolumeSourceFromSpec(spec *volume.Spec) (*api.ScaleIOPersistentVolumeSource, error) {
|
||||
source, err := getVolumeSourceFromSpec(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if val, ok := source.(*api.ScaleIOPersistentVolumeSource); ok {
|
||||
return val, nil
|
||||
}
|
||||
return nil, fmt.Errorf("spec is not a valid ScaleIOPersistentVolume type")
|
||||
}
|
||||
|
||||
func getScaleIOVolumeSourceFromSpec(spec *volume.Spec) (*api.ScaleIOVolumeSource, error) {
|
||||
source, err := getVolumeSourceFromSpec(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if val, ok := source.(*api.ScaleIOVolumeSource); ok {
|
||||
return val, nil
|
||||
}
|
||||
return nil, fmt.Errorf("spec is not a valid ScaleIOVolume type")
|
||||
}
|
||||
|
||||
func getSecretAndNamespaceFromSpec(spec *volume.Spec, pod *api.Pod) (secretName string, secretNS string, err error) {
|
||||
if source, err := getScaleIOVolumeSourceFromSpec(spec); err == nil {
|
||||
secretName = source.SecretRef.Name
|
||||
if pod != nil {
|
||||
secretNS = pod.Namespace
|
||||
}
|
||||
} else if source, err := getScaleIOPersistentVolumeSourceFromSpec(spec); err == nil {
|
||||
if source.SecretRef != nil {
|
||||
secretName = source.SecretRef.Name
|
||||
secretNS = source.SecretRef.Namespace
|
||||
if secretNS == "" && pod != nil {
|
||||
secretNS = pod.Namespace
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return "", "", errors.New("failed to get ScaleIOVolumeSource or ScaleIOPersistentVolumeSource")
|
||||
}
|
||||
return secretName, secretNS, nil
|
||||
}
|
||||
|
||||
func log(msg string, parts ...interface{}) string {
|
||||
return fmt.Sprintf(fmt.Sprintf("scaleio: %s", msg), parts...)
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -48,7 +49,7 @@ var (
|
||||
confKey.gateway: "http://sio/",
|
||||
confKey.volSpecName: testSioVolName,
|
||||
confKey.volumeName: "sio-vol",
|
||||
confKey.secretRef: "sio-secret",
|
||||
confKey.secretName: "sio-secret",
|
||||
confKey.protectionDomain: "defaultPD",
|
||||
confKey.storagePool: "deraultSP",
|
||||
confKey.fsType: "xfs",
|
||||
@ -60,7 +61,7 @@ var (
|
||||
|
||||
func TestUtilMapVolumeSource(t *testing.T) {
|
||||
data := make(map[string]string)
|
||||
mapVolumeSource(data, vol.VolumeSource.ScaleIO)
|
||||
mapVolumeSpec(data, volume.NewSpecFromVolume(vol))
|
||||
if data[confKey.gateway] != "http://test.scaleio:1111" {
|
||||
t.Error("Unexpected gateway value")
|
||||
}
|
||||
@ -79,9 +80,6 @@ func TestUtilMapVolumeSource(t *testing.T) {
|
||||
if data[confKey.fsType] != "ext4" {
|
||||
t.Error("Unexpected fstype value")
|
||||
}
|
||||
if data[confKey.secretRef] != "test-secret" {
|
||||
t.Error("Unexpected secret ref value")
|
||||
}
|
||||
if data[confKey.sslEnabled] != "false" {
|
||||
t.Error("Unexpected sslEnabled value")
|
||||
}
|
||||
@ -92,8 +90,8 @@ func TestUtilMapVolumeSource(t *testing.T) {
|
||||
|
||||
func TestUtilValidateConfigs(t *testing.T) {
|
||||
data := map[string]string{
|
||||
confKey.secretRef: "sio-secret",
|
||||
confKey.system: "sio",
|
||||
confKey.secretName: "sio-secret",
|
||||
confKey.system: "sio",
|
||||
}
|
||||
if err := validateConfigs(data); err != gatewayNotProvidedErr {
|
||||
t.Error("Expecting error for missing gateway, but did not get it")
|
||||
@ -105,7 +103,7 @@ func TestUtilApplyConfigDefaults(t *testing.T) {
|
||||
confKey.system: "sio",
|
||||
confKey.gateway: "http://sio/",
|
||||
confKey.volumeName: "sio-vol",
|
||||
confKey.secretRef: "test-secret",
|
||||
confKey.secretName: "test-secret",
|
||||
}
|
||||
applyConfigDefaults(data)
|
||||
|
||||
@ -130,7 +128,7 @@ func TestUtilApplyConfigDefaults(t *testing.T) {
|
||||
if data[confKey.storageMode] != "ThinProvisioned" {
|
||||
t.Error("Unexpected storage mode value")
|
||||
}
|
||||
if data[confKey.secretRef] != "test-secret" {
|
||||
if data[confKey.secretName] != "test-secret" {
|
||||
t.Error("Unexpected secret ref value")
|
||||
}
|
||||
if data[confKey.sslEnabled] != "false" {
|
||||
@ -157,7 +155,7 @@ func TestUtilSaveConfig(t *testing.T) {
|
||||
config := path.Join(tmpDir, testConfigFile)
|
||||
data := map[string]string{
|
||||
confKey.gateway: "https://test-gateway/",
|
||||
confKey.secretRef: "sio-secret",
|
||||
confKey.secretName: "sio-secret",
|
||||
confKey.sslEnabled: "false",
|
||||
}
|
||||
if err := saveConfig(config, data); err != nil {
|
||||
@ -178,7 +176,7 @@ func TestUtilSaveConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUtilAttachSecret(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t)
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret(testSecret, testns))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plug, err := plugMgr.FindPluginByName(sioPluginName)
|
||||
|
@ -37,19 +37,19 @@ import (
|
||||
)
|
||||
|
||||
type sioVolume struct {
|
||||
sioMgr *sioMgr
|
||||
plugin *sioPlugin
|
||||
pod *api.Pod
|
||||
podUID types.UID
|
||||
spec *volume.Spec
|
||||
source *api.ScaleIOVolumeSource
|
||||
namespace string
|
||||
volSpecName string
|
||||
volName string
|
||||
readOnly bool
|
||||
fsType string
|
||||
options volume.VolumeOptions
|
||||
configData map[string]string
|
||||
sioMgr *sioMgr
|
||||
plugin *sioPlugin
|
||||
pod *api.Pod
|
||||
podUID types.UID
|
||||
spec *volume.Spec
|
||||
secretName string
|
||||
secretNamespace string
|
||||
volSpecName string
|
||||
volName string
|
||||
readOnly bool
|
||||
fsType string
|
||||
options volume.VolumeOptions
|
||||
configData map[string]string
|
||||
|
||||
volume.MetricsNil
|
||||
}
|
||||
@ -59,7 +59,6 @@ type sioVolume struct {
|
||||
var _ volume.Volume = &sioVolume{}
|
||||
|
||||
// GetPath returns the path where the volume will be mounted.
|
||||
// The volumeName is prefixed with the pod's namespace a <pod.Namespace>-<volumeName>
|
||||
func (v *sioVolume) GetPath() string {
|
||||
return v.plugin.host.GetPodVolumeDir(
|
||||
v.podUID,
|
||||
@ -128,11 +127,11 @@ func (v *sioVolume) SetUpAt(dir string, fsGroup *int64) error {
|
||||
switch {
|
||||
default:
|
||||
options = append(options, "rw")
|
||||
case isROM && !v.source.ReadOnly:
|
||||
case isROM && !v.readOnly:
|
||||
options = append(options, "rw")
|
||||
case isROM:
|
||||
options = append(options, "ro")
|
||||
case v.source.ReadOnly:
|
||||
case v.readOnly:
|
||||
options = append(options, "ro")
|
||||
}
|
||||
|
||||
@ -327,10 +326,10 @@ func (v *sioVolume) Provision() (*api.PersistentVolume, error) {
|
||||
),
|
||||
},
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
ScaleIO: &api.ScaleIOVolumeSource{
|
||||
ScaleIO: &api.ScaleIOPersistentVolumeSource{
|
||||
Gateway: v.configData[confKey.gateway],
|
||||
SSLEnabled: sslEnabled,
|
||||
SecretRef: &api.LocalObjectReference{Name: v.configData[confKey.secretRef]},
|
||||
SecretRef: &api.SecretReference{Name: v.secretName, Namespace: v.secretNamespace},
|
||||
System: v.configData[confKey.system],
|
||||
ProtectionDomain: v.configData[confKey.protectionDomain],
|
||||
StoragePool: v.configData[confKey.storagePool],
|
||||
@ -366,13 +365,17 @@ func (v *sioVolume) setSioMgr() error {
|
||||
glog.V(4).Info(log("previous config file not found, creating new one"))
|
||||
// prepare config data
|
||||
configData = make(map[string]string)
|
||||
mapVolumeSource(configData, v.source)
|
||||
mapVolumeSpec(configData, v.spec)
|
||||
|
||||
// additional config data
|
||||
configData[confKey.secretNamespace] = v.secretNamespace
|
||||
configData[confKey.secretName] = v.secretName
|
||||
configData[confKey.volSpecName] = v.volSpecName
|
||||
|
||||
if err := validateConfigs(configData); err != nil {
|
||||
glog.Error(log("config setup failed: %s", err))
|
||||
return err
|
||||
}
|
||||
configData[confKey.namespace] = v.namespace
|
||||
configData[confKey.volSpecName] = v.volSpecName
|
||||
|
||||
// persist config
|
||||
if err := saveConfig(configName, configData); err != nil {
|
||||
@ -381,7 +384,7 @@ func (v *sioVolume) setSioMgr() error {
|
||||
}
|
||||
}
|
||||
// merge in secret
|
||||
if err := attachSecret(v.plugin, v.namespace, configData); err != nil {
|
||||
if err := attachSecret(v.plugin, v.secretNamespace, configData); err != nil {
|
||||
glog.Error(log("failed to load secret: %v", err))
|
||||
return err
|
||||
}
|
||||
@ -414,12 +417,13 @@ func (v *sioVolume) resetSioMgr() error {
|
||||
glog.Error(log("failed to load config data: %v", err))
|
||||
return err
|
||||
}
|
||||
v.namespace = configData[confKey.namespace]
|
||||
v.secretName = configData[confKey.secretName]
|
||||
v.secretNamespace = configData[confKey.secretNamespace]
|
||||
v.volName = configData[confKey.volumeName]
|
||||
v.volSpecName = configData[confKey.volSpecName]
|
||||
|
||||
// attach secret
|
||||
if err := attachSecret(v.plugin, v.namespace, configData); err != nil {
|
||||
if err := attachSecret(v.plugin, v.secretNamespace, configData); err != nil {
|
||||
glog.Error(log("failed to load secret: %v", err))
|
||||
return err
|
||||
}
|
||||
@ -446,21 +450,22 @@ func (v *sioVolume) resetSioMgr() error {
|
||||
func (v *sioVolume) setSioMgrFromConfig() error {
|
||||
glog.V(4).Info(log("setting scaleio mgr from available config"))
|
||||
if v.sioMgr == nil {
|
||||
configData := v.configData
|
||||
applyConfigDefaults(configData)
|
||||
if err := validateConfigs(configData); err != nil {
|
||||
applyConfigDefaults(v.configData)
|
||||
|
||||
v.configData[confKey.volSpecName] = v.volSpecName
|
||||
|
||||
if err := validateConfigs(v.configData); err != nil {
|
||||
glog.Error(log("config data setup failed: %s", err))
|
||||
return err
|
||||
}
|
||||
configData[confKey.namespace] = v.namespace
|
||||
configData[confKey.volSpecName] = v.volSpecName
|
||||
|
||||
// copy config and attach secret
|
||||
data := map[string]string{}
|
||||
for k, v := range configData {
|
||||
for k, v := range v.configData {
|
||||
data[k] = v
|
||||
}
|
||||
if err := attachSecret(v.plugin, v.namespace, data); err != nil {
|
||||
|
||||
if err := attachSecret(v.plugin, v.secretNamespace, data); err != nil {
|
||||
glog.Error(log("failed to load secret: %v", err))
|
||||
return err
|
||||
}
|
||||
@ -483,16 +488,20 @@ func (v *sioVolume) setSioMgrFromSpec() error {
|
||||
if v.sioMgr == nil {
|
||||
// get config data form spec volume source
|
||||
configData := map[string]string{}
|
||||
mapVolumeSource(configData, v.source)
|
||||
mapVolumeSpec(configData, v.spec)
|
||||
|
||||
// additional config
|
||||
configData[confKey.secretNamespace] = v.secretNamespace
|
||||
configData[confKey.secretName] = v.secretName
|
||||
configData[confKey.volSpecName] = v.volSpecName
|
||||
|
||||
if err := validateConfigs(configData); err != nil {
|
||||
glog.Error(log("config setup failed: %s", err))
|
||||
return err
|
||||
}
|
||||
configData[confKey.namespace] = v.namespace
|
||||
configData[confKey.volSpecName] = v.volSpecName
|
||||
|
||||
// attach secret object to config data
|
||||
if err := attachSecret(v.plugin, v.namespace, configData); err != nil {
|
||||
if err := attachSecret(v.plugin, v.secretNamespace, configData); err != nil {
|
||||
glog.Error(log("failed to load secret: %v", err))
|
||||
return err
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
fakeclient "k8s.io/client-go/kubernetes/fake"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
@ -39,29 +40,18 @@ var (
|
||||
testSioPD = "default"
|
||||
testSioVol = "vol-0001"
|
||||
testns = "default"
|
||||
testSecret = "sio-secret"
|
||||
testSioVolName = fmt.Sprintf("%s%s%s", testns, "-", testSioVol)
|
||||
podUID = types.UID("sio-pod")
|
||||
)
|
||||
|
||||
func newPluginMgr(t *testing.T) (*volume.VolumePluginMgr, string) {
|
||||
func newPluginMgr(t *testing.T, apiObject runtime.Object) (*volume.VolumePluginMgr, string) {
|
||||
tmpDir, err := utiltesting.MkTmpdir("scaleio-test")
|
||||
if err != nil {
|
||||
t.Fatalf("can't make a temp dir: %v", err)
|
||||
}
|
||||
config := &api.Secret{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "sio-secret",
|
||||
Namespace: testns,
|
||||
UID: "1234567890",
|
||||
},
|
||||
Type: api.SecretType("kubernetes.io/scaleio"),
|
||||
Data: map[string][]byte{
|
||||
"username": []byte("username"),
|
||||
"password": []byte("password"),
|
||||
},
|
||||
}
|
||||
|
||||
fakeClient := fakeclient.NewSimpleClientset(config)
|
||||
fakeClient := fakeclient.NewSimpleClientset(apiObject)
|
||||
host := volumetest.NewFakeVolumeHostWithNodeLabels(
|
||||
tmpDir,
|
||||
fakeClient,
|
||||
@ -74,8 +64,23 @@ func newPluginMgr(t *testing.T) (*volume.VolumePluginMgr, string) {
|
||||
return plugMgr, tmpDir
|
||||
}
|
||||
|
||||
func makeScaleIOSecret(name, namespace string) *api.Secret {
|
||||
return &api.Secret{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
UID: "1234567890",
|
||||
},
|
||||
Type: api.SecretType("kubernetes.io/scaleio"),
|
||||
Data: map[string][]byte{
|
||||
"username": []byte("username"),
|
||||
"password": []byte("password"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestVolumeCanSupport(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t)
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret(testSecret, testns))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
plug, err := plugMgr.FindPluginByName(sioPluginName)
|
||||
if err != nil {
|
||||
@ -100,7 +105,7 @@ func TestVolumeCanSupport(t *testing.T) {
|
||||
PersistentVolume: &api.PersistentVolume{
|
||||
Spec: api.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
ScaleIO: &api.ScaleIOVolumeSource{},
|
||||
ScaleIO: &api.ScaleIOPersistentVolumeSource{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -111,7 +116,7 @@ func TestVolumeCanSupport(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVolumeGetAccessModes(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t)
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret(testSecret, testns))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
plug, err := plugMgr.FindPersistentPluginByName(sioPluginName)
|
||||
if err != nil {
|
||||
@ -131,7 +136,7 @@ func containsMode(modes []api.PersistentVolumeAccessMode, mode api.PersistentVol
|
||||
}
|
||||
|
||||
func TestVolumeMounterUnmounter(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t)
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret(testSecret, testns))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plug, err := plugMgr.FindPluginByName(sioPluginName)
|
||||
@ -153,7 +158,7 @@ func TestVolumeMounterUnmounter(t *testing.T) {
|
||||
StoragePool: "default",
|
||||
VolumeName: testSioVol,
|
||||
FSType: "ext4",
|
||||
SecretRef: &api.LocalObjectReference{Name: "sio-secret"},
|
||||
SecretRef: &api.LocalObjectReference{Name: testSecret},
|
||||
ReadOnly: false,
|
||||
},
|
||||
},
|
||||
@ -245,7 +250,7 @@ func TestVolumeMounterUnmounter(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVolumeProvisioner(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t)
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret(testSecret, testns))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plug, err := plugMgr.FindPluginByName(sioPluginName)
|
||||
@ -274,7 +279,7 @@ func TestVolumeProvisioner(t *testing.T) {
|
||||
confKey.system: "sio",
|
||||
confKey.protectionDomain: testSioPD,
|
||||
confKey.storagePool: "default",
|
||||
confKey.secretRef: "sio-secret",
|
||||
confKey.secretName: testSecret,
|
||||
}
|
||||
|
||||
provisioner, err := sioPlug.NewProvisioner(options)
|
||||
@ -296,6 +301,17 @@ func TestVolumeProvisioner(t *testing.T) {
|
||||
t.Fatalf("call to Provision() failed: %v", err)
|
||||
}
|
||||
|
||||
if spec.Namespace != testns {
|
||||
t.Fatalf("unexpected namespace %v", spec.Namespace)
|
||||
}
|
||||
if spec.Spec.ScaleIO.SecretRef == nil {
|
||||
t.Fatalf("unexpected nil value for spec.SecretRef")
|
||||
}
|
||||
if spec.Spec.ScaleIO.SecretRef.Name != testSecret ||
|
||||
spec.Spec.ScaleIO.SecretRef.Namespace != testns {
|
||||
t.Fatalf("spec.SecretRef is not being set properly")
|
||||
}
|
||||
|
||||
spec.Spec.ClaimRef = &api.ObjectReference{Namespace: testns}
|
||||
|
||||
// validate provision
|
||||
@ -379,7 +395,7 @@ func TestVolumeProvisioner(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVolumeProvisionerWithIncompleteConfig(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t)
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret(testSecret, testns))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plug, err := plugMgr.FindPluginByName(sioPluginName)
|
||||
@ -411,7 +427,7 @@ func TestVolumeProvisionerWithIncompleteConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVolumeProvisionerWithZeroCapacity(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t)
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret(testSecret, testns))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plug, err := plugMgr.FindPluginByName(sioPluginName)
|
||||
@ -440,7 +456,7 @@ func TestVolumeProvisionerWithZeroCapacity(t *testing.T) {
|
||||
confKey.system: "sio",
|
||||
confKey.protectionDomain: testSioPD,
|
||||
confKey.storagePool: "default",
|
||||
confKey.secretRef: "sio-secret",
|
||||
confKey.secretName: "sio-secret",
|
||||
}
|
||||
|
||||
provisioner, _ := sioPlug.NewProvisioner(options)
|
||||
@ -457,3 +473,63 @@ func TestVolumeProvisionerWithZeroCapacity(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestVolumeProvisionerWithSecretNamespace(t *testing.T) {
|
||||
plugMgr, tmpDir := newPluginMgr(t, makeScaleIOSecret("sio-sec", "sio-ns"))
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
plug, err := plugMgr.FindPluginByName(sioPluginName)
|
||||
if err != nil {
|
||||
t.Fatalf("Can't find the plugin %v", sioPluginName)
|
||||
}
|
||||
sioPlug, ok := plug.(*sioPlugin)
|
||||
if !ok {
|
||||
t.Fatal("Cannot assert plugin to be type sioPlugin")
|
||||
}
|
||||
|
||||
options := volume.VolumeOptions{
|
||||
ClusterName: "testcluster",
|
||||
PVName: "pvc-sio-dynamic-vol",
|
||||
PVC: volumetest.CreateTestPVC("100Mi", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}),
|
||||
PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimDelete,
|
||||
}
|
||||
|
||||
options.PVC.Spec.AccessModes = []api.PersistentVolumeAccessMode{
|
||||
api.ReadWriteOnce,
|
||||
}
|
||||
|
||||
options.PVC.Namespace = "pvc-ns"
|
||||
options.Parameters = map[string]string{
|
||||
confKey.gateway: "http://test.scaleio:11111",
|
||||
confKey.system: "sio",
|
||||
confKey.protectionDomain: testSioPD,
|
||||
confKey.storagePool: "default",
|
||||
confKey.secretName: "sio-sec",
|
||||
confKey.secretNamespace: "sio-ns",
|
||||
}
|
||||
|
||||
provisioner, _ := sioPlug.NewProvisioner(options)
|
||||
sio := newFakeSio()
|
||||
sioVol := provisioner.(*sioVolume)
|
||||
if err := sioVol.setSioMgrFromConfig(); err != nil {
|
||||
t.Fatalf("failed to create scaleio mgr from config: %v", err)
|
||||
}
|
||||
sioVol.sioMgr.client = sio
|
||||
|
||||
spec, err := sioVol.Provision()
|
||||
if err != nil {
|
||||
t.Fatalf("call to Provision() failed: %v", err)
|
||||
}
|
||||
|
||||
if spec.GetObjectMeta().GetNamespace() != "pvc-ns" {
|
||||
t.Fatalf("unexpected spec.namespace %s", spec.GetObjectMeta().GetNamespace())
|
||||
}
|
||||
|
||||
if spec.Spec.ScaleIO.SecretRef.Name != "sio-sec" {
|
||||
t.Fatalf("unexpected spec.ScaleIOPersistentVolume.SecretRef.Name %v", spec.Spec.ScaleIO.SecretRef.Name)
|
||||
}
|
||||
|
||||
if spec.Spec.ScaleIO.SecretRef.Namespace != "sio-ns" {
|
||||
t.Fatalf("unexpected spec.ScaleIOPersistentVolume.SecretRef.Namespace %v", spec.Spec.ScaleIO.SecretRef.Namespace)
|
||||
}
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ type PersistentVolumeSource struct {
|
||||
PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" protobuf:"bytes,18,opt,name=portworxVolume"`
|
||||
// ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.
|
||||
// +optional
|
||||
ScaleIO *ScaleIOVolumeSource `json:"scaleIO,omitempty" protobuf:"bytes,19,opt,name=scaleIO"`
|
||||
ScaleIO *ScaleIOPersistentVolumeSource `json:"scaleIO,omitempty" protobuf:"bytes,19,opt,name=scaleIO"`
|
||||
// Local represents directly-attached storage with node affinity
|
||||
// +optional
|
||||
Local *LocalVolumeSource `json:"local,omitempty" protobuf:"bytes,20,opt,name=local"`
|
||||
@ -1396,13 +1396,48 @@ type ScaleIOVolumeSource struct {
|
||||
// Flag to enable/disable SSL communication with Gateway, default false
|
||||
// +optional
|
||||
SSLEnabled bool `json:"sslEnabled,omitempty" protobuf:"varint,4,opt,name=sslEnabled"`
|
||||
// The name of the Protection Domain for the configured storage (defaults to "default").
|
||||
// The name of the ScaleIO Protection Domain for the configured storage.
|
||||
// +optional
|
||||
ProtectionDomain string `json:"protectionDomain,omitempty" protobuf:"bytes,5,opt,name=protectionDomain"`
|
||||
// The Storage Pool associated with the protection domain (defaults to "default").
|
||||
// The ScaleIO Storage Pool associated with the protection domain.
|
||||
// +optional
|
||||
StoragePool string `json:"storagePool,omitempty" protobuf:"bytes,6,opt,name=storagePool"`
|
||||
// Indicates whether the storage for a volume should be thick or thin (defaults to "thin").
|
||||
// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
|
||||
// +optional
|
||||
StorageMode string `json:"storageMode,omitempty" protobuf:"bytes,7,opt,name=storageMode"`
|
||||
// The name of a volume already created in the ScaleIO system
|
||||
// that is associated with this volume source.
|
||||
VolumeName string `json:"volumeName,omitempty" protobuf:"bytes,8,opt,name=volumeName"`
|
||||
// Filesystem type to mount.
|
||||
// Must be a filesystem type supported by the host operating system.
|
||||
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// +optional
|
||||
FSType string `json:"fsType,omitempty" protobuf:"bytes,9,opt,name=fsType"`
|
||||
// Defaults to false (read/write). ReadOnly here will force
|
||||
// the ReadOnly setting in VolumeMounts.
|
||||
// +optional
|
||||
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,10,opt,name=readOnly"`
|
||||
}
|
||||
|
||||
// ScaleIOPersistentVolumeSource represents a persistent ScaleIO volume
|
||||
type ScaleIOPersistentVolumeSource struct {
|
||||
// The host address of the ScaleIO API Gateway.
|
||||
Gateway string `json:"gateway" protobuf:"bytes,1,opt,name=gateway"`
|
||||
// The name of the storage system as configured in ScaleIO.
|
||||
System string `json:"system" protobuf:"bytes,2,opt,name=system"`
|
||||
// SecretRef references to the secret for ScaleIO user and other
|
||||
// sensitive information. If this is not provided, Login operation will fail.
|
||||
SecretRef *SecretReference `json:"secretRef" protobuf:"bytes,3,opt,name=secretRef"`
|
||||
// Flag to enable/disable SSL communication with Gateway, default false
|
||||
// +optional
|
||||
SSLEnabled bool `json:"sslEnabled,omitempty" protobuf:"varint,4,opt,name=sslEnabled"`
|
||||
// The name of the ScaleIO Protection Domain for the configured storage.
|
||||
// +optional
|
||||
ProtectionDomain string `json:"protectionDomain,omitempty" protobuf:"bytes,5,opt,name=protectionDomain"`
|
||||
// The ScaleIO Storage Pool associated with the protection domain.
|
||||
// +optional
|
||||
StoragePool string `json:"storagePool,omitempty" protobuf:"bytes,6,opt,name=storagePool"`
|
||||
// Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.
|
||||
// +optional
|
||||
StorageMode string `json:"storageMode,omitempty" protobuf:"bytes,7,opt,name=storageMode"`
|
||||
// The name of a volume already created in the ScaleIO system
|
||||
|
Loading…
Reference in New Issue
Block a user