Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add PV.Name to volume tags. #18957

Merged
merged 2 commits into from
Jan 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (controller *PersistentVolumeProvisionerController) reconcileClaim(claim *a
}

glog.V(5).Infof("PersistentVolumeClaim[%s] provisioning", claim.Name)
provisioner, err := newProvisioner(controller.provisioner, claim)
provisioner, err := newProvisioner(controller.provisioner, claim, nil)
if err != nil {
return fmt.Errorf("Unexpected error getting new provisioner for claim %s: %v\n", claim.Name, err)
}
Expand Down Expand Up @@ -274,7 +274,7 @@ func provisionVolume(pv *api.PersistentVolume, controller *PersistentVolumeProvi
}
claim := obj.(*api.PersistentVolumeClaim)

provisioner, _ := newProvisioner(controller.provisioner, claim)
provisioner, _ := newProvisioner(controller.provisioner, claim, pv)
err := provisioner.Provision(pv)
if err != nil {
glog.Errorf("Could not provision %s", pv.Name)
Expand Down Expand Up @@ -330,15 +330,21 @@ func (controller *PersistentVolumeProvisionerController) Stop() {
}
}

func newProvisioner(plugin volume.ProvisionableVolumePlugin, claim *api.PersistentVolumeClaim) (volume.Provisioner, error) {
func newProvisioner(plugin volume.ProvisionableVolumePlugin, claim *api.PersistentVolumeClaim, pv *api.PersistentVolume) (volume.Provisioner, error) {
tags := make(map[string]string)
tags[cloudVolumeCreatedForClaimNamespaceTag] = claim.Namespace
tags[cloudVolumeCreatedForClaimNameTag] = claim.Name

// pv can be nil when the provisioner has not created the PV yet
if pv != nil {
tags[cloudVolumeCreatedForVolumeNameTag] = pv.Name
}

volumeOptions := volume.VolumeOptions{
Capacity: claim.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)],
AccessModes: claim.Spec.AccessModes,
PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimDelete,
CloudTags: &map[string]string{
cloudVolumeCreatedForNamespaceTag: claim.Namespace,
cloudVolumeCreatedForNameTag: claim.Name,
},
CloudTags: &tags,
}

provisioner, err := plugin.NewProvisioner(volumeOptions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
)

func TestProvisionerRunStop(t *testing.T) {
controller, _ := makeTestController()
controller, _, _ := makeTestController()

if len(controller.stopChannels) != 0 {
t.Errorf("Non-running provisioner should not have any stopChannels. Got %v", len(controller.stopChannels))
Expand Down Expand Up @@ -92,15 +92,15 @@ func makeTestClaim() *api.PersistentVolumeClaim {
}
}

func makeTestController() (*PersistentVolumeProvisionerController, *mockControllerClient) {
func makeTestController() (*PersistentVolumeProvisionerController, *mockControllerClient, *volume.FakeVolumePlugin) {
mockClient := &mockControllerClient{}
mockVolumePlugin := &volume.FakeVolumePlugin{}
controller, _ := NewPersistentVolumeProvisionerController(mockClient, 1*time.Second, nil, mockVolumePlugin, &fake_cloud.FakeCloud{})
return controller, mockClient
return controller, mockClient, mockVolumePlugin
}

func TestReconcileClaim(t *testing.T) {
controller, mockClient := makeTestController()
controller, mockClient, _ := makeTestController()
pvc := makeTestClaim()

// watch would have added the claim to the store
Expand Down Expand Up @@ -132,9 +132,16 @@ func TestReconcileClaim(t *testing.T) {
}
}

func checkTagValue(t *testing.T, tags map[string]string, tag string, expectedValue string) {
value, found := tags[tag]
if !found || value != expectedValue {
t.Errorf("Expected tag value %s = %s but value %s found", tag, expectedValue, value)
}
}

func TestReconcileVolume(t *testing.T) {

controller, mockClient := makeTestController()
controller, mockClient, mockVolumePlugin := makeTestController()
pv := makeTestVolume()
pvc := makeTestClaim()

Expand Down Expand Up @@ -163,6 +170,13 @@ func TestReconcileVolume(t *testing.T) {
if !isAnnotationMatch(pvProvisioningRequiredAnnotationKey, pvProvisioningCompletedAnnotationValue, mockClient.volume.Annotations) {
t.Errorf("Expected %s but got %s", pvProvisioningRequiredAnnotationKey, mockClient.volume.Annotations[pvProvisioningRequiredAnnotationKey])
}

// Check that the volume plugin was called with correct tags
tags := *mockVolumePlugin.LastProvisionerOptions.CloudTags
checkTagValue(t, tags, cloudVolumeCreatedForClaimNamespaceTag, pvc.Namespace)
checkTagValue(t, tags, cloudVolumeCreatedForClaimNameTag, pvc.Name)
checkTagValue(t, tags, cloudVolumeCreatedForVolumeNameTag, pv.Name)

}

var _ controllerClient = &mockControllerClient{}
Expand Down
7 changes: 5 additions & 2 deletions pkg/controller/persistentvolume/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ const (
qosProvisioningKey = "volume.alpha.kubernetes.io/storage-class"
// Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD)
// with namespace of a persistent volume claim used to create this volume.
cloudVolumeCreatedForNamespaceTag = "kubernetes.io/created-for/pvc/namespace"
cloudVolumeCreatedForClaimNamespaceTag = "kubernetes.io/created-for/pvc/namespace"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should fail validation - only one / is allowed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I interpreted this as a k8s label, not a cloud tag

// Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD)
// with name of a persistent volume claim used to create this volume.
cloudVolumeCreatedForNameTag = "kubernetes.io/created-for/pvc/name"
cloudVolumeCreatedForClaimNameTag = "kubernetes.io/created-for/pvc/name"
// Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD)
// with name of appropriate Kubernetes persistent volume .
cloudVolumeCreatedForVolumeNameTag = "kubernetes.io/created-for/pv/name"
)

// persistentVolumeOrderedIndex is a cache.Store that keeps persistent volumes indexed by AccessModes and ordered by storage capacity.
Expand Down
8 changes: 5 additions & 3 deletions pkg/volume/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,10 @@ func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin {
// Use as:
// volume.RegisterPlugin(&FakePlugin{"fake-name"})
type FakeVolumePlugin struct {
PluginName string
Host VolumeHost
Config VolumeConfig
PluginName string
Host VolumeHost
Config VolumeConfig
LastProvisionerOptions VolumeOptions
}

var _ VolumePlugin = &FakeVolumePlugin{}
Expand Down Expand Up @@ -160,6 +161,7 @@ func (plugin *FakeVolumePlugin) NewDeleter(spec *Spec) (Deleter, error) {
}

func (plugin *FakeVolumePlugin) NewProvisioner(options VolumeOptions) (Provisioner, error) {
plugin.LastProvisionerOptions = options
return &FakeProvisioner{options, plugin.Host}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion test/integration/persistent_volumes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestPersistentVolumeRecycler(t *testing.T) {
testClient := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()})
host := volume.NewFakeVolumeHost("/tmp/fake", nil, nil)

plugins := []volume.VolumePlugin{&volume.FakeVolumePlugin{"plugin-name", host, volume.VolumeConfig{}}}
plugins := []volume.VolumePlugin{&volume.FakeVolumePlugin{"plugin-name", host, volume.VolumeConfig{}, volume.VolumeOptions{}}}
cloud := &fake_cloud.FakeCloud{}

binder := persistentvolumecontroller.NewPersistentVolumeClaimBinder(binderClient, 10*time.Second)
Expand Down