2017-09-14 09:40:34 -07:00
/*
Copyright 2017 The Rook Authors. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package flexvolume to manage Kubernetes storage attach events.
package flexvolume
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"os"
"testing"
2017-12-04 08:33:19 -08:00
rookalpha "github.com/rook/rook/pkg/apis/rook.io/v1alpha1"
2017-12-04 09:03:06 -08:00
rookclient "github.com/rook/rook/pkg/client/clientset/versioned/fake"
2017-09-14 09:40:34 -07:00
"github.com/rook/rook/pkg/clusterd"
2017-12-04 08:33:19 -08:00
"github.com/rook/rook/pkg/daemon/agent/flexvolume/attachment"
"github.com/rook/rook/pkg/daemon/agent/flexvolume/manager"
2017-09-14 09:40:34 -07:00
"github.com/rook/rook/pkg/operator/k8sutil"
"github.com/rook/rook/pkg/operator/test"
"github.com/stretchr/testify/assert"
"k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1"
2017-12-04 09:03:06 -08:00
"k8s.io/apimachinery/pkg/api/errors"
2017-09-14 09:40:34 -07:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
func TestAttach ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
devicePath := ""
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
ClusterName : "testCluster" ,
StorageClass : "storageclass1" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "myPod" ,
PodNamespace : "Default" ,
RW : "rw" ,
}
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
2017-09-14 09:40:34 -07:00
2017-12-04 08:33:19 -08:00
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Attach ( opts , & devicePath )
2017-09-14 09:40:34 -07:00
assert . Nil ( t , err )
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Get ( "pvc-123" , metav1 . GetOptions {})
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
assert . Equal ( t , 1 , len ( volumeAttachment . Attachments ))
a := volumeAttachment . Attachments [ 0 ]
assert . Equal ( t , "node1" , a . Node )
assert . Equal ( t , "Default" , a . PodNamespace )
assert . Equal ( t , "myPod" , a . PodName )
assert . Equal ( t , "testCluster" , a . ClusterName )
assert . Equal ( t , "/test/pods/pod123/volumes/rook.io~rook/pvc-123" , a . MountDir )
assert . False ( t , a . ReadOnly )
2017-09-14 09:40:34 -07:00
}
func TestAttachAlreadyExist ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
pod := v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "otherpod" ,
Namespace : "Default" ,
},
Status : v1 . PodStatus {
Phase : "running" ,
},
}
clientset . CoreV1 (). Pods ( "Default" ). Create ( & pod )
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-12-04 09:03:06 -08:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {
2017-09-14 09:40:34 -07:00
{
Node : "node1" ,
PodNamespace : "Default" ,
PodName : "otherpod" ,
MountDir : "/tmt/test" ,
ReadOnly : false ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-09-14 09:40:34 -07:00
var devicePath * string
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
StorageClass : "storageclass1" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "myPod" ,
PodNamespace : "Default" ,
RW : "rw" ,
}
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Attach ( opts , devicePath )
2017-09-14 09:40:34 -07:00
assert . NotNil ( t , err )
2017-10-16 10:51:03 -07:00
assert . Equal ( t , "failed to attach volume pvc-123 for pod Default/myPod. Volume is already attached by pod Default/otherpod. Status running" , err . Error ())
2017-09-14 09:40:34 -07:00
}
func TestAttachReadOnlyButRWAlreadyExist ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
pod := v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "otherpod" ,
Namespace : "Default" ,
},
Status : v1 . PodStatus {
Phase : "running" ,
},
}
clientset . CoreV1 (). Pods ( "Default" ). Create ( & pod )
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-12-04 09:03:06 -08:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {
2017-09-14 09:40:34 -07:00
{
Node : "node1" ,
PodNamespace : "Default" ,
PodName : "otherpod" ,
MountDir : "/tmt/test" ,
ReadOnly : false ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-09-14 09:40:34 -07:00
var devicePath * string
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
StorageClass : "storageclass1" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "myPod" ,
PodNamespace : "Default" ,
RW : "ro" ,
}
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Attach ( opts , devicePath )
2017-09-14 09:40:34 -07:00
assert . NotNil ( t , err )
2017-10-16 10:51:03 -07:00
assert . Equal ( t , "failed to attach volume pvc-123 for pod Default/myPod. Volume is already attached by pod Default/otherpod. Status running" , err . Error ())
2017-09-14 09:40:34 -07:00
}
func TestAttachRWButROAlreadyExist ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-12-04 09:03:06 -08:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {
2017-09-14 09:40:34 -07:00
{
Node : "node1" ,
PodNamespace : "Default" ,
PodName : "otherpod" ,
MountDir : "/tmt/test" ,
ReadOnly : true ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-09-14 09:40:34 -07:00
var devicePath * string
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
StorageClass : "storageclass1" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "myPod" ,
PodNamespace : "Default" ,
RW : "rw" ,
}
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
2017-09-14 09:40:34 -07:00
2017-12-04 08:33:19 -08:00
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Attach ( opts , devicePath )
2017-09-14 09:40:34 -07:00
assert . NotNil ( t , err )
2017-10-16 10:51:03 -07:00
assert . Equal ( t , "failed to attach volume pvc-123 for pod Default/myPod. Volume is already attached by one or more pods" , err . Error ())
2017-09-14 09:40:34 -07:00
}
func TestMultipleAttachReadOnly ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
2017-12-04 09:03:06 -08:00
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
ClusterName : "testCluster" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "myPod" ,
PodNamespace : "Default" ,
RW : "ro" ,
}
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-09-14 09:40:34 -07:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {
2017-09-14 09:40:34 -07:00
{
Node : "otherNode" ,
PodNamespace : "Default" ,
PodName : "myPod" ,
MountDir : "/tmt/test" ,
ReadOnly : true ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-09-14 09:40:34 -07:00
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
2017-09-14 09:40:34 -07:00
devicePath := ""
2017-12-04 08:33:19 -08:00
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Attach ( opts , & devicePath )
2017-09-14 09:40:34 -07:00
assert . Nil ( t , err )
2017-12-04 09:03:06 -08:00
volAtt , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Get ( "pvc-123" , metav1 . GetOptions {})
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
assert . Equal ( t , 2 , len ( volAtt . Attachments ))
assert . True ( t , containsAttachment (
rookalpha . Attachment {
PodNamespace : opts . PodNamespace ,
PodName : opts . Pod ,
MountDir : opts . MountDir ,
ReadOnly : true ,
Node : "node1" ,
}, volAtt . Attachments ,
), "VolumeAttachment crd does not contain expected attachment" )
assert . True ( t , containsAttachment (
existingCRD . Attachments [ 0 ], volAtt . Attachments ,
), "VolumeAttachment crd does not contain expected attachment" )
2017-09-14 09:40:34 -07:00
}
2017-12-01 10:22:40 -08:00
func TestOrphanAttachOriginalPodDoesntExist ( t * testing . T ) {
2017-09-14 09:40:34 -07:00
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
2017-12-04 09:03:06 -08:00
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
ClusterName : "testCluster" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "newPod" ,
PodNamespace : "Default" ,
RW : "rw" ,
}
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-09-14 09:40:34 -07:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {
2017-09-14 09:40:34 -07:00
{
Node : "otherNode" ,
PodNamespace : "Default" ,
2017-12-04 09:03:06 -08:00
PodName : "oldPod" ,
2017-09-14 09:40:34 -07:00
MountDir : "/tmt/test" ,
ReadOnly : false ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-09-14 09:40:34 -07:00
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
2017-09-14 09:40:34 -07:00
devicePath := ""
2017-12-04 08:33:19 -08:00
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Attach ( opts , & devicePath )
2017-10-16 10:51:03 -07:00
assert . Nil ( t , err )
2017-12-04 09:03:06 -08:00
volAtt , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Get ( "pvc-123" , metav1 . GetOptions {})
assert . Nil ( t , err )
assert . NotNil ( t , volAtt )
assert . Equal ( t , 1 , len ( volAtt . Attachments ))
assert . True ( t , containsAttachment (
rookalpha . Attachment {
PodNamespace : opts . PodNamespace ,
PodName : opts . Pod ,
MountDir : opts . MountDir ,
ReadOnly : false ,
Node : "node1" ,
}, volAtt . Attachments ,
), "VolumeAttachment crd does not contain expected attachment" )
2017-10-16 10:51:03 -07:00
}
2017-12-01 10:22:40 -08:00
func TestOrphanAttachOriginalPodNameSame ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-12-01 10:22:40 -08:00
}
// Setting up the pod to ensure that it is exists
pod := v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "myPod" ,
Namespace : "Default" ,
UID : "pod456" ,
},
Spec : v1 . PodSpec {
NodeName : "node1" ,
},
}
clientset . CoreV1 (). Pods ( "Default" ). Create ( & pod )
// existing record of old attachment. Pod namespace and name must much with the new attachment input to simulate that the new attachment is for the same pod
2017-12-04 09:03:06 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-12-01 10:22:40 -08:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 09:03:06 -08:00
Attachments : [] rookalpha . Attachment {
2017-12-01 10:22:40 -08:00
{
Node : "otherNode" ,
PodNamespace : "Default" ,
PodName : "myPod" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
ReadOnly : false ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-12-01 10:22:40 -08:00
// attachment input. The ID of the pod must be different than the original record to simulate that
// the pod resource is a different one but for the same pod metadata. This is reflected in the MountDir.
// The namespace and name, however, must match.
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
ClusterName : "testCluster" ,
MountDir : "/test/pods/pod456/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "myPod" ,
PodNamespace : "Default" ,
RW : "rw" ,
}
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
assert . Nil ( t , err )
2017-12-01 10:22:40 -08:00
2017-12-04 09:03:06 -08:00
controller := & Controller {
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-12-01 10:22:40 -08:00
}
// Attach should succeed and the stale volumeattachment record should be updated to reflect the new pod information
2017-12-04 09:03:06 -08:00
devicePath := ""
err = controller . Attach ( opts , & devicePath )
2017-12-01 10:22:40 -08:00
assert . Nil ( t , err )
2017-12-04 09:03:06 -08:00
volAtt , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Get ( "pvc-123" , metav1 . GetOptions {})
assert . Nil ( t , err )
assert . NotNil ( t , volAtt )
assert . Equal ( t , 1 , len ( volAtt . Attachments ))
assert . True ( t , containsAttachment (
rookalpha . Attachment {
PodNamespace : opts . PodNamespace ,
PodName : opts . Pod ,
MountDir : opts . MountDir ,
ReadOnly : false ,
Node : "node1" ,
}, volAtt . Attachments ,
), "VolumeAttachment crd does not contain expected attachment" )
2017-12-01 10:22:40 -08:00
}
2017-10-16 10:51:03 -07:00
// This tests the idempotency of the VolumeAttachment record.
// If the VolumeAttachment record was previously created for this pod
// and the attach flow should continue.
func TestVolumeAttachmentExistAttach ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
}
opts := AttachOptions {
Image : "image123" ,
Pool : "testpool" ,
ClusterName : "testCluster" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
VolumeName : "pvc-123" ,
Pod : "myPod" ,
PodNamespace : "Default" ,
RW : "rw" ,
2017-10-16 10:51:03 -07:00
}
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-10-16 10:51:03 -07:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {
2017-10-16 10:51:03 -07:00
{
Node : "node1" ,
PodNamespace : "Default" ,
PodName : "myPod" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
ReadOnly : false ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-10-16 10:51:03 -07:00
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
2017-10-16 10:51:03 -07:00
devicePath := ""
2017-12-04 08:33:19 -08:00
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-10-16 10:51:03 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Attach ( opts , & devicePath )
2017-09-14 09:40:34 -07:00
assert . Nil ( t , err )
2017-12-04 09:03:06 -08:00
newAttach , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Get ( "pvc-123" , metav1 . GetOptions {})
assert . Nil ( t , err )
assert . NotNil ( t , newAttach )
// TODO: Check that the volume attach was not updated (can't use ResourceVersion in the fake testing)
2017-09-14 09:40:34 -07:00
}
func TestDetach ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-12-04 09:03:06 -08:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-09-14 09:40:34 -07:00
opts := AttachOptions {
VolumeName : "pvc-123" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
}
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Detach ( opts , nil )
2017-09-14 09:40:34 -07:00
assert . Nil ( t , err )
2017-12-04 09:03:06 -08:00
_ , err = context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Get ( "pvc-123" , metav1 . GetOptions {})
assert . NotNil ( t , err )
assert . True ( t , errors . IsNotFound ( err ))
2017-09-14 09:40:34 -07:00
}
func TestDetachWithAttachmentLeft ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
existingCRD := & rookalpha . VolumeAttachment {
2017-12-04 09:03:06 -08:00
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
Namespace : "rook-system" ,
},
2017-12-04 08:33:19 -08:00
Attachments : [] rookalpha . Attachment {
2017-09-14 09:40:34 -07:00
{
Node : "node1" ,
PodNamespace : "Default" ,
PodName : "myPod" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
},
},
}
2017-12-04 09:03:06 -08:00
volumeAttachment , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Create ( existingCRD )
assert . Nil ( t , err )
assert . NotNil ( t , volumeAttachment )
2017-09-14 09:40:34 -07:00
opts := AttachOptions {
VolumeName : "pvc-123" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
}
2017-12-04 09:03:06 -08:00
att , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
controller := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : att ,
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
2017-12-04 08:33:19 -08:00
err = controller . Detach ( opts , nil )
2017-09-14 09:40:34 -07:00
assert . Nil ( t , err )
2017-12-04 09:03:06 -08:00
volAttach , err := context . RookClientset . Rook (). VolumeAttachments ( "rook-system" ). Get ( "pvc-123" , metav1 . GetOptions {})
assert . Nil ( t , err )
assert . NotNil ( t , volAttach )
2017-09-14 09:40:34 -07:00
}
func TestGetAttachInfoFromMountDir ( t * testing . T ) {
clientset := test . New ( 3 )
os . Setenv ( k8sutil . PodNamespaceEnvVar , "rook-system" )
defer os . Unsetenv ( k8sutil . PodNamespaceEnvVar )
os . Setenv ( k8sutil . NodeNameEnvVar , "node1" )
defer os . Unsetenv ( k8sutil . NodeNameEnvVar )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
pv := & v1 . PersistentVolume {
ObjectMeta : metav1 . ObjectMeta {
Name : "pvc-123" ,
},
Spec : v1 . PersistentVolumeSpec {
PersistentVolumeSource : v1 . PersistentVolumeSource {
FlexVolume : & v1 . FlexVolumeSource {
Driver : "rook.io/rook" ,
FSType : "ext4" ,
ReadOnly : false ,
Options : map [ string ] string {
StorageClassKey : "storageClass1" ,
PoolKey : "pool123" ,
ImageKey : "pvc-123" ,
},
},
},
ClaimRef : & v1 . ObjectReference {
Namespace : "testnamespace" ,
},
},
}
clientset . CoreV1 (). PersistentVolumes (). Create ( pv )
sc := storagev1 . StorageClass {
ObjectMeta : metav1 . ObjectMeta {
Name : "storageClass1" ,
},
Provisioner : "rook.io/rook" ,
Parameters : map [ string ] string { "pool" : "testpool" , "clusterName" : "testCluster" , "fsType" : "ext3" },
}
clientset . StorageV1 (). StorageClasses (). Create ( & sc )
pod := v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "myPod" ,
Namespace : "testnamespace" ,
UID : "pod123" ,
},
Spec : v1 . PodSpec {
NodeName : "node1" ,
},
}
clientset . CoreV1 (). Pods ( "testnamespace" ). Create ( & pod )
opts := AttachOptions {
VolumeName : "pvc-123" ,
MountDir : "/test/pods/pod123/volumes/rook.io~rook/pvc-123" ,
}
2017-12-04 08:33:19 -08:00
controller := & Controller {
2017-10-20 13:55:59 -07:00
context : context ,
2017-10-25 12:23:15 -07:00
volumeManager : & manager . FakeVolumeManager {},
2017-09-14 09:40:34 -07:00
}
err := controller . GetAttachInfoFromMountDir ( opts . MountDir , & opts )
assert . Nil ( t , err )
assert . Equal ( t , "pod123" , opts . PodID )
assert . Equal ( t , "pvc-123" , opts . VolumeName )
assert . Equal ( t , "testnamespace" , opts . PodNamespace )
assert . Equal ( t , "myPod" , opts . Pod )
assert . Equal ( t , "pvc-123" , opts . Image )
assert . Equal ( t , "pool123" , opts . Pool )
assert . Equal ( t , "storageClass1" , opts . StorageClass )
assert . Equal ( t , "testCluster" , opts . ClusterName )
}
func TestParseClusterName ( t * testing . T ) {
clientset := test . New ( 3 )
context := & clusterd . Context {
2017-12-04 09:03:06 -08:00
Clientset : clientset ,
RookClientset : rookclient . NewSimpleClientset (),
2017-09-14 09:40:34 -07:00
}
sc := storagev1 . StorageClass {
ObjectMeta : metav1 . ObjectMeta {
Name : "rook-storageclass" ,
},
Provisioner : "rook.io/rook" ,
Parameters : map [ string ] string { "pool" : "testpool" , "clusterName" : "testCluster" , "fsType" : "ext3" },
}
clientset . StorageV1 (). StorageClasses (). Create ( & sc )
2017-12-04 09:03:06 -08:00
volumeAttachment , err := attachment . New ( context )
2017-12-04 08:33:19 -08:00
assert . Nil ( t , err )
fc := & Controller {
2017-12-04 09:03:06 -08:00
context : context ,
volumeAttachment : volumeAttachment ,
2017-09-14 09:40:34 -07:00
}
clusterName , _ := fc . parseClusterName ( "rook-storageclass" )
assert . Equal ( t , "testCluster" , clusterName )
}
func TestGetPodAndPVNameFromMountDir ( t * testing . T ) {
mountDir := "/var/lib/kubelet/pods/b8b7c55f-99ea-11e7-8994-0800277c89a7/volumes/rook.io~rook/pvc-b8aea7f4-99ea-11e7-8994-0800277c89a7"
pod , pv , err := getPodAndPVNameFromMountDir ( mountDir )
assert . Nil ( t , err )
assert . Equal ( t , "b8b7c55f-99ea-11e7-8994-0800277c89a7" , pod )
assert . Equal ( t , "pvc-b8aea7f4-99ea-11e7-8994-0800277c89a7" , pv )
}
func TestGetCRDNameFromMountDirInvalid ( t * testing . T ) {
mountDir := "volumes/rook.io~rook/pvc-b8aea7f4-99ea-11e7-8994-0800277c89a7"
_ , _ , err := getPodAndPVNameFromMountDir ( mountDir )
assert . NotNil ( t , err )
}
func defaultHeader () http . Header {
header := http . Header {}
header . Set ( "Content-Type" , runtime . ContentTypeJSON )
return header
}
func objBody ( object interface {}) io . ReadCloser {
output , err := json . MarshalIndent ( object , "" , "" )
if err != nil {
panic ( err )
}
return ioutil . NopCloser ( bytes . NewReader ([] byte ( output )))
}
2017-12-04 08:33:19 -08:00
func containsAttachment ( attachment rookalpha . Attachment , attachments [] rookalpha . Attachment ) bool {
2017-09-14 09:40:34 -07:00
for _ , a := range attachments {
if a . PodNamespace == attachment . PodNamespace && a . PodName == attachment . PodName && a . MountDir == attachment . MountDir && a . ReadOnly == attachment . ReadOnly && a . Node == attachment . Node {
return true
}
}
return false
}