Merge pull request #5591 from yousong/feature/yousong-backport-proxyfunc

Feature/yousong backport proxyfunc
This commit is contained in:
Zexi Li
2020-03-26 10:41:11 +08:00
committed by GitHub
130 changed files with 2479 additions and 593 deletions
+5 -1
View File
@@ -84,7 +84,11 @@ func newClient(options *BaseOptions) (*aliyun.SRegion, error) {
return nil, fmt.Errorf("Missing secret")
}
cli, err := aliyun.NewAliyunClient("", "", options.AccessKey, options.Secret, options.Debug)
cli, err := aliyun.NewAliyunClient(
aliyun.NewAliyunClientConfig(
options.AccessKey, options.Secret,
).Debug(options.Debug),
)
if err != nil {
return nil, err
}
+7 -1
View File
@@ -85,7 +85,13 @@ func newClient(options *BaseOptions) (*aws.SRegion, error) {
return nil, fmt.Errorf("Missing secret")
}
cli, err := aws.NewAwsClient("", "", options.AccessUrl, options.AccessKey, options.Secret, options.Debug)
cli, err := aws.NewAwsClient(
aws.NewAwsClientConfig(
options.AccessUrl,
options.AccessKey,
options.Secret,
).Debug(options.Debug),
)
if err != nil {
return nil, err
}
+11 -5
View File
@@ -100,11 +100,17 @@ func newClient(options *BaseOptions) (*azure.SRegion, error) {
return nil, fmt.Errorf("Missing Cloud Environment")
}
cli, err := azure.NewAzureClient("", "", options.CloudEnv,
options.DirectoryID,
options.ApplicationID, options.ApplicationKey,
options.SubscriptionID,
options.Debug)
cli, err := azure.NewAzureClient(
azure.NewAzureClientConfig(
options.CloudEnv,
options.DirectoryID,
options.ApplicationID,
options.ApplicationKey,
).
SubscriptionId(options.SubscriptionID).
Debug(options.Debug),
)
if err != nil {
return nil, err
}
+13
View File
@@ -381,6 +381,19 @@ func init() {
return nil
})
R(&options.SGoogleCloudAccountUpdateOptions{}, "cloud-account-update-google", "update a google cloud account", func(s *mcclient.ClientSession, args *options.SGoogleCloudAccountUpdateOptions) error {
params := jsonutils.Marshal(args).(*jsonutils.JSONDict)
if params.Size() == 0 {
return InvalidUpdateError()
}
result, err := modules.Cloudaccounts.Update(s, args.ID, params)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&options.SAWSCloudAccountUpdateOptions{}, "cloud-account-update-aws", "update an AWS cloud account", func(s *mcclient.ClientSession, args *options.SAWSCloudAccountUpdateOptions) error {
params := jsonutils.Marshal(args).(*jsonutils.JSONDict)
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
R(&options.ProxySettingCreateOptions{}, "proxysetting-create", "Create proxysetting", func(s *mcclient.ClientSession, opts *options.ProxySettingCreateOptions) error {
params, err := options.StructToParams(opts)
if err != nil {
return err
}
proxysetting, err := modules.ProxySettings.Create(s, params)
if err != nil {
return err
}
printObject(proxysetting)
return nil
})
R(&options.ProxySettingGetOptions{}, "proxysetting-show", "Show proxysetting", func(s *mcclient.ClientSession, opts *options.ProxySettingGetOptions) error {
proxysetting, err := modules.ProxySettings.Get(s, opts.ID, nil)
if err != nil {
return err
}
printObject(proxysetting)
return nil
})
R(&options.ProxySettingListOptions{}, "proxysetting-list", "List proxysettings", func(s *mcclient.ClientSession, opts *options.ProxySettingListOptions) error {
params, err := options.ListStructToParams(opts)
if err != nil {
return err
}
result, err := modules.ProxySettings.List(s, params)
if err != nil {
return err
}
printList(result, modules.ProxySettings.GetColumns(s))
return nil
})
R(&options.ProxySettingUpdateOptions{}, "proxysetting-update", "Update proxysetting", func(s *mcclient.ClientSession, opts *options.ProxySettingUpdateOptions) error {
params, err := options.StructToParams(opts)
proxysetting, err := modules.ProxySettings.Update(s, opts.ID, params)
if err != nil {
return err
}
printObject(proxysetting)
return nil
})
R(&options.ProxySettingDeleteOptions{}, "proxysetting-delete", "Delete proxysetting", func(s *mcclient.ClientSession, opts *options.ProxySettingDeleteOptions) error {
proxysetting, err := modules.ProxySettings.Delete(s, opts.ID, nil)
if err != nil {
return err
}
printObject(proxysetting)
return nil
})
}
+5 -2
View File
@@ -84,8 +84,11 @@ func newClient(options *BaseOptions) (*ctyun.SRegion, error) {
return nil, fmt.Errorf("Missing secret")
}
cli, err := ctyun.NewSCtyunClient("", "", "",
options.AccessKey, options.Secret, options.Debug)
cli, err := ctyun.NewSCtyunClient(
ctyun.NewSCtyunClientConfig(
options.AccessKey, options.Secret,
).Debug(options.Debug),
)
if err != nil {
return nil, err
}
+8 -1
View File
@@ -88,7 +88,14 @@ func newClient(options *BaseOptions) (*esxi.SESXiClient, error) {
return nil, fmt.Errorf("Missing password")
}
return esxi.NewESXiClient2("", "", options.Host, options.Port, options.Account, options.Password, false)
return esxi.NewESXiClient2(
esxi.NewESXiClientConfig(
options.Host,
options.Port,
options.Account,
options.Password,
),
)
}
func main() {
+8 -1
View File
@@ -94,7 +94,14 @@ func newClient(options *BaseOptions) (*google.SRegion, error) {
return nil, fmt.Errorf("Missing ProjectID")
}
cli, err := google.NewGoogleClient("", "", options.ProjectID, options.ClientEmail, options.PrivateKeyID, options.PrivateKey, options.Debug)
cli, err := google.NewGoogleClient(
google.NewGoogleClientConfig(
options.ProjectID,
options.ClientEmail,
options.PrivateKeyID,
options.PrivateKey,
).Debug(options.Debug),
)
if err != nil {
return nil, err
}
+8 -3
View File
@@ -86,9 +86,14 @@ func newClient(options *BaseOptions) (*huawei.SRegion, error) {
return nil, fmt.Errorf("Missing secret")
}
cli, err := huawei.NewHuaweiClient("", "", options.CloudEnv,
options.AccessKey, options.Secret, options.ProjectId,
options.Debug)
cli, err := huawei.NewHuaweiClient(
huawei.NewHuaweiClientConfig(
options.CloudEnv,
options.AccessKey,
options.Secret,
options.ProjectId,
).Debug(options.Debug),
)
if err != nil {
return nil, err
}
+12 -1
View File
@@ -93,7 +93,18 @@ func newClient(options *BaseOptions) (*openstack.SRegion, error) {
return nil, fmt.Errorf("Missing Password")
}
cli, err := openstack.NewOpenStackClient("", "", options.AuthURL, options.Username, options.Password, options.Project, options.EndpointType, options.DomainName, options.ProjectDomain, options.Debug)
cli, err := openstack.NewOpenStackClient(
openstack.NewOpenstackClientConfig(
options.AuthURL,
options.Username,
options.Password,
options.Project,
options.ProjectDomain,
).
EndpointType(options.EndpointType).
DomainName(options.DomainName).
Debug(options.Debug),
)
if err != nil {
return nil, err
}
+6 -5
View File
@@ -85,11 +85,12 @@ func newClient(options *BaseOptions) (*qcloud.SRegion, error) {
return nil, fmt.Errorf("Missing SecretID")
}
if cli, err := qcloud.NewQcloudClient("", "",
options.SecretID,
options.SecretKey,
options.AppID,
options.Debug); err != nil {
if cli, err := qcloud.NewQcloudClient(
qcloud.NewQcloudClientConfig(
options.SecretID,
options.SecretKey,
).AppId(options.AppID).Debug(options.Debug),
); err != nil {
return nil, err
} else if region := cli.GetRegion(options.RegionId); region == nil {
return nil, fmt.Errorf("No such region %s", options.RegionId)
+15 -3
View File
@@ -94,11 +94,23 @@ func newClient(options *BaseOptions) (cloudprovider.ICloudRegion, error) {
}
if options.Backend == api.CLOUD_PROVIDER_CEPH {
return ceph.NewCephRados("", "", options.AccessUrl, options.AccessKey, options.Secret, options.Debug)
return ceph.NewCephRados(
objectstore.NewObjectStoreClientConfig(
options.AccessUrl, options.AccessKey, options.Secret,
).Debug(options.Debug),
)
} else if options.Backend == api.CLOUD_PROVIDER_XSKY {
return xsky.NewXskyClient("", "", options.AccessUrl, options.AccessKey, options.Secret, options.Debug)
return xsky.NewXskyClient(
objectstore.NewObjectStoreClientConfig(
options.AccessUrl, options.AccessKey, options.Secret,
).Debug(options.Debug),
)
}
return objectstore.NewObjectStoreClient("", "", options.AccessUrl, options.AccessKey, options.Secret, options.Debug)
return objectstore.NewObjectStoreClient(
objectstore.NewObjectStoreClientConfig(
options.AccessUrl, options.AccessKey, options.Secret,
).Debug(options.Debug),
)
}
func main() {
+6 -5
View File
@@ -86,11 +86,12 @@ func newClient(options *BaseOptions) (*ucloud.SRegion, error) {
return nil, fmt.Errorf("Missing secret")
}
cli, err := ucloud.NewUcloudClient("", "",
options.AccessKey,
options.Secret,
options.ProjectId,
options.Debug)
cli, err := ucloud.NewUcloudClient(
ucloud.NewUcloudClientConfig(
options.AccessKey,
options.Secret,
).ProjectId(options.ProjectId).Debug(options.Debug),
)
if err != nil {
return nil, err
}
+7 -1
View File
@@ -89,7 +89,13 @@ func newClient(options *BaseOptions) (*zstack.SRegion, error) {
return nil, fmt.Errorf("Missing Password")
}
cli, err := zstack.NewZStackClient("", "", options.AuthURL, options.Username, options.Password, options.Debug)
cli, err := zstack.NewZStackClient(
zstack.NewZstackClientConfig(
options.AuthURL,
options.Username,
options.Password,
).Debug(options.Debug),
)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -97,7 +97,7 @@ require (
github.com/smartystreets/goconvey v1.6.4
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/stretchr/testify v1.4.0
github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181108132626-805d01dd0e2e
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible
github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20191108095731-8ca4b370cde4
github.com/tinylib/msgp v1.1.0 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
+2 -2
View File
@@ -693,8 +693,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/syncthing/syncthing v0.14.48-rc.4/go.mod h1:nw3siZwHPA6M8iSfjDCWQ402eqvEIasMQOE8nFOxy7M=
github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181108132626-805d01dd0e2e h1:CtKVGXKh2bfmepZ/YogAjvL/CrSy9NGZET500K7arf4=
github.com/tencentcloud/tencentcloud-sdk-go v0.0.0-20181108132626-805d01dd0e2e/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible h1:QIMoFqKCmNp4HPLiTR+couZbHsIZfoOllncHYvtqse8=
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20191108095731-8ca4b370cde4 h1:wVKDVTKxaf0ll8ONv22Q+cazYSSmcWt7JJOeQD0LoKQ=
github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20191108095731-8ca4b370cde4/go.mod h1:wk2XFUg6egk4tSDNZtXeKfe2G6690UVyt163PuUxBZk=
github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s=
+1
View File
@@ -0,0 +1 @@
package proxy // import "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
+36
View File
@@ -0,0 +1,36 @@
package proxy
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/apis"
)
const (
ProxySettingId_DIRECT = "DIRECT"
)
type ProxySettingCreateInput struct {
apis.VirtualResourceCreateInput
HttpProxy string
HttpsProxy string
NoProxy string
}
type ProxySettingUpdateInput ProxySettingCreateInput
// String implements ISerializable interface
func (ps *SProxySetting) String() string {
return jsonutils.Marshal(ps).String()
}
// IsZero implements ISerializable interface
func (ps *SProxySetting) IsZero() bool {
if ps.HTTPProxy == "" &&
ps.HTTPSProxy == "" &&
ps.NoProxy == "" {
return true
}
return false
}
@@ -0,0 +1,27 @@
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by model-api-gen. DO NOT EDIT.
package proxy
import (
"yunion.io/x/onecloud/pkg/apis"
)
// SProxySetting is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db/proxy.SProxySetting.
type SProxySetting struct {
apis.SStandaloneResourceBase
HTTPProxy string `json:"http_proxy"`
HTTPSProxy string `json:"https_proxy"`
NoProxy string `json:"no_proxy"`
}
+3
View File
@@ -79,6 +79,9 @@ type CloudaccountCreateInput struct {
// 额外信息,例如账单的access key
Options *jsonutils.JSONObject `json:"options"`
// 代理配置
ProxySettingId string `json:"proxy_setting_id"`
cloudprovider.SCloudaccount
cloudprovider.SCloudaccountCredential
}
+3
View File
@@ -18,6 +18,7 @@ import (
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/apis"
proxyapi "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
@@ -96,6 +97,8 @@ type CloudproviderDetails struct {
apis.StandaloneResourceDetails
SCloudprovider
ProxySetting proxyapi.SProxySetting `json:"proxy_setting"`
// 云账号名称
// example: google-account
Cloudaccount string `json:"cloudaccount"`
+3
View File
@@ -195,6 +195,8 @@ type SCloudaccount struct {
IsPublic bool `json:"is_public"`
// add share_mode field to indicate the share range of this account
ShareMode string `json:"share_mode"`
// 默认值proxyapi.ProxySettingId_DIRECT
ProxySettingId string `json:"proxy_setting_id"`
}
// SCloudprovider is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SCloudprovider.
@@ -215,6 +217,7 @@ type SCloudprovider struct {
type SCloudproviderCapability struct {
apis.SResourceBase
CloudproviderId string `json:"cloudprovider_id"`
CloudregionId string `json:"cloudregion_id"`
Capability string `json:"capability"`
}
+1
View File
@@ -0,0 +1 @@
package proxy // import "yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
+113
View File
@@ -0,0 +1,113 @@
package proxy
import (
"context"
"database/sql"
"net/http"
"net/url"
"golang.org/x/net/http/httpproxy"
"yunion.io/x/jsonutils"
proxyapi "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/httputils"
)
type SProxySettingManager struct {
db.SStandaloneResourceBaseManager
}
var ProxySettingManager *SProxySettingManager
func init() {
ProxySettingManager = &SProxySettingManager{
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
SProxySetting{},
"proxysettings_tbl",
"proxysetting",
"proxysettings",
),
}
ProxySettingManager.SetVirtualObject(ProxySettingManager)
}
type SProxySetting struct {
db.SStandaloneResourceBase
HTTPProxy string `create:"admin_optional" list:"admin" update:"admin"`
HTTPSProxy string `create:"admin_optional" list:"admin" update:"admin"`
NoProxy string `create:"admin_optional" list:"admin" update:"admin"`
}
func (man *SProxySettingManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data proxyapi.ProxySettingCreateInput) (proxyapi.ProxySettingCreateInput, error) {
return data, nil
}
func (ps *SProxySetting) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data proxyapi.ProxySettingUpdateInput) (proxyapi.ProxySettingUpdateInput, error) {
if ps.Id == proxyapi.ProxySettingId_DIRECT {
return data, httperrors.NewConflictError("DIRECT setting cannot be changed")
}
return data, nil
}
func (ps *SProxySetting) HttpTransportProxyFunc() httputils.TransportProxyFunc {
cfg := &httpproxy.Config{
HTTPProxy: ps.HTTPProxy,
HTTPSProxy: ps.HTTPSProxy,
NoProxy: ps.NoProxy,
}
proxyFunc := cfg.ProxyFunc()
return func(req *http.Request) (*url.URL, error) {
return proxyFunc(req.URL)
}
}
func (ps *SProxySetting) ValidateDeleteCondition(ctx context.Context) error {
for _, man := range referrersMen {
t := man.TableSpec().Instance()
n, err := t.Query().
Equals("proxy_setting_id", ps.Id).
CountWithError()
if err != nil {
return httperrors.NewInternalServerError("get proxysetting refcount fail %s", err)
}
if n > 0 {
return httperrors.NewResourceBusyError("proxysetting %s is still referred to by %d %s",
ps.Id, n, man.KeywordPlural())
}
}
return nil
}
func (man *SProxySettingManager) InitializeData() error {
_, err := man.FetchById(proxyapi.ProxySettingId_DIRECT)
if err == nil {
return nil
}
if err != sql.ErrNoRows {
return err
}
m, err := db.NewModelObject(man)
if err != nil {
return err
}
ps := m.(*SProxySetting)
ps.Id = proxyapi.ProxySettingId_DIRECT
ps.Name = proxyapi.ProxySettingId_DIRECT
ps.Description = "Connect directly"
if err := man.TableSpec().Insert(ps); err != nil {
return err
}
return nil
}
var referrersMen []db.IModelManager
func RegisterReferrer(man db.IModelManager) {
referrersMen = append(referrersMen, man)
}
+30 -1
View File
@@ -16,8 +16,12 @@ package models
import (
"context"
"net/http"
"net/url"
"time"
"golang.org/x/net/http/httpproxy"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
@@ -25,6 +29,7 @@ import (
"yunion.io/x/pkg/util/timeutils"
"yunion.io/x/pkg/utils"
proxyapi "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
@@ -68,6 +73,8 @@ type SCloudprovider struct {
Provider string `width:"64" charset:"ascii" list:"domain"`
Brand string `width:"64" charset:"ascii" list:"domain"`
ProxySetting *proxyapi.SProxySetting
}
func (manager *SCloudproviderManager) GetRegionCloudproviders(ctx context.Context, userCred mcclient.TokenCredential) ([]SCloudprovider, error) {
@@ -299,7 +306,29 @@ func (provider *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, err
if err != nil {
return nil, err
}
return cloudprovider.GetProvider(provider.Id, provider.Name, accessUrl, provider.Account, passwd, provider.Provider)
ps := provider.ProxySetting
cfg := &httpproxy.Config{
HTTPProxy: ps.HTTPProxy,
HTTPSProxy: ps.HTTPSProxy,
NoProxy: ps.NoProxy,
}
cfgProxyFunc := cfg.ProxyFunc()
proxyFunc := func(req *http.Request) (*url.URL, error) {
return cfgProxyFunc(req.URL)
}
return cloudprovider.GetProvider(
cloudprovider.ProviderConfig{
Id: provider.Id,
Name: provider.Name,
Vendor: provider.Provider,
URL: accessUrl,
Account: provider.Account,
Secret: passwd,
ProxyFunc: proxyFunc,
},
)
}
func (manager *SCloudproviderManager) InitializeData() error {
+3
View File
@@ -18,6 +18,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
)
func InitDB() error {
@@ -28,6 +29,8 @@ func InitDB() error {
*/
db.TenantCacheManager,
proxy.ProxySettingManager,
CloudproviderManager,
CloudeventManager,
} {
+2
View File
@@ -32,6 +32,7 @@ import (
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/appsrv/dispatcher"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudevent/models"
)
@@ -54,6 +55,7 @@ func InitHandlers(app *appsrv.Application) {
for _, manager := range []db.IModelManager{
db.OpsLog,
proxy.ProxySettingManager,
models.CloudeventManager,
} {
db.RegisterModelManager(manager)
+22 -7
View File
@@ -25,6 +25,7 @@ import (
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/httputils"
)
const (
@@ -140,8 +141,22 @@ type SCloudaccount struct {
AccessUrl string `json:"access_url"`
}
type ProviderConfig struct {
// Id, Name are properties of Cloudprovider object
Id string
Name string
// Vendor are names like Aliyun, OpenStack, etc.
Vendor string
URL string
Account string
Secret string
ProxyFunc httputils.TransportProxyFunc
}
type ICloudProviderFactory interface {
GetProvider(providerId, providerName, url, account, secret string) (ICloudProvider, error)
GetProvider(cfg ProviderConfig) (ICloudProvider, error)
GetClientRC(url, account, secret string) (map[string]string, error)
@@ -240,12 +255,12 @@ func GetRegistedProviderIds() []string {
return providers
}
func GetProvider(providerId, providerName, accessUrl, account, secret, provider string) (ICloudProvider, error) {
driver, err := GetProviderFactory(provider)
func GetProvider(cfg ProviderConfig) (ICloudProvider, error) {
driver, err := GetProviderFactory(cfg.Vendor)
if err != nil {
return nil, errors.Wrap(err, "GetProviderFactory")
}
return driver.GetProvider(providerId, providerName, accessUrl, account, secret)
return driver.GetProvider(cfg)
}
func GetClientRC(accessUrl, account, secret, provider string) (map[string]string, error) {
@@ -261,10 +276,10 @@ func IsSupported(provider string) bool {
return ok
}
func IsValidCloudAccount(accessUrl, account, secret, provider string) (string, error) {
factory, ok := providerTable[provider]
func IsValidCloudAccount(cfg ProviderConfig) (string, error) {
factory, ok := providerTable[cfg.Vendor]
if ok {
provider, err := factory.GetProvider("", "", accessUrl, account, secret)
provider, err := factory.GetProvider(cfg)
if err != nil {
return "", err
}
+75 -3
View File
@@ -32,10 +32,12 @@ import (
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
proxyapi "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
@@ -46,6 +48,7 @@ import (
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/util/choices"
"yunion.io/x/onecloud/pkg/util/httputils"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
@@ -68,6 +71,8 @@ func init() {
),
}
CloudaccountManager.SetVirtualObject(CloudaccountManager)
proxy.RegisterReferrer(CloudaccountManager)
}
type SCloudaccount struct {
@@ -148,6 +153,9 @@ type SCloudaccount struct {
IsPublic bool `default:"false" nullable:"false"`
// add share_mode field to indicate the share range of this account
ShareMode string `width:"32" charset:"ascii" nullable:"true" list:"domain"`
// 默认值proxyapi.ProxySettingId_DIRECT
ProxySettingId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"optional" update:"domain" default:"DIRECT"`
}
func (self *SCloudaccountManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
@@ -305,6 +313,16 @@ func (self *SCloudaccount) ValidateUpdateData(ctx context.Context, userCred mccl
}
data.Set("options", optionsJson)
}
v := validators.NewModelIdOrNameValidator(
"proxy_setting",
proxy.ProxySettingManager.Keyword(),
userCred,
)
if err := v.Validate(data); err != nil {
return nil, err
}
return self.SEnabledStatusStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data)
}
@@ -362,7 +380,27 @@ func (manager *SCloudaccountManager) ValidateCreateData(ctx context.Context, use
return input, httperrors.NewConflictError("The account has been registered")
}
accountId, err := cloudprovider.IsValidCloudAccount(input.AccessUrl, input.Account, input.Secret, input.Provider)
var proxyFunc httputils.TransportProxyFunc
{
if input.ProxySettingId == "" {
input.ProxySettingId = proxyapi.ProxySettingId_DIRECT
}
m, err := proxy.ProxySettingManager.FetchByIdOrName(userCred, input.ProxySettingId)
if err != nil {
return input, httperrors.NewInputParameterError("fetch proxysetting %s: %s",
input.ProxySettingId, err)
}
proxySetting := m.(*proxy.SProxySetting)
input.ProxySettingId = proxySetting.Id
proxyFunc = proxySetting.HttpTransportProxyFunc()
}
accountId, err := cloudprovider.IsValidCloudAccount(cloudprovider.ProviderConfig{
Vendor: input.Provider,
URL: input.AccessUrl,
Account: input.Account,
Secret: input.Secret,
ProxyFunc: proxyFunc,
})
if err != nil {
if err == cloudprovider.ErrNoSuchProvder {
return input, httperrors.NewResourceNotFoundError("no such provider %s", input.Provider)
@@ -516,7 +554,13 @@ func (self *SCloudaccount) PerformUpdateCredential(ctx context.Context, userCred
originSecret, _ := self.getPassword()
accountId, err := cloudprovider.IsValidCloudAccount(self.AccessUrl, account.Account, account.Secret, self.Provider)
accountId, err := cloudprovider.IsValidCloudAccount(cloudprovider.ProviderConfig{
Vendor: self.Provider,
URL: self.AccessUrl,
Account: account.Account,
Secret: account.Secret,
ProxyFunc: self.proxyFunc(),
})
if err != nil {
return nil, httperrors.NewInputParameterError("invalid cloud account info error: %s", err.Error())
}
@@ -668,12 +712,40 @@ func (self *SCloudaccount) GetProvider() (cloudprovider.ICloudProvider, error) {
return self.getProviderInternal()
}
func (self *SCloudaccount) proxySetting() *proxy.SProxySetting {
m, err := proxy.ProxySettingManager.FetchById(self.ProxySettingId)
if err != nil {
log.Errorf("cloudaccount %s(%s): get proxysetting %s: %v",
self.Name, self.Id, self.ProxySettingId, err)
return nil
}
ps := m.(*proxy.SProxySetting)
return ps
}
func (self *SCloudaccount) proxyFunc() httputils.TransportProxyFunc {
ps := self.proxySetting()
if ps != nil {
return ps.HttpTransportProxyFunc()
}
return nil
}
func (self *SCloudaccount) getProviderInternal() (cloudprovider.ICloudProvider, error) {
secret, err := self.getPassword()
if err != nil {
return nil, fmt.Errorf("Invalid password %s", err)
}
return cloudprovider.GetProvider(self.Id, self.Name, self.AccessUrl, self.Account, secret, self.Provider)
return cloudprovider.GetProvider(cloudprovider.ProviderConfig{
Id: self.Id,
Name: self.Name,
Vendor: self.Provider,
URL: self.AccessUrl,
Account: self.Account,
Secret: secret,
ProxyFunc: self.proxyFunc(),
})
}
func (self *SCloudaccount) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
+21 -1
View File
@@ -737,7 +737,18 @@ func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error)
if err != nil {
return nil, err
}
return cloudprovider.GetProvider(self.Id, self.Name, accessUrl, self.Account, passwd, self.Provider)
account := self.GetCloudaccount()
return cloudprovider.GetProvider(cloudprovider.ProviderConfig{
Id: self.Id,
Name: self.Name,
Vendor: self.Provider,
URL: accessUrl,
Account: self.Account,
Secret: passwd,
ProxyFunc: account.proxyFunc(),
})
}
func (self *SCloudprovider) savePassword(secret string) error {
@@ -871,7 +882,16 @@ func (self *SCloudprovider) getMoreDetails(ctx context.Context, out api.Cloudpro
// 此字段不能删除,公有云日志同步需要这个字段
out.Brand = account.Brand
out.Cloudaccount = account.GetName()
ps := account.proxySetting()
if ps != nil {
out.ProxySetting.Id = ps.Id
out.ProxySetting.Name = ps.Name
out.ProxySetting.HTTPProxy = ps.HTTPProxy
out.ProxySetting.HTTPSProxy = ps.HTTPSProxy
out.ProxySetting.NoProxy = ps.NoProxy
}
}
out.SyncStatus2 = self.getSyncStatus2()
capabilities, _ := CloudproviderCapabilityManager.getCapabilities(self.Id)
if len(capabilities) > 0 {
+3
View File
@@ -18,6 +18,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
)
func InitDB() error {
@@ -28,6 +29,8 @@ func InitDB() error {
*/
db.TenantCacheManager,
proxy.ProxySettingManager,
QuotaManager,
CloudproviderManager,
+4
View File
@@ -18,6 +18,7 @@ import (
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/appsrv/dispatcher"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/capabilities"
@@ -81,6 +82,9 @@ func InitHandlers(app *appsrv.Application) {
for _, manager := range []db.IModelManager{
db.OpsLog,
db.Metadata,
proxy.ProxySettingManager,
models.BucketManager,
models.CloudaccountManager,
models.CloudproviderManager,
+4
View File
@@ -79,6 +79,10 @@ func (this *Client) HttpClient() *http.Client {
return this.httpconn
}
func (this *Client) SetHttpTransportProxyFunc(proxyFunc httputils.TransportProxyFunc) {
httputils.SetClientProxyFunc(this.httpconn, proxyFunc)
}
func (this *Client) SetDebug(debug bool) {
this.debug = debug
}
+40
View File
@@ -0,0 +1,40 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
)
type ProxySettingManager struct {
modulebase.ResourceManager
}
var (
ProxySettings ProxySettingManager
)
func init() {
ProxySettings = ProxySettingManager{NewComputeManager("proxysetting", "proxysettings",
[]string{
"ID",
"Name",
"http_proxy",
"https_proxy",
"no_proxy",
},
[]string{})}
registerCompute(&ProxySettings)
}
+7 -2
View File
@@ -227,8 +227,9 @@ type SCloudAccountUpdateBaseOptions struct {
ID string `help:"ID or Name of cloud account" json:"-"`
Name string `help:"New name to update"`
SyncIntervalSeconds int `help:"auto synchornize interval in seconds"`
AutoCreateProject *bool `help:"automatically create local project for new remote project"`
SyncIntervalSeconds int `help:"auto synchornize interval in seconds"`
AutoCreateProject *bool `help:"automatically create local project for new remote project"`
ProxySetting string `help:"proxy setting name or id"`
Desc string `help:"Description" json:"description" token:"desc"`
}
@@ -259,6 +260,10 @@ type SQcloudCloudAccountUpdateOptions struct {
SCloudAccountUpdateBaseOptions
}
type SGoogleCloudAccountUpdateOptions struct {
SCloudAccountUpdateBaseOptions
}
type SAWSCloudAccountUpdateOptions struct {
SCloudAccountUpdateBaseOptions
+42
View File
@@ -0,0 +1,42 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package options
type ProxySettingCreateOptions struct {
NAME string
HTTPProxy string
HTTPSProxy string
NoProxy string
}
type ProxySettingGetOptions struct {
ID string `json:"-"`
}
type ProxySettingUpdateOptions struct {
ID string `json:"-"`
Name string
BackendGroup string
}
type ProxySettingDeleteOptions struct {
ID string `json:"-"`
}
type ProxySettingListOptions struct {
BaseListOptions
}
+54 -29
View File
@@ -20,6 +20,7 @@ import (
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/pkg/errors"
@@ -53,28 +54,48 @@ const (
ALIYUN_API_VERION_RDS = "2014-08-15"
)
type SAliyunClient struct {
providerId string
providerName string
type AliyunClientConfig struct {
cpcfg cloudprovider.ProviderConfig
accessKey string
secret string
accessSecret string
debug bool
}
func NewAliyunClientConfig(accessKey, accessSecret string) *AliyunClientConfig {
cfg := &AliyunClientConfig{
accessKey: accessKey,
accessSecret: accessSecret,
}
return cfg
}
func (cfg *AliyunClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *AliyunClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *AliyunClientConfig) Debug(debug bool) *AliyunClientConfig {
cfg.debug = debug
return cfg
}
func (cfg AliyunClientConfig) Copy() AliyunClientConfig {
return cfg
}
type SAliyunClient struct {
*AliyunClientConfig
ownerId string
ownerName string
iregions []cloudprovider.ICloudRegion
iBuckets []cloudprovider.ICloudBucket
Debug bool
}
func NewAliyunClient(providerId string, providerName string, accessKey string, secret string, isDebug bool) (*SAliyunClient, error) {
func NewAliyunClient(cfg *AliyunClientConfig) (*SAliyunClient, error) {
client := SAliyunClient{
providerId: providerId,
providerName: providerName,
accessKey: accessKey,
secret: secret,
Debug: isDebug,
AliyunClientConfig: cfg,
}
err := client.fetchRegions()
if err != nil {
@@ -84,7 +105,7 @@ func NewAliyunClient(providerId string, providerName string, accessKey string, s
if err != nil {
return nil, errors.Wrap(err, "fetchBuckets")
}
if client.Debug {
if client.debug {
log.Debugf("ClientID: %s ClientName: %s", client.ownerId, client.ownerName)
}
return &client, nil
@@ -165,18 +186,20 @@ func _jsonRequest(client *sdk.Client, domain string, version string, apiName str
return body, nil
}
func (self *SAliyunClient) UpdateAccount(accessKey, secret string) error {
if self.accessKey != accessKey || self.secret != secret {
self.accessKey = accessKey
self.secret = secret
return self.fetchRegions()
} else {
return nil
}
}
func (self *SAliyunClient) getDefaultClient() (*sdk.Client, error) {
return sdk.NewClientWithAccessKey(ALIYUN_DEFAULT_REGION, self.accessKey, self.secret)
transport := httputils.GetTransport(true)
transport.Proxy = self.cpcfg.ProxyFunc
client, err := sdk.NewClientWithOptions(
ALIYUN_DEFAULT_REGION,
&sdk.Config{
HttpTransport: transport,
},
&credentials.BaseCredential{
AccessKeyId: self.accessKey,
AccessKeySecret: self.accessSecret,
},
)
return client, err
}
func (self *SAliyunClient) ecsRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
@@ -184,7 +207,7 @@ func (self *SAliyunClient) ecsRequest(apiName string, params map[string]string)
if err != nil {
return nil, err
}
return jsonRequest(cli, "ecs.aliyuncs.com", ALIYUN_API_VERSION, apiName, params, self.Debug)
return jsonRequest(cli, "ecs.aliyuncs.com", ALIYUN_API_VERSION, apiName, params, self.debug)
}
func (self *SAliyunClient) trialRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
@@ -192,7 +215,7 @@ func (self *SAliyunClient) trialRequest(apiName string, params map[string]string
if err != nil {
return nil, err
}
return jsonRequest(cli, "actiontrail.cn-hangzhou.aliyuncs.com", ALIYUN_API_VERSION_TRIAL, apiName, params, self.Debug)
return jsonRequest(cli, "actiontrail.cn-hangzhou.aliyuncs.com", ALIYUN_API_VERSION_TRIAL, apiName, params, self.debug)
}
func (self *SAliyunClient) fetchRegions() error {
@@ -237,11 +260,13 @@ func (client *SAliyunClient) getOssClient(regionId string) (*oss.Client, error)
// which can be used to whitelist ips, domains from http_proxy,
// https_proxy setting
// oss use no timeout client so as to send/download large files
httpClient := httputils.GetAdaptiveTimeoutClient()
httputils.SetClientProxyFunc(httpClient, client.cpcfg.ProxyFunc)
cliOpts := []oss.ClientOption{
oss.HTTPClient(httputils.GetAdaptiveTimeoutClient()),
oss.HTTPClient(httpClient),
}
ep := getOSSExternalDomain(regionId)
cli, err := oss.New(ep, client.accessKey, client.secret, cliOpts...)
cli, err := oss.New(ep, client.accessKey, client.accessSecret, cliOpts...)
if err != nil {
return nil, errors.Wrap(err, "oss.New")
}
@@ -320,7 +345,7 @@ func (self *SAliyunClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error)
return nil, err
}
subAccount := cloudprovider.SSubAccount{}
subAccount.Name = self.providerName
subAccount.Name = self.cpcfg.Name
subAccount.Account = self.accessKey
subAccount.HealthStatus = api.CLOUD_PROVIDER_HEALTH_NORMAL
return []cloudprovider.SSubAccount{subAccount}, nil
+2 -2
View File
@@ -291,7 +291,7 @@ func (b *SBucket) UploadPart(ctx context.Context, key string, uploadId string, p
if err != nil {
return "", errors.Wrap(err, "bucket.UploadPart")
}
if b.region.client.Debug {
if b.region.client.debug {
log.Debugf("upload part key:%s uploadId:%s partIndex:%d etag:%s", key, uploadId, partIndex, part.ETag)
}
return part.ETag, nil
@@ -322,7 +322,7 @@ func (b *SBucket) CompleteMultipartUpload(ctx context.Context, key string, uploa
if err != nil {
return errors.Wrap(err, "bucket.CompleteMultipartUpload")
}
if b.region.client.Debug {
if b.region.client.debug {
log.Debugf("CompleteMultipartUpload bucket:%s key:%s etag:%s location:%s", result.Bucket, result.Key, result.ETag, result.Location)
}
return nil
+1 -1
View File
@@ -29,7 +29,7 @@ func (self *SAliyunClient) businessRequest(apiName string, params map[string]str
if err != nil {
return nil, err
}
return jsonRequest(cli, "business.aliyuncs.com", ALIYUN_BSS_API_VERSION, apiName, params, self.Debug)
return jsonRequest(cli, "business.aliyuncs.com", ALIYUN_BSS_API_VERSION, apiName, params, self.debug)
}
type SAccountBalance struct {
+3 -3
View File
@@ -88,15 +88,15 @@ func (self *SHost) GetIVMById(gid string) (cloudprovider.ICloudVM, error) {
}
func (self *SHost) GetId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) GetName() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId())
}
func (self *SHost) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) IsEmulated() bool {
+1 -1
View File
@@ -31,7 +31,7 @@ func (r *SRegion) metricsRequest(action string, params map[string]string) (jsonu
if err != nil {
return nil, errors.Wrap(err, "r.getSdkClient")
}
return jsonRequest(client, "metrics.aliyuncs.com", ALIYUN_API_VERSION_METRICS, action, params, r.client.Debug)
return jsonRequest(client, "metrics.aliyuncs.com", ALIYUN_API_VERSION_METRICS, action, params, r.client.debug)
}
type SResourceLabel struct {
+1 -1
View File
@@ -207,7 +207,7 @@ func (self *SRegion) GetNatGateways(vpcId string, natGwId string, offset, limit
return nil, 0, err
}
if self.client.Debug {
if self.client.debug {
log.Debugf("%s", body.PrettyString())
}
+2 -2
View File
@@ -94,7 +94,7 @@ func (self *SRegion) GetSNATEntries(tableId string, offset, limit int) ([]SSNATT
return nil, 0, err
}
if self.client.Debug {
if self.client.debug {
log.Debugf("%s", body.PrettyString())
}
@@ -120,7 +120,7 @@ func (self *SRegion) GetSNATEntry(tableID, SNATEntryID string) (SSNATTableEntry,
return SSNATTableEntry{}, err
}
if self.client.Debug {
if self.client.debug {
log.Debugf("%s", body.PrettyString())
}
+7 -2
View File
@@ -71,8 +71,13 @@ func (self *SAliyunProviderFactory) ValidateUpdateCloudaccountCredential(ctx con
return output, nil
}
func (self *SAliyunProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
client, err := aliyun.NewAliyunClient(providerId, providerName, account, secret, true)
func (self *SAliyunProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
client, err := aliyun.NewAliyunClient(
aliyun.NewAliyunClientConfig(
cfg.Account,
cfg.Secret,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -28,7 +28,7 @@ func (self *SAliyunClient) ramRequest(apiName string, params map[string]string)
if err != nil {
return nil, err
}
return jsonRequest(cli, "ram.aliyuncs.com", ALIYUN_RAM_API_VERSION, apiName, params, self.Debug)
return jsonRequest(cli, "ram.aliyuncs.com", ALIYUN_RAM_API_VERSION, apiName, params, self.debug)
}
type SRole struct {
+6 -8
View File
@@ -41,8 +41,6 @@ type SRegion struct {
sdkClient *sdk.Client
ossClient *oss.Client
Debug bool
RegionId string
LocalName string
@@ -75,7 +73,7 @@ func (self *SRegion) GetMetadata() *jsonutils.JSONDict {
func (self *SRegion) getSdkClient() (*sdk.Client, error) {
if self.sdkClient == nil {
cli, err := sdk.NewClientWithAccessKey(self.RegionId, self.client.accessKey, self.client.secret)
cli, err := sdk.NewClientWithAccessKey(self.RegionId, self.client.accessKey, self.client.accessSecret)
if err != nil {
return nil, err
}
@@ -108,7 +106,7 @@ func (self *SRegion) ecsRequest(apiName string, params map[string]string) (jsonu
if err != nil {
return nil, err
}
return jsonRequest(client, "ecs.aliyuncs.com", ALIYUN_API_VERSION, apiName, params, self.client.Debug)
return jsonRequest(client, "ecs.aliyuncs.com", ALIYUN_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) rdsRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
@@ -116,7 +114,7 @@ func (self *SRegion) rdsRequest(apiName string, params map[string]string) (jsonu
if err != nil {
return nil, err
}
return jsonRequest(client, "rds.aliyuncs.com", ALIYUN_API_VERION_RDS, apiName, params, self.client.Debug)
return jsonRequest(client, "rds.aliyuncs.com", ALIYUN_API_VERION_RDS, apiName, params, self.client.debug)
}
func (self *SRegion) vpcRequest(action string, params map[string]string) (jsonutils.JSONObject, error) {
@@ -124,7 +122,7 @@ func (self *SRegion) vpcRequest(action string, params map[string]string) (jsonut
if err != nil {
return nil, err
}
return jsonRequest(client, "vpc.aliyuncs.com", ALIYUN_API_VERSION_VPC, action, params, self.client.Debug)
return jsonRequest(client, "vpc.aliyuncs.com", ALIYUN_API_VERSION_VPC, action, params, self.client.debug)
}
func (self *SRegion) kvsRequest(action string, params map[string]string) (jsonutils.JSONObject, error) {
@@ -132,7 +130,7 @@ func (self *SRegion) kvsRequest(action string, params map[string]string) (jsonut
if err != nil {
return nil, err
}
return jsonRequest(client, "r-kvstore.aliyuncs.com", ALIYUN_API_VERSION_KVS, action, params, self.client.Debug)
return jsonRequest(client, "r-kvstore.aliyuncs.com", ALIYUN_API_VERSION_KVS, action, params, self.client.debug)
}
type LBRegion struct {
@@ -182,7 +180,7 @@ func (self *SRegion) lbRequest(apiName string, params map[string]string) (jsonut
}
func (self *SRegion) _lbRequest(client *sdk.Client, apiName string, domain string, params map[string]string) (jsonutils.JSONObject, error) {
return jsonRequest(client, domain, ALIYUN_API_VERSION_LB, apiName, params, self.Debug)
return jsonRequest(client, domain, ALIYUN_API_VERSION_LB, apiName, params, self.client.debug)
}
/////////////////////////////////////////////////////////////////////////////
+3 -3
View File
@@ -49,15 +49,15 @@ func (self *SStorage) GetMetadata() *jsonutils.JSONDict {
}
func (self *SStorage) GetId() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId(), self.storageType)
}
func (self *SStorage) GetName() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerName, self.zone.GetId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId(), self.storageType)
}
func (self *SStorage) GetGlobalId() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetGlobalId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetGlobalId(), self.storageType)
}
func (self *SStorage) IsEmulated() bool {
+3 -3
View File
@@ -46,11 +46,11 @@ func (self *SStoragecache) GetMetadata() *jsonutils.JSONDict {
}
func (self *SStoragecache) GetId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetId())
}
func (self *SStoragecache) GetName() string {
return fmt.Sprintf("%s-%s", self.region.client.providerName, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Name, self.region.GetId())
}
func (self *SStoragecache) GetStatus() string {
@@ -62,7 +62,7 @@ func (self *SStoragecache) Refresh() error {
}
func (self *SStoragecache) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetGlobalId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetGlobalId())
}
func (self *SStoragecache) IsEmulated() bool {
+1 -1
View File
@@ -246,7 +246,7 @@ func (self *SRegion) GetVSwitchAttributes(idstr string) (*SVSwitch, error) {
log.Errorf("DescribeVSwitchAttributes fail %s", err)
return nil, err
}
if self.client.Debug {
if self.client.debug {
log.Debugf("%s", body.PrettyString())
}
switches := SVSwitch{}
+45 -25
View File
@@ -29,6 +29,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/httputils"
)
const (
@@ -47,32 +48,49 @@ var (
DEBUG = false
)
type SAwsClient struct {
providerId string
providerName string
type AwsClientConfig struct {
cpcfg cloudprovider.ProviderConfig
accessUrl string // 服务区域 ChinaCloud | InternationalCloud
accessKey string
secret string
accessSecret string
debug bool
}
func NewAwsClientConfig(accessUrl, accessKey, accessSecret string) *AwsClientConfig {
cfg := &AwsClientConfig{
accessUrl: accessUrl,
accessKey: accessKey,
accessSecret: accessSecret,
}
return cfg
}
func (cfg *AwsClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *AwsClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *AwsClientConfig) Debug(debug bool) *AwsClientConfig {
cfg.debug = debug
return cfg
}
type SAwsClient struct {
*AwsClientConfig
ownerId string
ownerName string
iregions []cloudprovider.ICloudRegion
iBuckets []cloudprovider.ICloudBucket
debug bool
}
func NewAwsClient(providerId string, providerName string, accessUrl string, accessKey string, secret string, debug bool) (*SAwsClient, error) {
func NewAwsClient(cfg *AwsClientConfig) (*SAwsClient, error) {
client := SAwsClient{
providerId: providerId,
providerName: providerName,
accessUrl: accessUrl,
accessKey: accessKey,
secret: secret,
debug: debug,
AwsClientConfig: cfg,
}
DEBUG = debug
err := client.fetchRegions()
if err != nil {
return nil, errors.Wrap(err, "fetchRegions")
@@ -81,7 +99,7 @@ func NewAwsClient(providerId string, providerName string, accessUrl string, acce
if err != nil {
return nil, errors.Wrap(err, "fetchBuckets")
}
if debug {
if client.debug {
log.Debugf("ownerId: %s ownerName: %s", client.ownerId, client.ownerName)
}
return &client, nil
@@ -114,7 +132,7 @@ func (self *SAwsClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
return nil, err
}
subAccount := cloudprovider.SSubAccount{}
subAccount.Name = self.providerName
subAccount.Name = self.cpcfg.Name
subAccount.Account = self.accessKey
subAccount.HealthStatus = api.CLOUD_PROVIDER_HEALTH_NORMAL
return []cloudprovider.SSubAccount{subAccount}, nil
@@ -125,9 +143,9 @@ func (client *SAwsClient) GetAccountId() string {
}
func (self *SAwsClient) UpdateAccount(accessKey, secret string) error {
if self.accessKey != accessKey || self.secret != secret {
if self.accessKey != accessKey || self.accessSecret != secret {
self.accessKey = accessKey
self.secret = secret
self.accessSecret = secret
self.iregions = nil
return self.fetchRegions()
} else {
@@ -171,14 +189,16 @@ func (self *SAwsClient) fetchRegions() error {
}
func (client *SAwsClient) getAwsSession(regionId string) (*session.Session, error) {
disableParamValidation := true
chainVerboseErrors := true
httpClient := httputils.GetDefaultClient()
httputils.SetClientProxyFunc(httpClient, client.cpcfg.ProxyFunc)
return session.NewSession(&sdk.Config{
Region: sdk.String(regionId),
Credentials: credentials.NewStaticCredentials(client.accessKey, client.secret, ""),
DisableParamValidation: &disableParamValidation,
CredentialsChainVerboseErrors: &chainVerboseErrors,
Region: sdk.String(regionId),
Credentials: credentials.NewStaticCredentials(
client.accessKey, client.accessSecret, "",
),
HTTPClient: httpClient,
DisableParamValidation: sdk.Bool(true),
CredentialsChainVerboseErrors: sdk.Bool(true),
})
}
+3 -3
View File
@@ -34,15 +34,15 @@ type SHost struct {
}
func (self *SHost) GetId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) GetName() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId())
}
func (self *SHost) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) GetStatus() string {
+6 -2
View File
@@ -75,8 +75,12 @@ func (self *SAwsProviderFactory) ValidateUpdateCloudaccountCredential(ctx contex
return output, nil
}
func (self *SAwsProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
client, err := aws.NewAwsClient(providerId, providerName, url, account, secret, false)
func (self *SAwsProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
client, err := aws.NewAwsClient(
aws.NewAwsClientConfig(
cfg.URL, cfg.Account, cfg.Secret,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+3 -3
View File
@@ -30,15 +30,15 @@ type SStorage struct {
}
func (self *SStorage) GetId() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId(), self.storageType)
}
func (self *SStorage) GetName() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerName, self.zone.GetId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId(), self.storageType)
}
func (self *SStorage) GetGlobalId() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetGlobalId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetGlobalId(), self.storageType)
}
func (self *SStorage) GetStatus() string {
+3 -3
View File
@@ -43,15 +43,15 @@ type SStoragecache struct {
}
func (self *SStoragecache) GetId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetId())
}
func (self *SStoragecache) GetName() string {
return fmt.Sprintf("%s-%s", self.region.client.providerName, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Name, self.region.GetId())
}
func (self *SStoragecache) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetGlobalId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetGlobalId())
}
func (self *SStoragecache) GetStatus() string {
+64 -28
View File
@@ -33,6 +33,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/httputils"
)
const (
@@ -43,17 +44,12 @@ const (
)
type SAzureClient struct {
client autorest.Client
providerId string
providerName string
subscriptionId string
tenantId string
clientId string
clientScret string
domain string
baseUrl string
// secret string
envName string
*AzureClientConfig
client autorest.Client
domain string
baseUrl string
ressourceGroups []SResourceGroup
fetchResourceGroups bool
env azureenv.Environment
@@ -91,22 +87,53 @@ var DEFAULT_API_VERSION = map[string]string{
"microsoft.insights/eventtypes/management/values": "2017-03-01-preview",
}
func NewAzureClient(providerId string, providerName string, envName, tenantId, clientId, clientSecret, subscriptionId string, debug bool) (*SAzureClient, error) {
type AzureClientConfig struct {
cpcfg cloudprovider.ProviderConfig
envName string
tenantId string
clientId string
clientSecret string
subscriptionId string
debug bool
}
func NewAzureClientConfig(envName, tenantId, clientId, clientSecret string) *AzureClientConfig {
cfg := &AzureClientConfig{
envName: envName,
tenantId: tenantId,
clientId: clientId,
clientSecret: clientSecret,
}
return cfg
}
func (cfg *AzureClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *AzureClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *AzureClientConfig) SubscriptionId(id string) *AzureClientConfig {
cfg.subscriptionId = id
return cfg
}
func (cfg *AzureClientConfig) Debug(debug bool) *AzureClientConfig {
cfg.debug = debug
return cfg
}
func NewAzureClient(cfg *AzureClientConfig) (*SAzureClient, error) {
client := SAzureClient{
providerId: providerId,
providerName: providerName,
envName: envName,
tenantId: tenantId,
clientId: clientId,
clientScret: clientSecret,
subscriptionId: subscriptionId,
debug: debug,
AzureClientConfig: cfg,
}
err := client.fetchRegions()
if err != nil {
return nil, errors.Wrap(err, "fetchRegions")
}
if len(subscriptionId) > 0 {
if len(cfg.subscriptionId) > 0 {
err = client.fetchBuckets()
if err != nil {
return nil, errors.Wrap(err, "fetchBuckets")
@@ -117,24 +144,33 @@ func NewAzureClient(providerId string, providerName string, envName, tenantId, c
func (self *SAzureClient) getDefaultClient() (*autorest.Client, error) {
client := autorest.NewClientWithUserAgent("Yunion API")
conf := auth.NewClientCredentialsConfig(self.clientId, self.clientScret, self.tenantId)
conf := auth.NewClientCredentialsConfig(self.clientId, self.clientSecret, self.tenantId)
env, err := azureenv.EnvironmentFromName(self.envName)
if err != nil {
return nil, err
}
httpClient := httputils.GetDefaultClient()
httputils.SetClientProxyFunc(httpClient, self.cpcfg.ProxyFunc)
client.Sender = httpClient
self.env = env
self.domain = env.ResourceManagerEndpoint
conf.Resource = env.ResourceManagerEndpoint
conf.AADEndpoint = env.ActiveDirectoryEndpoint
authorizer, err := conf.Authorizer()
if err != nil {
return nil, err
{
spt, err := conf.ServicePrincipalToken()
if err != nil {
return nil, err
}
spt.SetSender(httpClient)
client.Authorizer = autorest.NewBearerAuthorizer(spt)
}
client.Authorizer = authorizer
if self.debug {
client.RequestInspector = LogRequest()
client.ResponseInspector = LogResponse()
}
return &client, nil
}
@@ -730,7 +766,7 @@ func _jsonRequest(client *autorest.Client, method, domain, baseURL, body string)
/*func (self *SAzureClient) UpdateAccount(envName, tenantId, appId, appKey, subscriptionId string) error {
if self.tenantId != tenantId || self.secret != secret || self.envName != envName {
if clientInfo, accountInfo := strings.Split(secret, "/"), strings.Split(tenantId, "/"); len(clientInfo) >= 2 && len(accountInfo) >= 1 {
self.clientId, self.clientScret = clientInfo[0], strings.Join(clientInfo[1:], "/")
self.clientId, self.clientSecret = clientInfo[0], strings.Join(clientInfo[1:], "/")
self.tenantId = accountInfo[0]
if len(accountInfo) == 2 {
self.subscriptionId = accountInfo[1]
@@ -741,7 +777,7 @@ func _jsonRequest(client *autorest.Client, method, domain, baseURL, body string)
}
return nil
} else {
return httperrors.NewUnauthorizedError("clientId、clientScret or subscriptId input error")
return httperrors.NewUnauthorizedError("clientId、clientSecret or subscriptId input error")
}
}
return nil
+1 -1
View File
@@ -35,7 +35,7 @@ func (self *SClassicHost) GetMetadata() *jsonutils.JSONDict {
}
func (self *SClassicHost) GetId() string {
return fmt.Sprintf("%s-%s-classic", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s-classic", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SClassicHost) GetName() string {
+1 -1
View File
@@ -43,7 +43,7 @@ func (self *SClassicWire) GetGlobalId() string {
}
func (self *SClassicWire) GetName() string {
return fmt.Sprintf("%s-%s-classic", self.zone.region.client.providerName, self.vpc.GetName())
return fmt.Sprintf("%s-%s-classic", self.zone.region.client.cpcfg.Name, self.vpc.GetName())
}
func (self *SClassicWire) IsEmulated() bool {
+1 -1
View File
@@ -40,7 +40,7 @@ func (self *SHost) GetMetadata() *jsonutils.JSONDict {
}
func (self *SHost) GetId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) GetName() string {
+7 -3
View File
@@ -111,9 +111,13 @@ func parseAccount(account, secret string) (tenantId string, appId string, appKey
return
}
func (self *SAzureProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
tenantId, appId, appKey, subId := parseAccount(account, secret)
if client, err := azure.NewAzureClient(providerId, providerName, url, tenantId, appId, appKey, subId, false); err != nil {
func (self *SAzureProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
tenantId, appId, appKey, subId := parseAccount(cfg.Account, cfg.Secret)
if client, err := azure.NewAzureClient(
azure.NewAzureClientConfig(
cfg.URL, tenantId, appId, appKey,
).SubscriptionId(subId).CloudproviderConfig(cfg),
); err != nil {
return nil, err
} else {
return &SAzureProvider{
+1 -1
View File
@@ -52,7 +52,7 @@ func (self *SStorage) GetId() string {
}
func (self *SStorage) GetName() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, strings.ToLower(self.storageType))
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, strings.ToLower(self.storageType))
}
func (self *SStorage) GetGlobalId() string {
+3 -3
View File
@@ -54,11 +54,11 @@ func (self *SStoragecache) GetMetadata() *jsonutils.JSONDict {
}
func (self *SStoragecache) GetId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetId())
}
func (self *SStoragecache) GetName() string {
return fmt.Sprintf("%s-%s", self.region.client.providerName, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Name, self.region.GetId())
}
func (self *SStoragecache) GetStatus() string {
@@ -70,7 +70,7 @@ func (self *SStoragecache) Refresh() error {
}
func (self *SStoragecache) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetGlobalId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetGlobalId())
}
func (self *SStoragecache) IsEmulated() bool {
+1 -1
View File
@@ -43,7 +43,7 @@ func (self *SWire) GetGlobalId() string {
}
func (self *SWire) GetName() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.vpc.GetName())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.vpc.GetName())
}
func (self *SWire) IsEmulated() bool {
+1 -1
View File
@@ -43,7 +43,7 @@ func (self *SZone) GetMetadata() *jsonutils.JSONDict {
}
func (self *SZone) GetId() string {
return self.region.client.providerId
return self.region.client.cpcfg.Id
}
func (self *SZone) GetName() string {
+44 -12
View File
@@ -44,21 +44,53 @@ const (
CTYUN_API_VERSION = "2019-11-22"
)
type SCtyunClient struct {
httpClient *http.Client
debug bool
type CtyunClientConfig struct {
cpcfg cloudprovider.ProviderConfig
providerId string
providerName string
projectId string // 项目ID.
projectId string
accessKey string
secret string
accessSecret string
iregions []cloudprovider.ICloudRegion
debug bool
}
func NewSCtyunClient(providerId string, providerName string, projectId string, accessKey string, secret string, debug bool) (*SCtyunClient, error) {
client := &SCtyunClient{httpClient: http.DefaultClient, providerId: providerId, providerName: providerName, projectId: projectId, accessKey: accessKey, secret: secret, debug: debug}
func NewSCtyunClientConfig(accessKey, accessSecret string) *CtyunClientConfig {
cfg := &CtyunClientConfig{
accessKey: accessKey,
accessSecret: accessSecret,
}
return cfg
}
func (cfg *CtyunClientConfig) ProjectId(projectId string) *CtyunClientConfig {
cfg.projectId = projectId
return cfg
}
func (cfg *CtyunClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *CtyunClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *CtyunClientConfig) Debug(debug bool) *CtyunClientConfig {
cfg.debug = debug
return cfg
}
type SCtyunClient struct {
*CtyunClientConfig
httpClient *http.Client
iregions []cloudprovider.ICloudRegion
}
func NewSCtyunClient(cfg *CtyunClientConfig) (*SCtyunClient, error) {
httpClient := httputils.GetDefaultClient()
httputils.SetClientProxyFunc(httpClient, cfg.cpcfg.ProxyFunc)
client := &SCtyunClient{
CtyunClientConfig: cfg,
httpClient: httpClient,
}
err := client.init()
if err != nil {
@@ -156,7 +188,7 @@ func formRequest(client *SCtyunClient, method httputils.THttpMethod, apiName str
// EEE, d MMM yyyy HH:mm:ss z
// Mon, 2 Jan 2006 15:04:05 MST
requestDate := time.Now().Format("Mon, 2 Jan 2006 15:04:05 MST")
hashMac := hmac.New(sha1.New, []byte(client.secret))
hashMac := hmac.New(sha1.New, []byte(client.accessSecret))
hashRawString := strings.Join([]string{contentMd5, requestDate, apiName}, "\n")
hashMac.Write([]byte(hashRawString))
hsum := base64.StdEncoding.EncodeToString(hashMac.Sum(nil))
@@ -242,7 +274,7 @@ func (self *SCtyunClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error)
iregion := self.iregions[i]
s := cloudprovider.SSubAccount{
Name: fmt.Sprintf("%s-%s", self.providerName, iregion.GetId()),
Name: fmt.Sprintf("%s-%s", self.cpcfg.Name, iregion.GetId()),
State: api.CLOUD_PROVIDER_CONNECTED,
Account: fmt.Sprintf("%s/%s", self.accessKey, iregion.GetId()),
HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
+2 -2
View File
@@ -35,11 +35,11 @@ type SHost struct {
}
func (self *SHost) GetId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) GetName() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId())
}
func (self *SHost) GetGlobalId() string {
+5 -1
View File
@@ -43,7 +43,11 @@ func (self *SProject) GetHealthStatus() string {
}
func (self *SCtyunClient) FetchProjects() ([]SProject, error) {
client, err := NewSCtyunClient("", "", "", self.accessKey, self.secret, self.debug)
client, err := NewSCtyunClient(
NewSCtyunClientConfig(
self.accessKey, self.accessSecret,
).Debug(self.debug),
)
if err != nil {
return nil, errors.Wrap(err, "CtyunClient.FetchProjects")
}
+8 -3
View File
@@ -76,15 +76,20 @@ func (self *SCtyunProviderFactory) ValidateUpdateCloudaccountCredential(ctx cont
return output, nil
}
func (self *SCtyunProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
segs := strings.Split(account, "/")
func (self *SCtyunProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
segs := strings.Split(cfg.Account, "/")
projectId := ""
account := cfg.Account
if len(segs) == 2 {
projectId = segs[1]
account = segs[0]
}
client, err := ctyun.NewSCtyunClient(providerId, providerName, projectId, account, secret, false)
client, err := ctyun.NewSCtyunClient(
ctyun.NewSCtyunClientConfig(
account, cfg.Secret,
).ProjectId(projectId).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+2 -2
View File
@@ -38,11 +38,11 @@ type SStorage struct {
}
func (self *SStorage) GetId() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetGlobalId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetGlobalId(), self.storageType)
}
func (self *SStorage) GetName() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerName, self.zone.GetId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId(), self.storageType)
}
func (self *SStorage) GetGlobalId() string {
+3 -3
View File
@@ -77,15 +77,15 @@ func (self *SStoragecache) fetchImages() error {
}
func (self *SStoragecache) GetId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetId())
}
func (self *SStoragecache) GetName() string {
return fmt.Sprintf("%s-%s", self.region.client.providerName, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Name, self.region.GetId())
}
func (self *SStoragecache) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetGlobalId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetGlobalId())
}
func (self *SStoragecache) GetStatus() string {
+72 -21
View File
@@ -26,8 +26,10 @@ import (
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/view"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"yunion.io/x/jsonutils"
@@ -39,6 +41,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/multicloud"
"yunion.io/x/onecloud/pkg/util/httputils"
)
const (
@@ -57,30 +60,60 @@ func init() {
defaultDc.ManagedEntity.ExtensibleManagedObject.Self.Value = defaultDcId
}
type ESXiClientConfig struct {
cpcfg cloudprovider.ProviderConfig
host string
port int
account string
password string
managed bool
}
func NewESXiClientConfig(host string, port int, account, password string) *ESXiClientConfig {
cfg := &ESXiClientConfig{
host: host,
port: port,
account: account,
password: password,
}
return cfg
}
func (cfg *ESXiClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *ESXiClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *ESXiClientConfig) Managed(managed bool) *ESXiClientConfig {
cfg.managed = managed
return cfg
}
type SESXiClient struct {
*ESXiClientConfig
cloudprovider.SFakeOnPremiseRegion
multicloud.SRegion
multicloud.SNoObjectStorageRegion
providerId string
providerName string
host string
port int
account string
password string
client *govmomi.Client
context context.Context
client *govmomi.Client
context context.Context
datacenters []*SDatacenter
}
func NewESXiClient(providerId string, providerName string, host string, port int, account string, passwd string) (*SESXiClient, error) {
return NewESXiClient2(providerId, providerName, host, port, account, passwd, true)
func NewESXiClient(cfg *ESXiClientConfig) (*SESXiClient, error) {
cfg.Managed(true)
return NewESXiClient2(cfg)
}
func NewESXiClient2(providerId string, providerName string, host string, port int, account string, passwd string, managed bool) (*SESXiClient, error) {
cli := &SESXiClient{providerId: providerId, providerName: providerName,
host: host, port: port, account: account, password: passwd, context: context.Background()}
func NewESXiClient2(cfg *ESXiClientConfig) (*SESXiClient, error) {
cli := &SESXiClient{
ESXiClientConfig: cfg,
context: context.Background(),
}
err := cli.connect()
if err != nil {
@@ -90,7 +123,7 @@ func NewESXiClient2(providerId string, providerName string, host string, port in
if !cli.IsVCenter() {
err := cli.checkHostManagedByVCenter()
if err != nil {
if managed {
if cfg.managed {
cli.disconnect()
return nil, err
} else {
@@ -118,7 +151,14 @@ func NewESXiClientFromAccessInfo(ctx context.Context, accessInfo *models.SVCente
accessInfo.Password = tmp
}
}
client, err := NewESXiClient("", "", accessInfo.Host, accessInfo.Port, accessInfo.Account, accessInfo.Password)
client, err := NewESXiClient(
NewESXiClientConfig(
accessInfo.Host,
accessInfo.Port,
accessInfo.Account,
accessInfo.Password,
).Managed(true),
)
if err != nil {
return nil, err
}
@@ -147,9 +187,20 @@ func (cli *SESXiClient) connect() error {
return fmt.Errorf("Illegal url %s: %s", cli.url(), err)
}
govmcli, err := govmomi.NewClient(cli.context, u, true)
if err != nil {
return err
var govmcli *govmomi.Client
{
insecure := true
soapCli := soap.NewClient(u, insecure)
httpClient := &soapCli.Client
httputils.SetClientProxyFunc(httpClient, cli.cpcfg.ProxyFunc)
vimCli, err := vim25.NewClient(cli.context, soapCli)
if err != nil {
return err
}
govmcli = &govmomi.Client{
Client: vimCli,
SessionManager: session.NewManager(vimCli),
}
}
userinfo := url.UserPassword(cli.account, cli.password)
@@ -180,7 +231,7 @@ func (cli *SESXiClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
}
subAccount := cloudprovider.SSubAccount{
Account: cli.account,
Name: cli.providerName,
Name: cli.cpcfg.Name,
HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
}
return []cloudprovider.SSubAccount{subAccount}, nil
@@ -382,8 +433,8 @@ func (cli *SESXiClient) FindHostByMoId(moId string) (cloudprovider.ICloudHost, e
}
func (cli *SESXiClient) getPrivateId(idStr string) string {
if len(cli.providerId) > 0 && strings.HasPrefix(idStr, cli.providerId) {
idStr = idStr[len(cli.providerId)+1:]
if len(cli.cpcfg.Id) > 0 && strings.HasPrefix(idStr, cli.cpcfg.Id) {
idStr = idStr[len(cli.cpcfg.Id)+1:]
}
return idStr
}
+7 -3
View File
@@ -101,8 +101,8 @@ func parseHostPort(host string, defPort int) (string, int, error) {
}
}
func (self *SESXiProviderFactory) GetProvider(providerId, providerName, urlStr, account, secret string) (cloudprovider.ICloudProvider, error) {
parts, err := url.Parse(urlStr)
func (self *SESXiProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
parts, err := url.Parse(cfg.URL)
if err != nil {
return nil, err
}
@@ -111,7 +111,11 @@ func (self *SESXiProviderFactory) GetProvider(providerId, providerName, urlStr,
return nil, err
}
client, err := esxi.NewESXiClient(providerId, providerName, host, port, account, secret)
client, err := esxi.NewESXiClient(
esxi.NewESXiClientConfig(
host, port, cfg.Account, cfg.Secret,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+65 -39
View File
@@ -61,13 +61,41 @@ const (
MAX_RETRY = 3
)
type GoogleClientConfig struct {
cpcfg cloudprovider.ProviderConfig
projectId string
clientEmail string
privateKeyId string
privateKey string
debug bool
}
func NewGoogleClientConfig(projectId, clientEmail, privateKeyId, privateKey string) *GoogleClientConfig {
privateKey = strings.Replace(privateKey, "\\n", "\n", -1)
cfg := &GoogleClientConfig{
projectId: projectId,
clientEmail: clientEmail,
privateKeyId: privateKeyId,
privateKey: privateKey,
}
return cfg
}
func (cfg *GoogleClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *GoogleClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *GoogleClientConfig) Debug(debug bool) *GoogleClientConfig {
cfg.debug = debug
return cfg
}
type SGoogleClient struct {
providerId string
providerName string
projectId string
privateKey string
privateKeyId string
clientEmail string
*GoogleClientConfig
iregions []cloudprovider.ICloudRegion
images []SImage
snapshots map[string][]SSnapshot
@@ -75,24 +103,16 @@ type SGoogleClient struct {
resourcepolices []SResourcePolicy
client *http.Client
Debug bool
}
func NewGoogleClient(providerId string, providerName string, projectId, clientEmail, privateKeyId, privateKey string, isDebug bool) (*SGoogleClient, error) {
func NewGoogleClient(cfg *GoogleClientConfig) (*SGoogleClient, error) {
client := SGoogleClient{
providerId: providerId,
providerName: providerName,
projectId: projectId,
privateKey: strings.Replace(privateKey, "\\n", "\n", -1),
privateKeyId: privateKeyId,
clientEmail: clientEmail,
Debug: isDebug,
GoogleClientConfig: cfg,
}
conf := &jwt.Config{
Email: clientEmail,
PrivateKeyID: privateKeyId,
PrivateKey: []byte(client.privateKey),
Email: cfg.clientEmail,
PrivateKeyID: cfg.privateKeyId,
PrivateKey: []byte(cfg.privateKey),
Scopes: []string{
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/compute",
@@ -106,7 +126,13 @@ func NewGoogleClient(providerId string, providerName string, projectId, clientEm
},
TokenURL: google.JWTTokenURL,
}
client.client = conf.Client(oauth2.NoContext)
httpClient := httputils.GetDefaultClient()
httputils.SetClientProxyFunc(httpClient, cfg.cpcfg.ProxyFunc)
ctx := context.Background()
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
client.client = conf.Client(ctx)
return &client, client.fetchRegions()
}
@@ -146,7 +172,7 @@ func jsonRequest(client *http.Client, method httputils.THttpMethod, domain, apiV
}
func (self *SGoogleClient) ecsGet(resource string, retval interface{}) error {
resp, err := jsonRequest(self.client, "GET", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, nil, nil, self.Debug)
resp, err := jsonRequest(self.client, "GET", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, nil, nil, self.debug)
if err != nil {
return err
}
@@ -161,15 +187,15 @@ func (self *SGoogleClient) ecsGet(resource string, retval interface{}) error {
func (self *SGoogleClient) ecsList(resource string, params map[string]string) (jsonutils.JSONObject, error) {
resource = fmt.Sprintf("projects/%s/%s", self.projectId, resource)
return jsonRequest(self.client, "GET", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, nil, self.Debug)
return jsonRequest(self.client, "GET", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, nil, self.debug)
}
func (self *SGoogleClient) managerList(resource string, params map[string]string) (jsonutils.JSONObject, error) {
return jsonRequest(self.client, "GET", GOOGLE_MANAGER_DOMAIN, GOOGLE_MANAGER_API_VERSION, resource, params, nil, self.Debug)
return jsonRequest(self.client, "GET", GOOGLE_MANAGER_DOMAIN, GOOGLE_MANAGER_API_VERSION, resource, params, nil, self.debug)
}
func (self *SGoogleClient) managerGet(resource string) (jsonutils.JSONObject, error) {
return jsonRequest(self.client, "GET", GOOGLE_MANAGER_DOMAIN, GOOGLE_MANAGER_API_VERSION, resource, nil, nil, self.Debug)
return jsonRequest(self.client, "GET", GOOGLE_MANAGER_DOMAIN, GOOGLE_MANAGER_API_VERSION, resource, nil, nil, self.debug)
}
func (self *SGoogleClient) ecsListAll(resource string, params map[string]string, retval interface{}) error {
@@ -201,7 +227,7 @@ func (self *SGoogleClient) ecsListAll(resource string, params map[string]string,
}
func (self *SGoogleClient) ecsDelete(id string, retval interface{}) error {
resp, err := jsonRequest(self.client, "DELETE", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, id, nil, nil, self.Debug)
resp, err := jsonRequest(self.client, "DELETE", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, id, nil, nil, self.debug)
if err != nil {
return err
}
@@ -215,7 +241,7 @@ func (self *SGoogleClient) ecsPatch(resource string, action string, params map[s
if len(action) > 0 {
resource = fmt.Sprintf("%s/%s", resource, action)
}
resp, err := jsonRequest(self.client, "PATCH", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, body, self.Debug)
resp, err := jsonRequest(self.client, "PATCH", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, body, self.debug)
if err != nil {
return "", err
}
@@ -225,7 +251,7 @@ func (self *SGoogleClient) ecsPatch(resource string, action string, params map[s
func (self *SGoogleClient) ecsDo(resource string, action string, params map[string]string, body jsonutils.JSONObject) (string, error) {
resource = fmt.Sprintf("%s/%s", resource, action)
resp, err := jsonRequest(self.client, "POST", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, body, self.Debug)
resp, err := jsonRequest(self.client, "POST", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, params, body, self.debug)
if err != nil {
return "", err
}
@@ -251,7 +277,7 @@ func (self *SGoogleClient) ecsInsert(resource string, body jsonutils.JSONObject,
}
}
}
resp, err := jsonRequest(self.client, "POST", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, nil, body, self.Debug)
resp, err := jsonRequest(self.client, "POST", GOOGLE_COMPUTE_DOMAIN, GOOGLE_API_VERSION, resource, nil, body, self.debug)
if err != nil {
return err
}
@@ -262,7 +288,7 @@ func (self *SGoogleClient) ecsInsert(resource string, body jsonutils.JSONObject,
}
func (self *SGoogleClient) storageInsert(resource string, body jsonutils.JSONObject, retval interface{}) error {
resp, err := jsonRequest(self.client, "POST", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, nil, body, self.Debug)
resp, err := jsonRequest(self.client, "POST", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, nil, body, self.debug)
if err != nil {
return err
}
@@ -273,11 +299,11 @@ func (self *SGoogleClient) storageInsert(resource string, body jsonutils.JSONObj
}
func (self *SGoogleClient) storageUpload(resource string, header http.Header, body io.Reader) error {
return rawRequest(self.client, "POST", GOOGLE_STORAGE_UPLOAD_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, header, body, self.Debug)
return rawRequest(self.client, "POST", GOOGLE_STORAGE_UPLOAD_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, header, body, self.debug)
}
func (self *SGoogleClient) storageList(resource string, params map[string]string) (jsonutils.JSONObject, error) {
return jsonRequest(self.client, "GET", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, params, nil, self.Debug)
return jsonRequest(self.client, "GET", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, params, nil, self.debug)
}
func (self *SGoogleClient) storageListAll(resource string, params map[string]string, retval interface{}) error {
@@ -309,7 +335,7 @@ func (self *SGoogleClient) storageListAll(resource string, params map[string]str
}
func (self *SGoogleClient) storageGet(resource string, retval interface{}) error {
resp, err := jsonRequest(self.client, "GET", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, nil, nil, self.Debug)
resp, err := jsonRequest(self.client, "GET", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, nil, nil, self.debug)
if err != nil {
return err
}
@@ -323,7 +349,7 @@ func (self *SGoogleClient) storageGet(resource string, retval interface{}) error
}
func (self *SGoogleClient) storageDelete(id string, retval interface{}) error {
resp, err := jsonRequest(self.client, "DELETE", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, id, nil, nil, self.Debug)
resp, err := jsonRequest(self.client, "DELETE", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, id, nil, nil, self.debug)
if err != nil {
return err
}
@@ -335,7 +361,7 @@ func (self *SGoogleClient) storageDelete(id string, retval interface{}) error {
func (self *SGoogleClient) storageDo(resource string, action string, params map[string]string, body jsonutils.JSONObject) (string, error) {
resource = fmt.Sprintf("%s/%s", resource, action)
resp, err := jsonRequest(self.client, "POST", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, params, body, self.Debug)
resp, err := jsonRequest(self.client, "POST", GOOGLE_STORAGE_DOMAIN, GOOGLE_STORAGE_API_VERSION, resource, params, body, self.debug)
if err != nil {
return "", err
}
@@ -344,7 +370,7 @@ func (self *SGoogleClient) storageDo(resource string, action string, params map[
}
func (self *SGoogleClient) cloudbuildGet(resource string, retval interface{}) error {
resp, err := jsonRequest(self.client, "GET", GOOGLE_CLOUDBUILD_DOMAIN, GOOGLE_CLOUDBUILD_API_VERSION, resource, nil, nil, self.Debug)
resp, err := jsonRequest(self.client, "GET", GOOGLE_CLOUDBUILD_DOMAIN, GOOGLE_CLOUDBUILD_API_VERSION, resource, nil, nil, self.debug)
if err != nil {
return err
}
@@ -358,7 +384,7 @@ func (self *SGoogleClient) cloudbuildGet(resource string, retval interface{}) er
}
func (self *SGoogleClient) cloudbuildInsert(resource string, body jsonutils.JSONObject, retval interface{}) error {
resp, err := jsonRequest(self.client, "POST", GOOGLE_CLOUDBUILD_DOMAIN, GOOGLE_CLOUDBUILD_API_VERSION, resource, nil, body, self.Debug)
resp, err := jsonRequest(self.client, "POST", GOOGLE_CLOUDBUILD_DOMAIN, GOOGLE_CLOUDBUILD_API_VERSION, resource, nil, body, self.debug)
if err != nil {
return err
}
@@ -369,7 +395,7 @@ func (self *SGoogleClient) cloudbuildInsert(resource string, body jsonutils.JSON
}
func (self *SGoogleClient) billingList(resource string, params map[string]string) (jsonutils.JSONObject, error) {
return jsonRequest(self.client, "GET", GOOGLE_BILLING_DOMAIN, GOOGLE_BILLING_API_VERSION, resource, params, nil, self.Debug)
return jsonRequest(self.client, "GET", GOOGLE_BILLING_DOMAIN, GOOGLE_BILLING_API_VERSION, resource, params, nil, self.debug)
}
func (self *SGoogleClient) billingListAll(resource string, params map[string]string, retval interface{}) error {
@@ -401,7 +427,7 @@ func (self *SGoogleClient) billingListAll(resource string, params map[string]str
}
func (self *SGoogleClient) monitorList(resource string, params map[string]string) (jsonutils.JSONObject, error) {
return jsonRequest(self.client, "GET", GOOGLE_MONITOR_DOMAIN, GOOGLE_MONITOR_API_VERSION, resource, params, nil, self.Debug)
return jsonRequest(self.client, "GET", GOOGLE_MONITOR_DOMAIN, GOOGLE_MONITOR_API_VERSION, resource, params, nil, self.debug)
}
func (self *SGoogleClient) monitorListAll(resource string, params map[string]string, retval interface{}) error {
@@ -500,7 +526,7 @@ func (client *SGoogleClient) GetSubAccounts() ([]cloudprovider.SSubAccount, erro
accounts := []cloudprovider.SSubAccount{}
for _, project := range projects {
subAccount := cloudprovider.SSubAccount{}
subAccount.Name = client.providerName
subAccount.Name = client.cpcfg.Name
subAccount.Account = fmt.Sprintf("%s/%s", project.ProjectId, client.clientEmail)
if project.LifecycleState == "ACTIVE" {
subAccount.HealthStatus = api.CLOUD_PROVIDER_HEALTH_NORMAL
+1 -1
View File
@@ -44,7 +44,7 @@ func (host *SHost) GetGlobalId() string {
}
func (host *SHost) GetName() string {
return fmt.Sprintf("%s-%s", host.zone.region.client.providerName, host.zone.GetName())
return fmt.Sprintf("%s-%s", host.zone.region.client.cpcfg.Name, host.zone.GetName())
}
func (host *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
+10 -5
View File
@@ -101,21 +101,26 @@ func (self *SGoogleProviderFactory) ValidateUpdateCloudaccountCredential(ctx con
return output, nil
}
func (self *SGoogleProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
func (self *SGoogleProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
privateKeyID, privateKey := "", ""
privateKeyInfo := strings.Split(secret, "/")
privateKeyInfo := strings.Split(cfg.Secret, "/")
if len(privateKeyInfo) < 2 {
return nil, fmt.Errorf("Missing privateKeyID or privateKey for google cloud")
}
privateKeyID = privateKeyInfo[0]
privateKey = strings.Join(privateKeyInfo[1:], "/")
projectID, clientEmail := "", ""
accountInfo := strings.Split(account, "/")
accountInfo := strings.Split(cfg.Account, "/")
if len(accountInfo) < 2 {
return nil, fmt.Errorf("Invalid projectID or client email for google cloud %s", account)
return nil, fmt.Errorf("Invalid projectID or client email for google cloud %s", cfg.Account)
}
projectID, clientEmail = accountInfo[0], accountInfo[1]
client, err := google.NewGoogleClient(providerId, providerName, projectID, clientEmail, privateKeyID, privateKey, false)
client, err := google.NewGoogleClient(
google.NewGoogleClientConfig(
projectID, clientEmail, privateKeyID, privateKey,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+3 -3
View File
@@ -45,11 +45,11 @@ func (cache *SStoragecache) GetMetadata() *jsonutils.JSONDict {
}
func (cache *SStoragecache) GetId() string {
return cache.region.client.providerId
return cache.region.client.cpcfg.Id
}
func (cache *SStoragecache) GetName() string {
return cache.region.client.providerName
return cache.region.client.cpcfg.Name
}
func (cache *SStoragecache) GetStatus() string {
@@ -61,7 +61,7 @@ func (cache *SStoragecache) Refresh() error {
}
func (cache *SStoragecache) GetGlobalId() string {
return cache.region.client.providerId
return cache.region.client.cpcfg.Id
}
func (cache *SStoragecache) IsEmulated() bool {
+51 -8
View File
@@ -15,6 +15,8 @@
package client
import (
"net/http"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth/credentials"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/modules"
@@ -81,9 +83,55 @@ type Client struct {
CloudEye *modules.SCloudEyeManager
}
func (self *Client) Init() error {
// 从环境变量中初始化client
return nil
func (self *Client) SetHttpClient(httpClient *http.Client) {
self.Servers.SetHttpClient(httpClient)
self.ServersV2.SetHttpClient(httpClient)
self.NovaServers.SetHttpClient(httpClient)
self.Snapshots.SetHttpClient(httpClient)
self.OsSnapshots.SetHttpClient(httpClient)
self.Images.SetHttpClient(httpClient)
self.OpenStackImages.SetHttpClient(httpClient)
self.Projects.SetHttpClient(httpClient)
self.Regions.SetHttpClient(httpClient)
self.Zones.SetHttpClient(httpClient)
self.Vpcs.SetHttpClient(httpClient)
self.Eips.SetHttpClient(httpClient)
self.Elasticcache.SetHttpClient(httpClient)
self.DcsAvailableZone.SetHttpClient(httpClient)
self.Disks.SetHttpClient(httpClient)
self.Domains.SetHttpClient(httpClient)
self.Keypairs.SetHttpClient(httpClient)
self.Elb.SetHttpClient(httpClient)
self.ElbBackend.SetHttpClient(httpClient)
self.ElbBackendGroup.SetHttpClient(httpClient)
self.ElbListeners.SetHttpClient(httpClient)
self.ElbCertificates.SetHttpClient(httpClient)
self.ElbHealthCheck.SetHttpClient(httpClient)
self.ElbL7policies.SetHttpClient(httpClient)
self.ElbPolicies.SetHttpClient(httpClient)
self.ElbWhitelist.SetHttpClient(httpClient)
self.Orders.SetHttpClient(httpClient)
self.SecurityGroupRules.SetHttpClient(httpClient)
self.SecurityGroups.SetHttpClient(httpClient)
self.NovaSecurityGroups.SetHttpClient(httpClient)
self.Subnets.SetHttpClient(httpClient)
self.Users.SetHttpClient(httpClient)
self.Interface.SetHttpClient(httpClient)
self.Jobs.SetHttpClient(httpClient)
self.Balances.SetHttpClient(httpClient)
self.Bandwidths.SetHttpClient(httpClient)
self.Port.SetHttpClient(httpClient)
self.Flavors.SetHttpClient(httpClient)
self.VpcRoutes.SetHttpClient(httpClient)
self.SNatRules.SetHttpClient(httpClient)
self.DNatRules.SetHttpClient(httpClient)
self.NatGateways.SetHttpClient(httpClient)
self.DBInstance.SetHttpClient(httpClient)
self.DBInstanceBackup.SetHttpClient(httpClient)
self.DBInstanceFlavor.SetHttpClient(httpClient)
self.DBInstanceJob.SetHttpClient(httpClient)
self.Traces.SetHttpClient(httpClient)
self.CloudEye.SetHttpClient(httpClient)
}
func (self *Client) InitWithOptions(regionId, projectId string, credential auth.Credential) error {
@@ -167,11 +215,6 @@ func (self *Client) initManagers() {
self.init = true
}
// todo: init from envrioment
func NewClient() (*Client, error) {
return nil, nil
}
func NewClientWithAccessKey(regionId, projectId, accessKey, secretKey string, debug bool) (*Client, error) {
c := &Client{debug: debug}
err := c.InitWithAccessKey(regionId, projectId, accessKey, secretKey)
@@ -62,6 +62,10 @@ func (self *SBaseManager) GetColumns() []string {
return self.columns
}
func (self *SBaseManager) SetHttpClient(httpClient *http.Client) {
self.httpClient = httpClient
}
func (self *SBaseManager) _list(request requests.IRequest, responseKey string) (*responses.ListResult, error) {
_, body, err := self.jsonRequest(request)
if err != nil {
+1 -3
View File
@@ -14,8 +14,6 @@
package huawei
import "yunion.io/x/onecloud/pkg/multicloud/huawei/client"
// https://support.huaweicloud.com/api-iam/zh-cn_topic_0057845574.html
// 租户列表
type SDomain struct {
@@ -29,7 +27,7 @@ type SDomain struct {
}
func (self *SHuaweiClient) GetDomains() ([]SDomain, error) {
huawei, _ := client.NewClientWithAccessKey("", "", self.accessKey, self.secret, self.debug)
huawei, _ := self.newGeneralAPIClient()
domains := make([]SDomain, 0)
err := doListAll(huawei.Domains.List, nil, &domains)
return domains, err
+3 -3
View File
@@ -37,15 +37,15 @@ type SHost struct {
}
func (self *SHost) GetId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) GetName() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerName, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId())
}
func (self *SHost) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.zone.region.client.providerId, self.zone.GetId())
return fmt.Sprintf("%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId())
}
func (self *SHost) GetStatus() string {
+66 -21
View File
@@ -27,6 +27,7 @@ import (
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth/credentials"
"yunion.io/x/onecloud/pkg/multicloud/huawei/obs"
"yunion.io/x/onecloud/pkg/util/httputils"
)
/*
@@ -48,17 +49,41 @@ const (
HUAWEI_API_VERSION = "2018-12-25"
)
type SHuaweiClient struct {
signer auth.Signer
type HuaweiClientConfig struct {
cpcfg cloudprovider.ProviderConfig
debug bool
providerId string
providerName string
projectId string // 华为云项目ID.
cloudEnv string // 服务区域 ChinaCloud | InternationalCloud
accessKey string
secret string
accessSecret string
debug bool
}
func NewHuaweiClientConfig(cloudEnv, accessKey, accessSecret, projectId string) *HuaweiClientConfig {
cfg := &HuaweiClientConfig{
projectId: projectId,
cloudEnv: cloudEnv,
accessKey: accessKey,
accessSecret: accessSecret,
}
return cfg
}
func (cfg *HuaweiClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *HuaweiClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *HuaweiClientConfig) Debug(debug bool) *HuaweiClientConfig {
cfg.debug = debug
return cfg
}
type SHuaweiClient struct {
*HuaweiClientConfig
signer auth.Signer
isMainProject bool // whether the project is the main project in the region
@@ -73,15 +98,9 @@ type SHuaweiClient struct {
// 初次导入Subaccount时,参数account对应cloudaccounts表中的account字段,即accesskey。此时projectID为空,
// 只能进行同步子账号、查询region列表等projectId无关的操作。
// todo: 通过accessurl支持国际站。目前暂时未支持国际站
func NewHuaweiClient(providerId, providerName, cloudEnv, accessKey, secret, projectId string, debug bool) (*SHuaweiClient, error) {
func NewHuaweiClient(cfg *HuaweiClientConfig) (*SHuaweiClient, error) {
client := SHuaweiClient{
providerId: providerId,
providerName: providerName,
projectId: projectId,
cloudEnv: cloudEnv,
accessKey: accessKey,
secret: secret,
debug: debug,
HuaweiClientConfig: cfg,
}
err := client.init()
if err != nil {
@@ -119,8 +138,34 @@ func (self *SHuaweiClient) initSigner() error {
return nil
}
func (self *SHuaweiClient) newRegionAPIClient(regionId string) (*client.Client, error) {
cli, err := client.NewClientWithAccessKey(regionId, self.projectId, self.accessKey, self.accessSecret, self.debug)
if err != nil {
return nil, err
}
httpClient := httputils.GetDefaultClient()
httputils.SetClientProxyFunc(httpClient, self.cpcfg.ProxyFunc)
cli.SetHttpClient(httpClient)
return cli, nil
}
func (self *SHuaweiClient) newGeneralAPIClient() (*client.Client, error) {
cli, err := client.NewClientWithAccessKey("", "", self.accessKey, self.accessSecret, self.debug)
if err != nil {
return nil, err
}
httpClient := httputils.GetDefaultClient()
httputils.SetClientProxyFunc(httpClient, self.cpcfg.ProxyFunc)
cli.SetHttpClient(httpClient)
return cli, nil
}
func (self *SHuaweiClient) fetchRegions() error {
huawei, _ := client.NewClientWithAccessKey("", "", self.accessKey, self.secret, self.debug)
huawei, _ := self.newGeneralAPIClient()
regions := make([]SRegion, 0)
err := doListAll(huawei.Regions.List, nil, &regions)
if err != nil {
@@ -179,7 +224,7 @@ func getOBSEndpoint(regionId string) string {
func (client *SHuaweiClient) getOBSClient(regionId string) (*obs.ObsClient, error) {
endpoint := getOBSEndpoint(regionId)
return obs.New(client.accessKey, client.secret, endpoint)
return obs.New(client.accessKey, client.accessSecret, endpoint)
}
func (self *SHuaweiClient) fetchBuckets() error {
@@ -225,9 +270,9 @@ func (self *SHuaweiClient) GetCloudRegionExternalIdPrefix() string {
}
func (self *SHuaweiClient) UpdateAccount(accessKey, secret string) error {
if self.accessKey != accessKey || self.secret != secret {
if self.accessKey != accessKey || self.accessSecret != secret {
self.accessKey = accessKey
self.secret = secret
self.accessSecret = secret
return self.fetchRegions()
} else {
return nil
@@ -258,7 +303,7 @@ func (self *SHuaweiClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error)
continue
}
s := cloudprovider.SSubAccount{
Name: fmt.Sprintf("%s-%s", self.providerName, project.Name),
Name: fmt.Sprintf("%s-%s", self.cpcfg.Name, project.Name),
State: api.CLOUD_PROVIDER_CONNECTED,
Account: fmt.Sprintf("%s/%s", self.accessKey, project.ID),
HealthStatus: project.GetHealthStatus(),
@@ -384,7 +429,7 @@ func (self *SHuaweiClient) QueryAccountBalance() (*SAccountBalance, error) {
// https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0075213309.html
func (self *SHuaweiClient) queryDomainBalance(domainId string) (float64, error) {
huawei, _ := client.NewClientWithAccessKey("", "", self.accessKey, self.secret, self.debug)
huawei, _ := self.newGeneralAPIClient()
huawei.Balances.SetDomainId(domainId)
balances := make([]SBalance, 0)
err := doListAll(huawei.Balances.List, nil, &balances)
+1 -2
View File
@@ -20,7 +20,6 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client"
)
// https://support.huaweicloud.com/api-iam/zh-cn_topic_0057845625.html
@@ -49,7 +48,7 @@ func (self *SProject) GetHealthStatus() string {
}
func (self *SHuaweiClient) fetchProjects() ([]SProject, error) {
huawei, _ := client.NewClientWithAccessKey("", "", self.accessKey, self.secret, self.debug)
huawei, _ := self.newGeneralAPIClient()
projects := make([]SProject, 0)
err := doListAll(huawei.Projects.List, nil, &projects)
return projects, err
+7 -3
View File
@@ -99,9 +99,13 @@ func parseAccount(account string) (accessKey string, projectId string) {
return
}
func (self *SHuaweiProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
accessKey, projectId := parseAccount(account)
client, err := huawei.NewHuaweiClient(providerId, providerName, url, accessKey, secret, projectId, false)
func (self *SHuaweiProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
accessKey, projectId := parseAccount(cfg.Account)
client, err := huawei.NewHuaweiClient(
huawei.NewHuaweiClientConfig(
cfg.URL, accessKey, cfg.Secret, projectId,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -82,7 +82,7 @@ func (self *SRegion) getECSClient() (*client.Client, error) {
}
if self.ecsClient == nil {
self.ecsClient, err = client.NewClientWithAccessKey(self.ID, self.client.projectId, self.client.accessKey, self.client.secret, self.client.debug)
self.ecsClient, err = self.client.newRegionAPIClient(self.ID)
if err != nil {
return nil, err
}
+3 -3
View File
@@ -31,15 +31,15 @@ type SStorage struct {
}
func (self *SStorage) GetId() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetId(), self.storageType)
}
func (self *SStorage) GetName() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerName, self.zone.GetId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Name, self.zone.GetId(), self.storageType)
}
func (self *SStorage) GetGlobalId() string {
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetGlobalId(), self.storageType)
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.cpcfg.Id, self.zone.GetGlobalId(), self.storageType)
}
func (self *SStorage) GetStatus() string {
+3 -3
View File
@@ -68,15 +68,15 @@ func (self *SStoragecache) fetchImages() error {
}
func (self *SStoragecache) GetId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetId())
}
func (self *SStoragecache) GetName() string {
return fmt.Sprintf("%s-%s", self.region.client.providerName, self.region.GetId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Name, self.region.GetId())
}
func (self *SStoragecache) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.region.client.providerId, self.region.GetGlobalId())
return fmt.Sprintf("%s-%s", self.region.client.cpcfg.Id, self.region.GetGlobalId())
}
func (self *SStoragecache) GetStatus() string {
+114
View File
@@ -0,0 +1,114 @@
package loader
import (
"net/http"
"net/url"
"testing"
"yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
func TestProxyFunc(t *testing.T) {
runT := func(t *testing.T, cpcfg *cloudprovider.ProviderConfig) {
vendor := cpcfg.Vendor
proxied := false
proxyFunc := func(req *http.Request) (*url.URL, error) {
proxied = true
return url.Parse("http://TestProxyFunc" + "." + vendor + "/")
}
cpcfg.ProxyFunc = proxyFunc
_, err := cloudprovider.GetProvider(*cpcfg)
if !proxied {
if err != nil {
t.Logf("vendor %s: err: %v", vendor, err)
}
t.Errorf("vendor %s: proxyFunc not working", vendor)
}
}
t.Parallel()
t.Run("cloud", func(t *testing.T) {
cpcfgs := map[string]*cloudprovider.ProviderConfig{
compute.CLOUD_PROVIDER_VMWARE: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_QCLOUD: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_AZURE: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_HUAWEI: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_OPENSTACK: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_ZSTACK: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_UCLOUD: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_ALIYUN: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_AWS: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_CTYUN: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_GOOGLE: &cloudprovider.ProviderConfig{},
}
for vendor := range cpcfgs {
cpcfgs[vendor].Vendor = vendor
cpcfgs[vendor].Id = vendor + "-Id"
cpcfgs[vendor].Name = vendor + "-Name"
cpcfgs[vendor].URL = "http://" + vendor + ".AccessUrl/TestProxyFunc"
cpcfgs[vendor].Account = vendor + "-Account"
cpcfgs[vendor].Secret = vendor + "-Secret"
}
if true {
cpcfgs[compute.CLOUD_PROVIDER_OPENSTACK].Account = "projectId/username/domainName"
}
if true {
cpcfgs[compute.CLOUD_PROVIDER_AZURE].URL = "AzureChinaCloud"
cpcfgs[compute.CLOUD_PROVIDER_AZURE].Account = "tenantId/subscriptionId"
cpcfgs[compute.CLOUD_PROVIDER_AZURE].Secret = "appId/appKey"
}
if true {
cpcfgs[compute.CLOUD_PROVIDER_UCLOUD].Account = "accessKey::projectId"
}
if true {
const pkey = `-----BEGIN RSA PRIVATE KEY-----` + "\n" +
`MIICXgIBAAKBgQDIUZ819CKNzPf3dL1aTC9tx6Y+Z/wQ74hWgyxM4DM5kxMZDoWd` + "\n" +
`2zzj7B8vUU64tYaeCaPFahxcMNs705wNACkFnmqop08zUSWTfbPg/uNdhGvuF0vT` + "\n" +
`3o5oNbUfVLrusvVJwP6mAnfJsECZJsPMqVIyM5z6uMBpAkjsaqEP7cOISwIDAQAB` + "\n" +
`AoGBAIzBXZ/ptcXxumM0skCau9DlspizNFkqFqDDdwNlnljcUVUP8S9kd7qnlZoI` + "\n" +
`BcqgMsElgOAcmWTmJ4Y4QLSZ4jgDthDUqt+dv384G4tUHv5LDU4SMnKiPFzqzsOn` + "\n" +
`PR72ZcoZZZW9PvNMmJDWSIwuEXgWovXhK5pO3wuuHUDjPHlxAkEA8DdcBRAV9yuq` + "\n" +
`AbVFSWxBIpNkXkIoOCQiBOP8LBTvua5Dkuxe5qZkDXuTupYmLRmIoDJuZVKo0jWw` + "\n" +
`6xBg1Io4BQJBANV7J3u5HV7IxlG35g8iCsU/AnLYQYWIWqF9+DKM8fqkDHGx6KGl` + "\n" +
`THG0gKGjhkWe/qzTsQbe4gHWZp6z1apVQA8CQQC9aDkzeMKJGTG8lQzj3urg82zx` + "\n" +
`caK62arFRmrA62U2eHSptZ0CqvI7O1R5jAjgCMEU547qb6nTzigIwOpIzA9tAkB6` + "\n" +
`EyaM1Vo6LU1axXJFDQ5jpJhd29P76/EHj+Ux4u8siEqlaTrB1KhWDQXRaJULktPH` + "\n" +
`OHZum11Z96RO9D8mXAF5AkEAq1xtCrJp8rWTGH5PGShyCOk2ZNbV0AL+may4FAgc` + "\n" +
`hbZ+WzxylVxMKJmWqEBAYF3/7oouyteF8Vq3TVOv442NSg==` + "\n" +
`-----END RSA PRIVATE KEY-----`
cpcfgs[compute.CLOUD_PROVIDER_GOOGLE].Account = "projectId/email"
cpcfgs[compute.CLOUD_PROVIDER_GOOGLE].Secret = "keyid/" + pkey
}
for _, cpcfg := range cpcfgs {
cpcfg := cpcfg
t.Run(cpcfg.Vendor, func(t *testing.T) {
//t.Parallel()
runT(t, cpcfg)
})
}
})
t.Run("objectstore", func(t *testing.T) {
cpcfgs := map[string]*cloudprovider.ProviderConfig{
compute.CLOUD_PROVIDER_CEPH: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_XSKY: &cloudprovider.ProviderConfig{},
compute.CLOUD_PROVIDER_GENERICS3: &cloudprovider.ProviderConfig{},
}
for vendor := range cpcfgs {
cpcfgs[vendor].Vendor = vendor
cpcfgs[vendor].Id = vendor + "-Id"
cpcfgs[vendor].Name = vendor + "-Name"
cpcfgs[vendor].URL = "http://" + vendor + ".AccessUrl/TestProxyFunc"
cpcfgs[vendor].Account = vendor + "-Account"
cpcfgs[vendor].Secret = vendor + "-Secret"
}
for _, cpcfg := range cpcfgs {
cpcfg := cpcfg
t.Run(cpcfg.Vendor, func(t *testing.T) {
//t.Parallel()
runT(t, cpcfg)
})
}
})
}
@@ -63,6 +63,10 @@ func getJsonBodyReader(body jsonutils.JSONObject) io.Reader {
return reqBody
}
func (api *SCephAdminApi) httpClient() *http.Client {
return api.client
}
func (api *SCephAdminApi) jsonRequest(ctx context.Context, method httputils.THttpMethod, path string, hdr http.Header, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
urlStr := strings.TrimRight(api.endpoint, "/") + "/" + strings.TrimLeft(path, "/")
req, err := http.NewRequest(string(method), urlStr, getJsonBodyReader(body))
+12 -4
View File
@@ -26,6 +26,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/multicloud/objectstore"
"yunion.io/x/onecloud/pkg/util/httputils"
)
type SCephRadosClient struct {
@@ -38,12 +39,19 @@ type SCephRadosClient struct {
userInfo *SUserInfo
}
func NewCephRados(providerId string, providerName string, endpoint string, accessKey string, secret string, isDebug bool) (*SCephRadosClient, error) {
s3store, err := objectstore.NewObjectStoreClientAndFetch(providerId, providerName, endpoint, accessKey, secret, isDebug, false)
func NewCephRados(cfg *objectstore.ObjectStoreClientConfig) (*SCephRadosClient, error) {
s3store, err := objectstore.NewObjectStoreClientAndFetch(cfg, false)
if err != nil {
return nil, errors.Wrap(err, "NewObjectStoreClient")
}
adminApi := newCephAdminApi(accessKey, secret, endpoint, isDebug, "")
adminApi := newCephAdminApi(
cfg.GetAccessKey(),
cfg.GetAccessSecret(),
cfg.GetEndpoint(),
cfg.GetDebug(),
"",
)
httputils.SetClientProxyFunc(adminApi.httpClient(), cfg.GetCloudproviderConfig().ProxyFunc)
client := SCephRadosClient{
SObjectStoreClient: s3store,
@@ -75,7 +83,7 @@ func NewCephRados(providerId string, providerName string, endpoint string, acces
log.Errorf("adminApi.GetUserInfo fail: %s", err)
}
}
if isDebug {
if cfg.GetDebug() {
log.Debugf("%#v %#v %#v", userQuota, bucketQuota, userInfo)
}
client.userQuota = userQuota
@@ -17,6 +17,7 @@ package provider
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/objectstore"
"yunion.io/x/onecloud/pkg/multicloud/objectstore/ceph"
s3provider "yunion.io/x/onecloud/pkg/multicloud/objectstore/provider"
)
@@ -33,8 +34,12 @@ func (self *SCephRadosProviderFactory) GetName() string {
return api.CLOUD_PROVIDER_CEPH
}
func (self *SCephRadosProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
client, err := ceph.NewCephRados(providerId, providerName, url, account, secret, false)
func (self *SCephRadosProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
client, err := ceph.NewCephRados(
objectstore.NewObjectStoreClientConfig(
cfg.URL, cfg.Account, cfg.Secret,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+67 -22
View File
@@ -31,42 +31,80 @@ import (
"yunion.io/x/onecloud/pkg/util/httputils"
)
type ObjectStoreClientConfig struct {
cpcfg cloudprovider.ProviderConfig
endpoint string
accessKey string
accessSecret string
debug bool
}
func NewObjectStoreClientConfig(endpoint, accessKey, accessSecret string) *ObjectStoreClientConfig {
cfg := &ObjectStoreClientConfig{
endpoint: endpoint,
accessKey: accessKey,
accessSecret: accessSecret,
}
return cfg
}
func (cfg *ObjectStoreClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *ObjectStoreClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *ObjectStoreClientConfig) Debug(debug bool) *ObjectStoreClientConfig {
cfg.debug = debug
return cfg
}
func (cfg *ObjectStoreClientConfig) GetCloudproviderConfig() cloudprovider.ProviderConfig {
return cfg.cpcfg
}
func (cfg *ObjectStoreClientConfig) GetEndpoint() string {
return cfg.endpoint
}
func (cfg *ObjectStoreClientConfig) GetAccessKey() string {
return cfg.accessKey
}
func (cfg *ObjectStoreClientConfig) GetAccessSecret() string {
return cfg.accessSecret
}
func (cfg *ObjectStoreClientConfig) GetDebug() bool {
return cfg.debug
}
type SObjectStoreClient struct {
object.SObject
*ObjectStoreClientConfig
cloudprovider.SFakeOnPremiseRegion
multicloud.SRegion
providerId string
providerName string
endpoint string
accessKey string
secret string
ownerId string
ownerName string
iBuckets []cloudprovider.ICloudBucket
client *s3cli.Client
Debug bool
}
func NewObjectStoreClient(providerId string, providerName string, endpoint string, accessKey string, secret string, isDebug bool) (*SObjectStoreClient, error) {
return NewObjectStoreClientAndFetch(providerId, providerName, endpoint, accessKey, secret, isDebug, true)
func NewObjectStoreClient(cfg *ObjectStoreClientConfig) (*SObjectStoreClient, error) {
return NewObjectStoreClientAndFetch(cfg, true)
}
func NewObjectStoreClientAndFetch(providerId string, providerName string, endpoint string, accessKey string, secret string, isDebug bool, doFetch bool) (*SObjectStoreClient, error) {
func NewObjectStoreClientAndFetch(cfg *ObjectStoreClientConfig, doFetch bool) (*SObjectStoreClient, error) {
client := SObjectStoreClient{
providerId: providerId,
providerName: providerName,
endpoint: endpoint,
accessKey: accessKey,
secret: secret,
Debug: isDebug,
ObjectStoreClientConfig: cfg,
}
parts, err := url.Parse(endpoint)
parts, err := url.Parse(cfg.endpoint)
if err != nil {
return nil, errors.Wrap(err, "url.Parse endpoint")
}
@@ -74,18 +112,25 @@ func NewObjectStoreClientAndFetch(providerId string, providerName string, endpoi
if parts.Scheme == "https" {
useSsl = true
}
cli, err := s3cli.New(parts.Host, accessKey, secret, useSsl, client.Debug)
cli, err := s3cli.New(
parts.Host,
client.accessKey,
client.accessSecret,
useSsl,
client.debug,
)
if err != nil {
return nil, errors.Wrap(err, "minio.New")
}
tr := httputils.GetTransport(true)
tr.Proxy = cfg.cpcfg.ProxyFunc
cli.SetCustomTransport(tr)
client.client = cli
client.SetVirtualObject(&client)
if isDebug {
if client.debug {
cli.TraceOn(os.Stderr)
}
@@ -102,7 +147,7 @@ func NewObjectStoreClientAndFetch(providerId string, providerName string, endpoi
func (cli *SObjectStoreClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
subAccount := cloudprovider.SSubAccount{
Account: cli.accessKey,
Name: cli.providerName,
Name: cli.cpcfg.Name,
HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
}
return []cloudprovider.SSubAccount{subAccount}, nil
@@ -158,7 +203,7 @@ func (cli *SObjectStoreClient) S3Client() *s3cli.Client {
func (cli *SObjectStoreClient) GetClientRC() map[string]string {
return map[string]string{
"S3_ACCESS_KEY": cli.accessKey,
"S3_SECRET": cli.secret,
"S3_SECRET": cli.accessSecret,
"S3_ACCESS_URL": cli.endpoint,
"S3_BACKEND": api.CLOUD_PROVIDER_GENERICS3,
}
@@ -71,8 +71,12 @@ func (self *SObjectStoreProviderFactory) ValidateUpdateCloudaccountCredential(ct
return output, nil
}
func (self *SObjectStoreProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
client, err := objectstore.NewObjectStoreClient(providerId, providerName, url, account, secret, false)
func (self *SObjectStoreProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
client, err := objectstore.NewObjectStoreClient(
objectstore.NewObjectStoreClientConfig(
cfg.URL, cfg.Account, cfg.Secret,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
@@ -60,6 +60,10 @@ func getJsonBodyReader(body jsonutils.JSONObject) io.Reader {
return reqBody
}
func (api *SXskyAdminApi) httpClient() *http.Client {
return api.client
}
func (api *SXskyAdminApi) jsonRequest(ctx context.Context, method httputils.THttpMethod, path string, hdr http.Header, body jsonutils.JSONObject) (http.Header, jsonutils.JSONObject, error) {
urlStr := strings.TrimRight(api.endpoint, "/") + "/" + strings.TrimLeft(path, "/")
req, err := http.NewRequest(string(method), urlStr, getJsonBodyReader(body))
@@ -17,6 +17,7 @@ package provider
import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/objectstore"
s3provider "yunion.io/x/onecloud/pkg/multicloud/objectstore/provider"
"yunion.io/x/onecloud/pkg/multicloud/objectstore/xsky"
)
@@ -33,8 +34,12 @@ func (self *SXskyProviderFactory) GetName() string {
return api.CLOUD_PROVIDER_XSKY
}
func (self *SXskyProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
client, err := xsky.NewXskyClient(providerId, providerName, url, account, secret, false)
func (self *SXskyProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
client, err := xsky.NewXskyClient(
objectstore.NewObjectStoreClientConfig(
cfg.URL, cfg.Account, cfg.Secret,
).CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
@@ -42,7 +47,11 @@ func (self *SXskyProviderFactory) GetProvider(providerId, providerName, url, acc
}
func (self *SXskyProviderFactory) GetClientRC(url, account, secret string) (map[string]string, error) {
client, err := xsky.NewXskyClient("", "", url, account, secret, false)
client, err := xsky.NewXskyClient(
objectstore.NewObjectStoreClientConfig(
url, account, secret,
),
)
if err != nil {
return nil, err
}
+18 -5
View File
@@ -26,6 +26,7 @@ import (
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/objectstore"
"yunion.io/x/onecloud/pkg/util/httputils"
)
type SXskyClient struct {
@@ -46,9 +47,16 @@ func parseAccount(account string) (user string, accessKey string) {
return
}
func NewXskyClient(providerId string, providerName string, endpoint string, account string, password string, isDebug bool) (*SXskyClient, error) {
usrname, accessKey := parseAccount(account)
adminApi := newXskyAdminApi(usrname, password, endpoint, isDebug)
func NewXskyClient(cfg *objectstore.ObjectStoreClientConfig) (*SXskyClient, error) {
usrname, accessKey := parseAccount(cfg.GetEndpoint())
adminApi := newXskyAdminApi(
usrname,
cfg.GetAccessSecret(),
cfg.GetEndpoint(),
cfg.GetDebug(),
)
httputils.SetClientProxyFunc(adminApi.httpClient(), cfg.GetCloudproviderConfig().ProxyFunc)
gwEp, err := adminApi.getS3GatewayEndpoint(context.Background())
if err != nil {
return nil, errors.Wrap(err, "adminApi.getS3GatewayIP")
@@ -68,7 +76,12 @@ func NewXskyClient(providerId string, providerName string, endpoint string, acco
}
}
s3store, err := objectstore.NewObjectStoreClientAndFetch(providerId, providerName, gwEp, accessKey, key.SecretKey, isDebug, false)
s3store, err := objectstore.NewObjectStoreClientAndFetch(
objectstore.NewObjectStoreClientConfig(
gwEp, accessKey, key.SecretKey,
).Debug(cfg.GetDebug()).CloudproviderConfig(cfg.GetCloudproviderConfig()),
false,
)
if err != nil {
return nil, errors.Wrap(err, "NewObjectStoreClient")
}
@@ -80,7 +93,7 @@ func NewXskyClient(providerId string, providerName string, endpoint string, acco
}
if len(accessKey) > 0 {
client.initAccount = account
client.initAccount = cfg.GetAccessKey()
}
client.SetVirtualObject(&client)
+1 -1
View File
@@ -32,7 +32,7 @@ func (storage *SNovaStorage) GetMetadata() *jsonutils.JSONDict {
}
func (storage *SNovaStorage) GetId() string {
return fmt.Sprintf("%s-%s-%s", storage.zone.region.client.providerID, storage.zone.GetGlobalId(), storage.GetName())
return fmt.Sprintf("%s-%s-%s", storage.zone.region.client.cpcfg.Id, storage.zone.GetGlobalId(), storage.GetName())
}
func (storage *SNovaStorage) GetName() string {
+55 -26
View File
@@ -37,47 +37,75 @@ const (
OPENSTACK_DEFAULT_REGION = "RegionOne"
)
type SOpenStackClient struct {
providerID string
providerName string
authURL string
username string
password string
project string
projectDomain string
endpointType string
domainName string
client *mcclient.Client
tokenCredential mcclient.TokenCredential
iregions []cloudprovider.ICloudRegion
type OpenstackClientConfig struct {
cpcfg cloudprovider.ProviderConfig
Debug bool
authURL string
username string
password string
project string
projectDomain string
domainName string
endpointType string
debug bool
}
func NewOpenStackClient(providerID string, providerName string, authURL string, username string, password string, project string, endpointType string, domainName string, projectDomainName string, isDebug bool) (*SOpenStackClient, error) {
cli := &SOpenStackClient{
providerID: providerID,
providerName: providerName,
authURL: strings.TrimRight(authURL, "/"),
func NewOpenstackClientConfig(authURL, username, password, project, projectDomain string) *OpenstackClientConfig {
cfg := &OpenstackClientConfig{
authURL: authURL,
username: username,
password: password,
project: project,
projectDomain: projectDomainName,
endpointType: endpointType,
domainName: domainName,
Debug: isDebug,
projectDomain: projectDomain,
}
return cfg
}
func (cfg *OpenstackClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *OpenstackClientConfig {
cfg.cpcfg = cpcfg
return cfg
}
func (cfg *OpenstackClientConfig) DomainName(domainName string) *OpenstackClientConfig {
cfg.domainName = domainName
return cfg
}
func (cfg *OpenstackClientConfig) EndpointType(endpointType string) *OpenstackClientConfig {
cfg.endpointType = endpointType
return cfg
}
func (cfg *OpenstackClientConfig) Debug(debug bool) *OpenstackClientConfig {
cfg.debug = debug
return cfg
}
type SOpenStackClient struct {
*OpenstackClientConfig
client *mcclient.Client
tokenCredential mcclient.TokenCredential
iregions []cloudprovider.ICloudRegion
}
func NewOpenStackClient(cfg *OpenstackClientConfig) (*SOpenStackClient, error) {
cli := &SOpenStackClient{
OpenstackClientConfig: cfg,
}
return cli, cli.fetchRegions()
}
func (cli *SOpenStackClient) GetCloudRegionExternalIdPrefix() string {
return fmt.Sprintf("%s/%s/", CLOUD_PROVIDER_OPENSTACK, cli.providerID)
return fmt.Sprintf("%s/%s/", CLOUD_PROVIDER_OPENSTACK, cli.cpcfg.Id)
}
func (cli *SOpenStackClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
subAccount := cloudprovider.SSubAccount{
Account: fmt.Sprintf("%s/%s", cli.project, cli.username),
Name: cli.providerName,
Name: cli.cpcfg.Name,
}
if len(cli.domainName) > 0 {
subAccount.Account = fmt.Sprintf("%s/%s", subAccount.Account, cli.domainName)
@@ -194,7 +222,8 @@ func (cli *SOpenStackClient) getVersion(region string, service string) (string,
}
func (cli *SOpenStackClient) connect() error {
cli.client = mcclient.NewClient(cli.authURL, 5, cli.Debug, false, "", "")
cli.client = mcclient.NewClient(cli.authURL, 5, cli.debug, false, "", "")
cli.client.SetHttpTransportProxyFunc(cli.cpcfg.ProxyFunc)
tokenCredential, err := cli.client.Authenticate(cli.username, cli.password, cli.domainName, cli.project, cli.projectDomain)
if err != nil {
return err
+15 -4
View File
@@ -102,16 +102,27 @@ func (self *SOpenStackProviderFactory) ValidateUpdateCloudaccountCredential(ctx
return output, nil
}
func (self *SOpenStackProviderFactory) GetProvider(providerId, providerName, url, account, password string) (cloudprovider.ICloudProvider, error) {
accountInfo := strings.Split(account, "/")
func (self *SOpenStackProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) {
accountInfo := strings.Split(cfg.Account, "/")
if len(accountInfo) < 2 {
return nil, fmt.Errorf("Missing username or project name %s", account)
return nil, fmt.Errorf("Missing username or project name %s", cfg.Account)
}
project, username, endpointType, domainName, projectDomainName := accountInfo[0], accountInfo[1], "internal", "Default", "Default"
if len(accountInfo) == 3 {
domainName, projectDomainName = accountInfo[2], accountInfo[2]
}
client, err := openstack.NewOpenStackClient(providerId, providerName, url, username, password, project, endpointType, domainName, projectDomainName, false)
client, err := openstack.NewOpenStackClient(
openstack.NewOpenstackClientConfig(
cfg.URL,
username,
cfg.Secret,
project,
projectDomainName,
).
DomainName(domainName).
EndpointType(endpointType).
CloudproviderConfig(cfg),
)
if err != nil {
return nil, err
}
+2 -2
View File
@@ -59,11 +59,11 @@ func (region *SRegion) GetId() string {
}
func (region *SRegion) GetName() string {
return fmt.Sprintf("%s-%s", region.client.providerName, region.Name)
return fmt.Sprintf("%s-%s", region.client.cpcfg.Name, region.Name)
}
func (region *SRegion) GetGlobalId() string {
return fmt.Sprintf("%s/%s/%s", CLOUD_PROVIDER_OPENSTACK, region.client.providerID, region.Name)
return fmt.Sprintf("%s/%s/%s", CLOUD_PROVIDER_OPENSTACK, region.client.cpcfg.Id, region.Name)
}
func (region *SRegion) IsEmulated() bool {
+3 -3
View File
@@ -42,11 +42,11 @@ func (cache *SStoragecache) GetMetadata() *jsonutils.JSONDict {
}
func (cache *SStoragecache) GetId() string {
return fmt.Sprintf("%s-%s", cache.region.client.providerID, cache.region.GetId())
return fmt.Sprintf("%s-%s", cache.region.client.cpcfg.Id, cache.region.GetId())
}
func (cache *SStoragecache) GetName() string {
return fmt.Sprintf("%s-%s", cache.region.client.providerName, cache.region.GetId())
return fmt.Sprintf("%s-%s", cache.region.client.cpcfg.Name, cache.region.GetId())
}
func (cache *SStoragecache) GetStatus() string {
@@ -58,7 +58,7 @@ func (cache *SStoragecache) Refresh() error {
}
func (cache *SStoragecache) GetGlobalId() string {
return fmt.Sprintf("%s-%s", cache.region.client.providerID, cache.region.GetGlobalId())
return fmt.Sprintf("%s-%s", cache.region.client.cpcfg.Id, cache.region.GetGlobalId())
}
func (cache *SStoragecache) IsEmulated() bool {
+3 -3
View File
@@ -135,7 +135,7 @@ func (b *SBucket) SetAcl(aclStr cloudprovider.TBucketACLType) error {
}
func (b *SBucket) getFullName() string {
return fmt.Sprintf("%s-%s", b.Name, b.region.client.AppID)
return fmt.Sprintf("%s-%s", b.Name, b.region.client.appId)
}
func (b *SBucket) getBucketUrlHost() string {
@@ -393,8 +393,8 @@ func (b *SBucket) GetTempUrl(method string, key string, expire time.Duration) (s
return "", errors.Wrap(err, "GetCosClient")
}
url, err := coscli.Object.GetPresignedURL(context.Background(), method, key,
b.region.client.SecretID,
b.region.client.SecretKey,
b.region.client.secretId,
b.region.client.secretKey,
expire, nil)
if err != nil {
return "", errors.Wrap(err, "coscli.Object.GetPresignedURL")

Some files were not shown because too many files have changed in this diff Show More