diff --git a/pkg/multicloud/openstack/hypervisor.go b/pkg/multicloud/openstack/hypervisor.go index e856cd0dc4..0e0f764126 100644 --- a/pkg/multicloud/openstack/hypervisor.go +++ b/pkg/multicloud/openstack/hypervisor.go @@ -100,7 +100,7 @@ func (host *SHypervisor) GetIWires() ([]cloudprovider.ICloudWire, error) { func (host *SHypervisor) GetIStorages() ([]cloudprovider.ICloudStorage, error) { istorages := []cloudprovider.ICloudStorage{} storages, err := host.zone.region.GetStorageTypes() - if err != nil { + if err != nil && errors.Cause(err) != ErrNoEndpoint { return nil, errors.Wrap(err, "GetStorageTypes") } for i := range storages { diff --git a/pkg/multicloud/openstack/openstack.go b/pkg/multicloud/openstack/openstack.go index 2a7cad14ba..e4070c962c 100644 --- a/pkg/multicloud/openstack/openstack.go +++ b/pkg/multicloud/openstack/openstack.go @@ -45,6 +45,8 @@ const ( OPENSTACK_SERVICE_VOLUMEV2 = "volumev2" OPENSTACK_SERVICE_VOLUME = "volume" OPENSTACK_SERVICE_IMAGE = "image" + + ErrNoEndpoint = errors.Error("no valid endpoint") ) type OpenstackClientConfig struct { @@ -256,12 +258,20 @@ func jsonReuest(token mcclient.TokenCredential, service, region, endpointType st } } - requestUrl := resource - if !strings.HasPrefix(resource, serviceUrl) { - requestUrl = fmt.Sprintf("%s/%s", serviceUrl, resource) + if service == OPENSTACK_SERVICE_IDENTITY { + if strings.HasSuffix(serviceUrl, "/v3/") { + serviceUrl = strings.TrimSuffix(serviceUrl, "/v3/") + } else if strings.HasSuffix(serviceUrl, "/v3") { + serviceUrl = strings.TrimSuffix(serviceUrl, "/v3") + } } - if query != nil { + requestUrl := resource + if !strings.HasPrefix(resource, serviceUrl) { + requestUrl = fmt.Sprintf("%s/%s", strings.TrimSuffix(serviceUrl, "/"), strings.TrimPrefix(resource, "/")) + } + + if query != nil && len(query) > 0 { requestUrl = fmt.Sprintf("%s?%s", requestUrl, query.Encode()) } @@ -333,7 +343,7 @@ func (cli *SOpenStackClient) bsRequest(region string, method httputils.THttpMeth return jsonReuest(cli.tokenCredential, service, region, cli.endpointType, method, resource, query, body, cli.debug) } } - return nil, fmt.Errorf("no valid volume service endpoint") + return nil, errors.Wrap(ErrNoEndpoint, "cinder service") } func (cli *SOpenStackClient) bsCreate(projectId, region, resource string, body interface{}) (jsonutils.JSONObject, error) { @@ -351,7 +361,7 @@ func (cli *SOpenStackClient) bsCreate(projectId, region, resource string, body i return jsonReuest(token, service, region, cli.endpointType, httputils.POST, resource, nil, body, cli.debug) } } - return nil, fmt.Errorf("no valid volume service endpoint") + return nil, errors.Wrap(ErrNoEndpoint, "cinder service") } func (cli *SOpenStackClient) imageUpload(region, url string, body io.Reader) (*http.Response, error) { diff --git a/pkg/multicloud/openstack/zone.go b/pkg/multicloud/openstack/zone.go index f8327ad51f..69e951f763 100644 --- a/pkg/multicloud/openstack/zone.go +++ b/pkg/multicloud/openstack/zone.go @@ -112,7 +112,7 @@ func (zone *SZone) getStorageByCategory(category, host string) (*SStorage, error func (zone *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) { storages, err := zone.region.GetStorageTypes() - if err != nil { + if err != nil && errors.Cause(err) != ErrNoEndpoint { return nil, errors.Wrap(err, "GetStorageTypes") } istorages := []cloudprovider.ICloudStorage{}