ScaleIO - API source code update

This commit tracks all human-generated code for API source updates.
This commit is contained in:
Vladimir Vivien
2017-10-13 22:57:37 -04:00
parent 7b588817ca
commit 3fb3cc7122
14 changed files with 455 additions and 154 deletions

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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...)
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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)
}
}