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

Commit 8707a36

Browse files
author
Kubernetes Submit Queue
authored
Merge pull request #53115 from FengyunPan/fix-auto
Automatic merge from submit-queue (batch tested with PRs 53418, 53366, 53115, 53402, 53130). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Fix the version detection of OpenStack Cinder **What this PR does / why we need it**: When running Kubernetes against an installation of DevStack which deploys the Cinder service at a path rather than a port (ex: http://foo.bar/volume rather than http://foo.bar:xxx), the version detection fails. It is better to use the OpenStack service catalog. OTOH, when initialize cinder client, kubernetes will check the endpoint from the OpenStack service catalog, so we can do this version detection by it. There are two case should be fixed in other PR: 1. revisit the version detection after supporting Cinder V3 API. 2. add codes to support MicroVersion after gophercloud supports MicroVersion. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #50461 **Special notes for your reviewer**: /assign @dims /assign @xsgordon **Release note**: ```release-note Using OpenStack service catalog to do version detection ```
2 parents 6ca51e9 + b5eb673 commit 8707a36

3 files changed

Lines changed: 17 additions & 114 deletions

File tree

pkg/cloudprovider/providers/openstack/BUILD

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ go_library(
2828
"//vendor/github.com/golang/glog:go_default_library",
2929
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
3030
"//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
31-
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions:go_default_library",
3231
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes:go_default_library",
3332
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
3433
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces:go_default_library",
@@ -74,7 +73,6 @@ go_test(
7473
deps = [
7574
"//pkg/cloudprovider:go_default_library",
7675
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
77-
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions:go_default_library",
7876
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
7977
"//vendor/k8s.io/api/core/v1:go_default_library",
8078
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

pkg/cloudprovider/providers/openstack/openstack.go

Lines changed: 17 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ import (
2424
"io/ioutil"
2525
"net/http"
2626
"regexp"
27-
"sort"
2827
"strings"
2928
"time"
3029

3130
"github.com/gophercloud/gophercloud"
3231
"github.com/gophercloud/gophercloud/openstack"
33-
apiversions_v1 "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions"
3432
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces"
3533
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
3634
"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts"
@@ -664,49 +662,6 @@ func (os *OpenStack) Routes() (cloudprovider.Routes, bool) {
664662
return r, true
665663
}
666664

667-
// Implementation of sort interface for blockstorage version probing
668-
type APIVersionsByID []apiversions_v1.APIVersion
669-
670-
func (apiVersions APIVersionsByID) Len() int {
671-
return len(apiVersions)
672-
}
673-
674-
func (apiVersions APIVersionsByID) Swap(i, j int) {
675-
apiVersions[i], apiVersions[j] = apiVersions[j], apiVersions[i]
676-
}
677-
678-
func (apiVersions APIVersionsByID) Less(i, j int) bool {
679-
return apiVersions[i].ID > apiVersions[j].ID
680-
}
681-
682-
func autoVersionSelector(apiVersion *apiversions_v1.APIVersion) string {
683-
switch strings.ToLower(apiVersion.ID) {
684-
case "v2.0":
685-
return "v2"
686-
case "v1.0":
687-
return "v1"
688-
default:
689-
return ""
690-
}
691-
}
692-
693-
func doBsApiVersionAutodetect(availableApiVersions []apiversions_v1.APIVersion) string {
694-
sort.Sort(APIVersionsByID(availableApiVersions))
695-
for _, status := range []string{"CURRENT", "SUPPORTED"} {
696-
for _, version := range availableApiVersions {
697-
if strings.ToUpper(version.Status) == status {
698-
if detectedApiVersion := autoVersionSelector(&version); detectedApiVersion != "" {
699-
glog.V(3).Infof("Blockstorage API version probing has found a suitable %s api version: %s", status, detectedApiVersion)
700-
return detectedApiVersion
701-
}
702-
}
703-
}
704-
}
705-
706-
return ""
707-
708-
}
709-
710665
func (os *OpenStack) volumeService(forceVersion string) (volumeService, error) {
711666
bsVersion := ""
712667
if forceVersion == "" {
@@ -721,43 +676,36 @@ func (os *OpenStack) volumeService(forceVersion string) (volumeService, error) {
721676
if err != nil {
722677
return nil, err
723678
}
679+
glog.V(3).Infof("Using Blockstorage API V1")
724680
return &VolumesV1{sClient, os.bsOpts}, nil
725681
case "v2":
726682
sClient, err := os.NewBlockStorageV2()
727683
if err != nil {
728684
return nil, err
729685
}
686+
glog.V(3).Infof("Using Blockstorage API V2")
730687
return &VolumesV2{sClient, os.bsOpts}, nil
731688
case "auto":
732-
sClient, err := os.NewBlockStorageV1()
689+
// Currently kubernetes just support Cinder v1 and Cinder v2.
690+
// Choose Cinder v2 firstly, if kubernetes can't initialize cinder v2 client, try to initialize cinder v1 client.
691+
// Return appropriate message when kubernetes can't initialize them.
692+
// TODO(FengyunPan): revisit 'auto' after supporting Cinder v3.
693+
sClient, err := os.NewBlockStorageV2()
733694
if err != nil {
734-
return nil, err
735-
}
736-
availableApiVersions := []apiversions_v1.APIVersion{}
737-
err = apiversions_v1.List(sClient).EachPage(func(page pagination.Page) (bool, error) {
738-
// returning false from this handler stops page iteration, error is propagated to the upper function
739-
apiversions, err := apiversions_v1.ExtractAPIVersions(page)
695+
sClient, err = os.NewBlockStorageV1()
740696
if err != nil {
741-
glog.Errorf("Unable to extract api versions from page: %v", err)
742-
return false, err
697+
// Nothing suitable found, failed autodetection, just exit with appropriate message
698+
err_txt := "BlockStorage API version autodetection failed. " +
699+
"Please set it explicitly in cloud.conf in section [BlockStorage] with key `bs-version`"
700+
return nil, errors.New(err_txt)
701+
} else {
702+
glog.V(3).Infof("Using Blockstorage API V1")
703+
return &VolumesV1{sClient, os.bsOpts}, nil
743704
}
744-
availableApiVersions = append(availableApiVersions, apiversions...)
745-
return true, nil
746-
})
747-
748-
if err != nil {
749-
glog.Errorf("Error when retrieving list of supported blockstorage api versions: %v", err)
750-
return nil, err
751-
}
752-
if autodetectedVersion := doBsApiVersionAutodetect(availableApiVersions); autodetectedVersion != "" {
753-
return os.volumeService(autodetectedVersion)
754705
} else {
755-
// Nothing suitable found, failed autodetection, just exit with appropriate message
756-
err_txt := "BlockStorage API version autodetection failed. " +
757-
"Please set it explicitly in cloud.conf in section [BlockStorage] with key `bs-version`"
758-
return nil, errors.New(err_txt)
706+
glog.V(3).Infof("Using Blockstorage API V2")
707+
return &VolumesV2{sClient, os.bsOpts}, nil
759708
}
760-
761709
default:
762710
err_txt := fmt.Sprintf("Config error: unrecognised bs-version \"%v\"", os.bsOpts.BSVersion)
763711
glog.Warningf(err_txt)

pkg/cloudprovider/providers/openstack/openstack_test.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"time"
2727

2828
"github.com/gophercloud/gophercloud"
29-
"github.com/gophercloud/gophercloud/openstack/blockstorage/v1/apiversions"
3029
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
3130
"k8s.io/api/core/v1"
3231

@@ -557,48 +556,6 @@ func TestVolumes(t *testing.T) {
557556

558557
}
559558

560-
func TestCinderAutoDetectApiVersion(t *testing.T) {
561-
updated := "" // not relevant to this test, can be set to any value
562-
status_current := "CURRENT"
563-
status_supported := "SUPpORTED" // lowercase to test regression resitance if api returns different case
564-
status_deprecated := "DEPRECATED"
565-
566-
var result_version, api_version [4]string
567-
568-
for ver := 0; ver <= 3; ver++ {
569-
api_version[ver] = fmt.Sprintf("v%d.0", ver)
570-
result_version[ver] = fmt.Sprintf("v%d", ver)
571-
}
572-
result_version[0] = ""
573-
api_current_v1 := apiversions.APIVersion{ID: api_version[1], Status: status_current, Updated: updated}
574-
api_current_v2 := apiversions.APIVersion{ID: api_version[2], Status: status_current, Updated: updated}
575-
api_current_v3 := apiversions.APIVersion{ID: api_version[3], Status: status_current, Updated: updated}
576-
577-
api_supported_v1 := apiversions.APIVersion{ID: api_version[1], Status: status_supported, Updated: updated}
578-
api_supported_v2 := apiversions.APIVersion{ID: api_version[2], Status: status_supported, Updated: updated}
579-
580-
api_deprecated_v1 := apiversions.APIVersion{ID: api_version[1], Status: status_deprecated, Updated: updated}
581-
api_deprecated_v2 := apiversions.APIVersion{ID: api_version[2], Status: status_deprecated, Updated: updated}
582-
583-
var testCases = []struct {
584-
test_case []apiversions.APIVersion
585-
wanted_result string
586-
}{
587-
{[]apiversions.APIVersion{api_current_v1}, result_version[1]},
588-
{[]apiversions.APIVersion{api_current_v2}, result_version[2]},
589-
{[]apiversions.APIVersion{api_supported_v1, api_current_v2}, result_version[2]}, // current always selected
590-
{[]apiversions.APIVersion{api_current_v1, api_supported_v2}, result_version[1]}, // current always selected
591-
{[]apiversions.APIVersion{api_current_v3, api_supported_v2, api_deprecated_v1}, result_version[2]}, // with current v3, but should fall back to v2
592-
{[]apiversions.APIVersion{api_current_v3, api_deprecated_v2, api_deprecated_v1}, result_version[0]}, // v3 is not supported
593-
}
594-
595-
for _, suite := range testCases {
596-
if autodetectedVersion := doBsApiVersionAutodetect(suite.test_case); autodetectedVersion != suite.wanted_result {
597-
t.Fatalf("Autodetect for suite: %s, failed with result: '%s', wanted '%s'", suite.test_case, autodetectedVersion, suite.wanted_result)
598-
}
599-
}
600-
}
601-
602559
func TestInstanceIDFromProviderID(t *testing.T) {
603560
testCases := []struct {
604561
providerID string

0 commit comments

Comments
 (0)