@@ -25,8 +25,11 @@ import (
2525 "strings"
2626 "time"
2727
28+ "k8s.io/api/core/v1"
2829 "k8s.io/apimachinery/pkg/api/resource"
2930 "k8s.io/apimachinery/pkg/types"
31+ "k8s.io/kubernetes/pkg/cloudprovider"
32+ kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
3033 k8s_volume "k8s.io/kubernetes/pkg/volume"
3134 volumeutil "k8s.io/kubernetes/pkg/volume/util"
3235
@@ -71,6 +74,8 @@ type Volume struct {
7174 AttachedServerId string
7275 // Device file path
7376 AttachedDevice string
77+ // AvailabilityZone is which availability zone the volume is in
78+ AvailabilityZone string
7479 // Unique identifier for the volume.
7580 ID string
7681 // Human-readable display name for the volume.
@@ -89,6 +94,9 @@ type VolumeCreateOpts struct {
8994 Metadata map [string ]string
9095}
9196
97+ // implements PVLabeler.
98+ var _ cloudprovider.PVLabeler = (* OpenStack )(nil )
99+
92100const (
93101 VolumeAvailableStatus = "available"
94102 VolumeInUseStatus = "in-use"
@@ -171,10 +179,11 @@ func (volumes *VolumesV1) getVolume(volumeID string) (Volume, error) {
171179 }
172180
173181 volume := Volume {
174- ID : volumeV1 .ID ,
175- Name : volumeV1 .Name ,
176- Status : volumeV1 .Status ,
177- Size : volumeV1 .Size ,
182+ AvailabilityZone : volumeV1 .AvailabilityZone ,
183+ ID : volumeV1 .ID ,
184+ Name : volumeV1 .Name ,
185+ Status : volumeV1 .Status ,
186+ Size : volumeV1 .Size ,
178187 }
179188
180189 if len (volumeV1 .Attachments ) > 0 && volumeV1 .Attachments [0 ]["server_id" ] != nil {
@@ -195,10 +204,11 @@ func (volumes *VolumesV2) getVolume(volumeID string) (Volume, error) {
195204 }
196205
197206 volume := Volume {
198- ID : volumeV2 .ID ,
199- Name : volumeV2 .Name ,
200- Status : volumeV2 .Status ,
201- Size : volumeV2 .Size ,
207+ AvailabilityZone : volumeV2 .AvailabilityZone ,
208+ ID : volumeV2 .ID ,
209+ Name : volumeV2 .Name ,
210+ Status : volumeV2 .Status ,
211+ Size : volumeV2 .Size ,
202212 }
203213
204214 if len (volumeV2 .Attachments ) > 0 {
@@ -219,10 +229,10 @@ func (volumes *VolumesV3) getVolume(volumeID string) (Volume, error) {
219229 }
220230
221231 volume := Volume {
222- ID : volumeV3 .ID ,
223- Name : volumeV3 .Name ,
224- Status : volumeV3 .Status ,
225- Size : volumeV3 .Size ,
232+ AvailabilityZone : volumeV3 .AvailabilityZone ,
233+ ID : volumeV3 .ID ,
234+ Name : volumeV3 .Name ,
235+ Status : volumeV3 .Status ,
226236 }
227237
228238 if len (volumeV3 .Attachments ) > 0 {
@@ -680,6 +690,28 @@ func (os *OpenStack) ShouldTrustDevicePath() bool {
680690 return os .bsOpts .TrustDevicePath
681691}
682692
693+ // GetLabelsForVolume implements PVLabeler.GetLabelsForVolume
694+ func (os * OpenStack ) GetLabelsForVolume (pv * v1.PersistentVolume ) (map [string ]string , error ) {
695+ // Ignore any volumes that are being provisioned
696+ if pv .Spec .Cinder .VolumeID == k8s_volume .ProvisionedVolumeName {
697+ return nil , nil
698+ }
699+
700+ // Get Volume
701+ volume , err := os .getVolume (pv .Spec .Cinder .VolumeID )
702+ if err != nil {
703+ return nil , err
704+ }
705+
706+ // Contruct Volume Labels
707+ labels := make (map [string ]string )
708+ labels [kubeletapis .LabelZoneFailureDomain ] = volume .AvailabilityZone
709+ labels [kubeletapis .LabelZoneRegion ] = os .region
710+ glog .V (4 ).Infof ("The Volume %s has labels %v" , pv .Spec .Cinder .VolumeID , labels )
711+
712+ return labels , nil
713+ }
714+
683715// recordOpenstackOperationMetric records openstack operation metrics
684716func recordOpenstackOperationMetric (operation string , timeTaken float64 , err error ) {
685717 if err != nil {
0 commit comments