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

Commit 2abd29a

Browse files
committed
Merge branch 'master' into upgrade_aliases_branch
2 parents 8625286 + a15cff3 commit 2abd29a

6 files changed

Lines changed: 170 additions & 39 deletions

File tree

pkg/cloudprovider/providers/openstack/BUILD

Lines changed: 2 additions & 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",
@@ -75,6 +76,7 @@ go_test(
7576
"//pkg/cloudprovider:go_default_library",
7677
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
7778
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
79+
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers:go_default_library",
7880
"//vendor/k8s.io/api/core/v1:go_default_library",
7981
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
8082
"//vendor/k8s.io/apimachinery/pkg/types: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_routes_test.go

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"net"
2121
"testing"
2222

23+
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
24+
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers"
2325
"k8s.io/apimachinery/pkg/types"
2426
"k8s.io/kubernetes/pkg/cloudprovider"
2527
)
@@ -37,14 +39,18 @@ func TestRoutes(t *testing.T) {
3739
t.Fatalf("Failed to construct/authenticate OpenStack: %s", err)
3840
}
3941

42+
// Pick the first router and server to try a test with
43+
os.routeOpts.RouterId = getRouters(os)[0].ID
44+
servername := getServers(os)[0].Name
45+
4046
r, ok := os.Routes()
4147
if !ok {
42-
t.Fatalf("Routes() returned false - perhaps your stack doens't support Neutron?")
48+
t.Skip("Routes() returned false - perhaps your stack does not support Neutron extraroute extension?")
4349
}
4450

4551
newroute := cloudprovider.Route{
4652
DestinationCIDR: "10.164.2.0/24",
47-
TargetNode: types.NodeName("testinstance"),
53+
TargetNode: types.NodeName(servername),
4854
}
4955
err = r.CreateRoute(clusterName, "myhint", &newroute)
5056
if err != nil {
@@ -69,3 +75,39 @@ func TestRoutes(t *testing.T) {
6975
t.Fatalf("DeleteRoute error: %v", err)
7076
}
7177
}
78+
79+
func getServers(os *OpenStack) []servers.Server {
80+
c, err := os.NewComputeV2()
81+
allPages, err := servers.List(c, servers.ListOpts{}).AllPages()
82+
if err != nil {
83+
panic(err)
84+
}
85+
allServers, err := servers.ExtractServers(allPages)
86+
if err != nil {
87+
panic(err)
88+
}
89+
if len(allServers) == 0 {
90+
panic("No servers to test with")
91+
}
92+
return allServers
93+
}
94+
95+
func getRouters(os *OpenStack) []routers.Router {
96+
listOpts := routers.ListOpts{}
97+
n, err := os.NewNetworkV2()
98+
if err != nil {
99+
panic(err)
100+
}
101+
allPages, err := routers.List(n, listOpts).AllPages()
102+
if err != nil {
103+
panic(err)
104+
}
105+
allRouters, err := routers.ExtractRouters(allPages)
106+
if err != nil {
107+
panic(err)
108+
}
109+
if len(allRouters) == 0 {
110+
panic("No routers to test with")
111+
}
112+
return allRouters
113+
}

pkg/cloudprovider/providers/openstack/openstack_test.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ func configFromEnv() (cfg Config, ok bool) {
421421
cfg.Global.DomainId != "" || cfg.Global.DomainName != ""))
422422

423423
cfg.Metadata.SearchOrder = fmt.Sprintf("%s,%s", configDriveID, metadataID)
424+
cfg.BlockStorage.BSVersion = "auto"
424425

425426
return
426427
}
@@ -443,7 +444,7 @@ func TestLoadBalancer(t *testing.T) {
443444
t.Skipf("No config found in environment")
444445
}
445446

446-
versions := []string{"v1", "v2", ""}
447+
versions := []string{"v2", ""}
447448

448449
for _, v := range versions {
449450
t.Logf("Trying LBVersion = '%s'\n", v)
@@ -525,30 +526,30 @@ func TestVolumes(t *testing.T) {
525526

526527
id, err := os.InstanceID()
527528
if err != nil {
528-
t.Fatalf("Cannot find instance id: %v", err)
529-
}
529+
t.Logf("Cannot find instance id: %v - perhaps you are running this test outside a VM launched by OpenStack", err)
530+
} else {
531+
diskId, err := os.AttachDisk(id, vol)
532+
if err != nil {
533+
t.Fatalf("Cannot AttachDisk Cinder volume %s: %v", vol, err)
534+
}
535+
t.Logf("Volume (%s) attached, disk ID: %s\n", vol, diskId)
530536

531-
diskId, err := os.AttachDisk(id, vol)
532-
if err != nil {
533-
t.Fatalf("Cannot AttachDisk Cinder volume %s: %v", vol, err)
534-
}
535-
t.Logf("Volume (%s) attached, disk ID: %s\n", vol, diskId)
537+
WaitForVolumeStatus(t, os, vol, volumeInUseStatus)
536538

537-
WaitForVolumeStatus(t, os, vol, volumeInUseStatus)
539+
devicePath := os.GetDevicePath(diskId)
540+
if diskPathRegexp.FindString(devicePath) == "" {
541+
t.Fatalf("GetDevicePath returned and unexpected path for Cinder volume %s, returned %s", vol, devicePath)
542+
}
543+
t.Logf("Volume (%s) found at path: %s\n", vol, devicePath)
538544

539-
devicePath := os.GetDevicePath(diskId)
540-
if diskPathRegexp.FindString(devicePath) == "" {
541-
t.Fatalf("GetDevicePath returned and unexpected path for Cinder volume %s, returned %s", vol, devicePath)
542-
}
543-
t.Logf("Volume (%s) found at path: %s\n", vol, devicePath)
545+
err = os.DetachDisk(id, vol)
546+
if err != nil {
547+
t.Fatalf("Cannot DetachDisk Cinder volume %s: %v", vol, err)
548+
}
549+
t.Logf("Volume (%s) detached\n", vol)
544550

545-
err = os.DetachDisk(id, vol)
546-
if err != nil {
547-
t.Fatalf("Cannot DetachDisk Cinder volume %s: %v", vol, err)
551+
WaitForVolumeStatus(t, os, vol, volumeAvailableStatus)
548552
}
549-
t.Logf("Volume (%s) detached\n", vol)
550-
551-
WaitForVolumeStatus(t, os, vol, volumeAvailableStatus)
552553

553554
err = os.DeleteVolume(vol)
554555
if err != nil {

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)