Skip to content
This repository was archived by the owner on Mar 22, 2018. It is now read-only.

Commit 852a15b

Browse files
committed
Support VolumeV3 for OpenStack cloud Provider
1 parent a81422a commit 852a15b

4 files changed

Lines changed: 104 additions & 17 deletions

File tree

pkg/cloudprovider/providers/openstack/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ go_library(
3232
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions:go_default_library",
3333
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:go_default_library",
3434
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
35+
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes:go_default_library",
3536
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces:go_default_library",
3637
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach:go_default_library",
3738
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",

pkg/cloudprovider/providers/openstack/openstack.go

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -660,27 +660,36 @@ func (os *OpenStack) volumeService(forceVersion string) (volumeService, error) {
660660
}
661661
glog.V(3).Infof("Using Blockstorage API V2")
662662
return &VolumesV2{sClient, os.bsOpts}, nil
663+
case "v3":
664+
sClient, err := os.NewBlockStorageV3()
665+
if err != nil {
666+
return nil, err
667+
}
668+
glog.V(3).Infof("Using Blockstorage API V3")
669+
return &VolumesV3{sClient, os.bsOpts}, nil
663670
case "auto":
664-
// Currently kubernetes just support Cinder v1 and Cinder v2.
665-
// Choose Cinder v2 firstly, if kubernetes can't initialize cinder v2 client, try to initialize cinder v1 client.
671+
// Currently kubernetes support Cinder v1 / Cinder v2 / Cinder v3.
672+
// Choose Cinder v3 firstly, if kubernetes can't initialize cinder v3 client, try to initialize cinder v2 client.
673+
// If kubernetes can't initialize cinder v2 client, try to initialize cinder v1 client.
666674
// Return appropriate message when kubernetes can't initialize them.
667-
// TODO(FengyunPan): revisit 'auto' after supporting Cinder v3.
668-
sClient, err := os.NewBlockStorageV2()
669-
if err != nil {
670-
sClient, err = os.NewBlockStorageV1()
671-
if err != nil {
672-
// Nothing suitable found, failed autodetection, just exit with appropriate message
673-
err_txt := "BlockStorage API version autodetection failed. " +
674-
"Please set it explicitly in cloud.conf in section [BlockStorage] with key `bs-version`"
675-
return nil, errors.New(err_txt)
676-
} else {
677-
glog.V(3).Infof("Using Blockstorage API V1")
678-
return &VolumesV1{sClient, os.bsOpts}, nil
679-
}
680-
} else {
675+
if sClient, err := os.NewBlockStorageV3(); err == nil {
676+
glog.V(3).Infof("Using Blockstorage API V3")
677+
return &VolumesV3{sClient, os.bsOpts}, nil
678+
}
679+
680+
if sClient, err := os.NewBlockStorageV2(); err == nil {
681681
glog.V(3).Infof("Using Blockstorage API V2")
682682
return &VolumesV2{sClient, os.bsOpts}, nil
683683
}
684+
685+
if sClient, err := os.NewBlockStorageV1(); err == nil {
686+
glog.V(3).Infof("Using Blockstorage API V1")
687+
return &VolumesV1{sClient, os.bsOpts}, nil
688+
}
689+
690+
err_txt := "BlockStorage API version autodetection failed. " +
691+
"Please set it explicitly in cloud.conf in section [BlockStorage] with key `bs-version`"
692+
return nil, errors.New(err_txt)
684693
default:
685694
err_txt := fmt.Sprintf("Config error: unrecognised bs-version \"%v\"", os.bsOpts.BSVersion)
686695
return nil, errors.New(err_txt)

pkg/cloudprovider/providers/openstack/openstack_client.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ func (os *OpenStack) NewBlockStorageV2() (*gophercloud.ServiceClient, error) {
6363
return storage, nil
6464
}
6565

66+
func (os *OpenStack) NewBlockStorageV3() (*gophercloud.ServiceClient, error) {
67+
storage, err := openstack.NewBlockStorageV3(os.provider, gophercloud.EndpointOpts{
68+
Region: os.region,
69+
})
70+
if err != nil {
71+
return nil, fmt.Errorf("unable to initialize cinder v3 client for region %s: %v", os.region, err)
72+
}
73+
return storage, nil
74+
}
75+
6676
func (os *OpenStack) NewLoadBalancerV2() (*gophercloud.ServiceClient, error) {
6777
var lb *gophercloud.ServiceClient
6878
var err error

pkg/cloudprovider/providers/openstack/openstack_volumes.go

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
volumeexpand "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions"
3232
volumes_v1 "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
3333
volumes_v2 "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
34+
volumes_v3 "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
3435
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach"
3536
"github.com/prometheus/client_golang/prometheus"
3637

@@ -56,6 +57,12 @@ type VolumesV2 struct {
5657
opts BlockStorageOpts
5758
}
5859

60+
// Volumes implementation for v3
61+
type VolumesV3 struct {
62+
blockstorage *gophercloud.ServiceClient
63+
opts BlockStorageOpts
64+
}
65+
5966
type Volume struct {
6067
// ID of the instance, to which this volume is attached. "" if not attached
6168
AttachedServerId string
@@ -131,6 +138,26 @@ func (volumes *VolumesV2) createVolume(opts VolumeCreateOpts) (string, string, e
131138
return vol.ID, vol.AvailabilityZone, nil
132139
}
133140

141+
func (volumes *VolumesV3) createVolume(opts VolumeCreateOpts) (string, string, error) {
142+
startTime := time.Now()
143+
144+
create_opts := volumes_v3.CreateOpts{
145+
Name: opts.Name,
146+
Size: opts.Size,
147+
VolumeType: opts.VolumeType,
148+
AvailabilityZone: opts.Availability,
149+
Metadata: opts.Metadata,
150+
}
151+
152+
vol, err := volumes_v3.Create(volumes.blockstorage, create_opts).Extract()
153+
timeTaken := time.Since(startTime).Seconds()
154+
recordOpenstackOperationMetric("create_v3_volume", timeTaken, err)
155+
if err != nil {
156+
return "", "", err
157+
}
158+
return vol.ID, vol.AvailabilityZone, nil
159+
}
160+
134161
func (volumes *VolumesV1) getVolume(volumeID string) (Volume, error) {
135162
startTime := time.Now()
136163
volumeV1, err := volumes_v1.Get(volumes.blockstorage, volumeID).Extract()
@@ -179,6 +206,29 @@ func (volumes *VolumesV2) getVolume(volumeID string) (Volume, error) {
179206
return volume, nil
180207
}
181208

209+
func (volumes *VolumesV3) getVolume(volumeID string) (Volume, error) {
210+
startTime := time.Now()
211+
volumeV3, err := volumes_v3.Get(volumes.blockstorage, volumeID).Extract()
212+
timeTaken := time.Since(startTime).Seconds()
213+
recordOpenstackOperationMetric("get_v3_volume", timeTaken, err)
214+
if err != nil {
215+
return Volume{}, fmt.Errorf("error occurred getting volume by ID: %s, err: %v", volumeID, err)
216+
}
217+
218+
volume := Volume{
219+
ID: volumeV3.ID,
220+
Name: volumeV3.Name,
221+
Status: volumeV3.Status,
222+
}
223+
224+
if len(volumeV3.Attachments) > 0 {
225+
volume.AttachedServerId = volumeV3.Attachments[0].ServerID
226+
volume.AttachedDevice = volumeV3.Attachments[0].Device
227+
}
228+
229+
return volume, nil
230+
}
231+
182232
func (volumes *VolumesV1) deleteVolume(volumeID string) error {
183233
startTime := time.Now()
184234
err := volumes_v1.Delete(volumes.blockstorage, volumeID).ExtractErr()
@@ -195,6 +245,14 @@ func (volumes *VolumesV2) deleteVolume(volumeID string) error {
195245
return err
196246
}
197247

248+
func (volumes *VolumesV3) deleteVolume(volumeID string) error {
249+
startTime := time.Now()
250+
err := volumes_v3.Delete(volumes.blockstorage, volumeID).ExtractErr()
251+
timeTaken := time.Since(startTime).Seconds()
252+
recordOpenstackOperationMetric("delete_v3_volume", timeTaken, err)
253+
return err
254+
}
255+
198256
func (volumes *VolumesV1) expandVolume(volumeID string, newSize int) error {
199257
startTime := time.Now()
200258
create_opts := volumeexpand.ExtendSizeOpts{
@@ -203,7 +261,6 @@ func (volumes *VolumesV1) expandVolume(volumeID string, newSize int) error {
203261
err := volumeexpand.ExtendSize(volumes.blockstorage, volumeID, create_opts).ExtractErr()
204262
timeTaken := time.Since(startTime).Seconds()
205263
recordOpenstackOperationMetric("expand_volume", timeTaken, err)
206-
207264
return err
208265
}
209266

@@ -215,7 +272,17 @@ func (volumes *VolumesV2) expandVolume(volumeID string, newSize int) error {
215272
err := volumeexpand.ExtendSize(volumes.blockstorage, volumeID, create_opts).ExtractErr()
216273
timeTaken := time.Since(startTime).Seconds()
217274
recordOpenstackOperationMetric("expand_volume", timeTaken, err)
275+
return err
276+
}
218277

278+
func (volumes *VolumesV3) expandVolume(volumeID string, newSize int) error {
279+
startTime := time.Now()
280+
create_opts := volumeexpand.ExtendSizeOpts{
281+
NewSize: newSize,
282+
}
283+
err := volumeexpand.ExtendSize(volumes.blockstorage, volumeID, create_opts).ExtractErr()
284+
timeTaken := time.Since(startTime).Seconds()
285+
recordOpenstackOperationMetric("expand_volume", timeTaken, err)
219286
return err
220287
}
221288

0 commit comments

Comments
 (0)