mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-31 01:35:56 +08:00
Merge pull request #11878 from tb365/automated-cherry-pick-of-#11877-upstream-release-3.7
Automated cherry pick of #11877: huawei cloud stack client fix
This commit is contained in:
@@ -755,6 +755,7 @@ type ICloudSku interface {
|
||||
GetPrepaidStatus() string
|
||||
GetPostpaidStatus() string
|
||||
|
||||
GetCpuArch() string
|
||||
GetCpuCoreCount() int
|
||||
GetMemorySizeMB() int
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ func (self *SHuaweiCloudStackGuestDriver) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK
|
||||
}
|
||||
|
||||
func (self *SHuaweiCloudStackGuestDriver) DoScheduleSKUFilter() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SHuaweiCloudStackGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
|
||||
keys := models.SComputeResourceKeys{}
|
||||
keys.SBaseProjectQuotaKeys = quotas.OwnerIdProjectQuotaKeys(scope, ownerId)
|
||||
@@ -153,5 +157,5 @@ func (self *SHuaweiCloudStackGuestDriver) IsNeedInjectPasswordByCloudInit(desc *
|
||||
}
|
||||
|
||||
func (self *SHuaweiCloudStackGuestDriver) IsSupportSetAutoRenew() bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1902,7 +1902,7 @@ func (self *SDisk) PerformPurge(ctx context.Context, userCred mcclient.TokenCred
|
||||
}
|
||||
|
||||
provider := self.GetCloudprovider()
|
||||
if provider != nil && provider.Provider == api.CLOUD_PROVIDER_HUAWEI {
|
||||
if provider != nil && utils.IsInStringArray(provider.Provider, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
cnt, err := self.GetSnapshotCount()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInternalServerError("GetSnapshotCount fail %s", err)
|
||||
@@ -1917,7 +1917,7 @@ func (self *SDisk) PerformPurge(ctx context.Context, userCred mcclient.TokenCred
|
||||
|
||||
func (self *SDisk) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if !jsonutils.QueryBoolean(query, "delete_snapshots", false) {
|
||||
if provider := self.GetCloudprovider(); provider != nil && provider.Provider == api.CLOUD_PROVIDER_HUAWEI {
|
||||
if provider := self.GetCloudprovider(); provider != nil && utils.IsInStringArray(provider.Provider, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
cnt, err := self.GetSnapshotCount()
|
||||
if err != nil {
|
||||
return httperrors.NewInternalServerError("GetSnapshotCount fail %s", err)
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -124,7 +125,7 @@ func (man *SCachedLoadbalancerAclManager) ValidateCreateData(ctx context.Context
|
||||
}
|
||||
}
|
||||
|
||||
if providerV.Model.(*SCloudprovider).Provider == api.CLOUD_PROVIDER_HUAWEI {
|
||||
if utils.IsInStringArray(providerV.Model.(*SCloudprovider).Provider, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
listenerV := validators.NewModelIdOrNameValidator("listener", "loadbalancerlistener", ownerId)
|
||||
if err := listenerV.Validate(data); err != nil {
|
||||
return nil, err
|
||||
@@ -322,7 +323,7 @@ func (self *SCachedLoadbalancerAcl) syncRemoveCloudLoadbalanceAcl(ctx context.Co
|
||||
func (acl *SCachedLoadbalancerAcl) SyncWithCloudLoadbalancerAcl(ctx context.Context, userCred mcclient.TokenCredential, extAcl cloudprovider.ICloudLoadbalancerAcl, projectId mcclient.IIdentityProvider) error {
|
||||
diff, err := db.UpdateWithLock(ctx, acl, func() error {
|
||||
// todo: 华为云acl没有name字段应此不需要同步名称
|
||||
if api.CLOUD_PROVIDER_HUAWEI != acl.GetProviderName() {
|
||||
if !utils.IsInStringArray(acl.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
acl.Name = extAcl.GetName()
|
||||
} else {
|
||||
ext_listener_id := extAcl.GetAclListenerID()
|
||||
@@ -358,7 +359,7 @@ func (man *SCachedLoadbalancerAclManager) GetOrCreateCachedAcl(ctx context.Conte
|
||||
defer lockman.ReleaseClass(ctx, man, ownerProjId)
|
||||
|
||||
listenerId := ""
|
||||
if lblis.GetProviderName() == api.CLOUD_PROVIDER_HUAWEI {
|
||||
if utils.IsInStringArray(lblis.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
listenerId = lblis.Id
|
||||
}
|
||||
if lblis.GetProviderName() == api.CLOUD_PROVIDER_OPENSTACK {
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -739,7 +740,7 @@ func (lbr *SLoadbalancerListenerRule) constructFieldsFromCloudListenerRule(userC
|
||||
lbr.Status = extRule.GetStatus()
|
||||
lbr.Condition = extRule.GetCondition()
|
||||
if groupId := extRule.GetBackendGroupId(); len(groupId) > 0 {
|
||||
if lbr.GetProviderName() == api.CLOUD_PROVIDER_HUAWEI {
|
||||
if utils.IsInStringArray(lbr.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
group, err := db.FetchByExternalId(HuaweiCachedLbbgManager, groupId)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
@@ -781,7 +782,7 @@ func (lbr *SLoadbalancerListenerRule) updateCachedLoadbalancerBackendGroupAssoci
|
||||
}
|
||||
|
||||
switch lbr.GetProviderName() {
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
case api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
_group, err := db.FetchByExternalId(HuaweiCachedLbbgManager, exteralLbbgId)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
|
||||
@@ -372,7 +372,7 @@ func (man *SLoadbalancerListenerManager) ValidateAcl(aclStatusV *validators.Vali
|
||||
return httperrors.NewMissingParameterError("acl_type")
|
||||
}
|
||||
} else {
|
||||
if providerName != api.CLOUD_PROVIDER_HUAWEI {
|
||||
if !utils.IsInStringArray(providerName, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
data.Set("acl_id", jsonutils.NewString(""))
|
||||
data.Set("cached_acl_id", jsonutils.NewString(""))
|
||||
}
|
||||
@@ -1011,7 +1011,7 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
|
||||
switch lblis.ListenerType {
|
||||
case api.LB_LISTENER_TYPE_UDP:
|
||||
if lblis.GetProviderName() != api.CLOUD_PROVIDER_HUAWEI {
|
||||
if !utils.IsInStringArray(lblis.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
lblis.HealthCheckExp = extListener.GetHealthCheckExp()
|
||||
lblis.HealthCheckReq = extListener.GetHealthCheckReq()
|
||||
}
|
||||
@@ -1053,7 +1053,7 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
|
||||
groupId := extListener.GetBackendGroupId()
|
||||
switch lblis.GetProviderName() {
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
case api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
if len(groupId) > 0 {
|
||||
group, err := db.FetchByExternalIdAndManagerId(HuaweiCachedLbbgManager, groupId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", lb.ManagerId)
|
||||
@@ -1145,7 +1145,7 @@ func (lblis *SLoadbalancerListener) updateCachedLoadbalancerBackendGroupAssociat
|
||||
}
|
||||
|
||||
switch lblis.GetProviderName() {
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
case api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
_group, err := db.FetchByExternalIdAndManagerId(HuaweiCachedLbbgManager, exteralLbbgId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", managerId)
|
||||
})
|
||||
|
||||
@@ -507,7 +507,7 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou
|
||||
params.EgressMbps = lb.EgressMbps
|
||||
}
|
||||
|
||||
if lb.AddressType == api.LB_ADDR_TYPE_INTRANET || utils.IsInStringArray(lb.SManagedResourceBase.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_AWS, api.CLOUD_PROVIDER_QCLOUD}) {
|
||||
if lb.AddressType == api.LB_ADDR_TYPE_INTRANET || utils.IsInStringArray(lb.SManagedResourceBase.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK, api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_AWS, api.CLOUD_PROVIDER_QCLOUD}) {
|
||||
vpc := lb.GetVpc()
|
||||
if vpc == nil {
|
||||
return nil, fmt.Errorf("failed to find vpc for lb %s", lb.Name)
|
||||
@@ -519,7 +519,7 @@ func (lb *SLoadbalancer) GetCreateLoadbalancerParams(iRegion cloudprovider.IClou
|
||||
params.VpcID = iVpc.GetId()
|
||||
}
|
||||
|
||||
if lb.AddressType == api.LB_ADDR_TYPE_INTRANET || utils.IsInStringArray(lb.SManagedResourceBase.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_AWS}) {
|
||||
if lb.AddressType == api.LB_ADDR_TYPE_INTRANET || utils.IsInStringArray(lb.SManagedResourceBase.GetProviderName(), []string{api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK, api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_AWS}) {
|
||||
networks, err := lb.GetNetworks()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find network for lb %s: %s", lb.Name, err)
|
||||
|
||||
@@ -362,7 +362,7 @@ func (self *SMountTarget) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return httperrors.NewGeneralError(errors.Wrapf(err, "GetRegion"))
|
||||
}
|
||||
if region.Provider == api.CLOUD_PROVIDER_HUAWEI {
|
||||
if utils.IsInStringArray(region.Provider, []string{api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}) {
|
||||
return httperrors.NewNotSupportedError("not allow to delete")
|
||||
}
|
||||
return self.SStatusStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
|
||||
@@ -551,7 +551,7 @@ func (lbbg *SLoadbalancerBackendGroup) purgeCachedlbbg(ctx context.Context, user
|
||||
switch lbbg.GetProviderName() {
|
||||
case api.CLOUD_PROVIDER_AWS:
|
||||
return lbbg.purgeAwsCachedlbbg(ctx, userCred)
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
case api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
return lbbg.purgeHuaweiCachedlbbg(ctx, userCred)
|
||||
}
|
||||
|
||||
@@ -632,7 +632,7 @@ func (lbb *SLoadbalancerBackend) purgeCachedlbb(ctx context.Context, userCred mc
|
||||
switch lbb.GetProviderName() {
|
||||
case api.CLOUD_PROVIDER_AWS:
|
||||
return lbb.purgeAwsCachedlbb(ctx, userCred)
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
case api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
return lbb.purgeHuaweiCachedlbb(ctx, userCred)
|
||||
}
|
||||
|
||||
|
||||
@@ -1095,6 +1095,7 @@ func (self *SServerSku) constructSku(extSku cloudprovider.ICloudSku) {
|
||||
self.PrepaidStatus = extSku.GetPrepaidStatus()
|
||||
self.PostpaidStatus = extSku.GetPostpaidStatus()
|
||||
|
||||
self.CpuArch = extSku.GetCpuArch()
|
||||
self.CpuCoreCount = extSku.GetCpuCoreCount()
|
||||
self.MemorySizeMB = extSku.GetMemorySizeMB()
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ func (manager *SZoneManager) AllowListItems(ctx context.Context, userCred mcclie
|
||||
func (zone *SZone) ValidateDeleteCondition(ctx context.Context) error {
|
||||
usage := zone.GeneralUsage()
|
||||
if !usage.IsEmpty() {
|
||||
return httperrors.NewNotEmptyError("not empty zone")
|
||||
return httperrors.NewNotEmptyError("not empty zone: %s", zone.Id)
|
||||
}
|
||||
return zone.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
}
|
||||
|
||||
@@ -17,3 +17,7 @@ func init() {
|
||||
func (self *SHuaweiCloudStackRegionDriver) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK
|
||||
}
|
||||
|
||||
func (self *SHuaweiCloudStackRegionDriver) IsSupportedElasticcache() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func init() {
|
||||
|
||||
func getOnLoadbalancerListenerCreateCompleteFunc(provider string) func(ctx context.Context, lblis *models.SLoadbalancerListener, data jsonutils.JSONObject, self *LoadbalancerListenerCreateTask) {
|
||||
switch provider {
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
case api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
return onHuaweiLoadbalancerListenerCreateComplete
|
||||
case api.CLOUD_PROVIDER_OPENSTACK:
|
||||
return onOpenstackLoadbalancerListenerCreateComplete
|
||||
|
||||
@@ -38,7 +38,7 @@ func init() {
|
||||
|
||||
func getOnPrepareLoadbalancerBackendgroupFunc(provider string) func(ctx context.Context, region *models.SCloudregion, lbr *models.SLoadbalancerListenerRule, data jsonutils.JSONObject, self *LoadbalancerListenerRuleCreateTask) {
|
||||
switch provider {
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
case api.CLOUD_PROVIDER_HUAWEI, api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
return onHuaiweiPrepareLoadbalancerBackendgroup
|
||||
case api.CLOUD_PROVIDER_AWS:
|
||||
return onAwsPrepareLoadbalancerBackendgroup
|
||||
|
||||
@@ -117,6 +117,10 @@ func (self *SInstanceType) GetPostpaidStatus() string {
|
||||
return api.SkuStatusAvailable
|
||||
}
|
||||
|
||||
func (self *SInstanceType) GetCpuArch() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SInstanceType) GetCpuCoreCount() int {
|
||||
return int(self.CpuCoreCount)
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ func (b *SBucket) GetStorageClass() string {
|
||||
output, err := obscli.GetBucketStoragePolicy(b.Name)
|
||||
if err != nil {
|
||||
log.Errorf("obscli.GetBucketStoragePolicy error %s", err)
|
||||
return ""
|
||||
}
|
||||
return output.StorageClass
|
||||
}
|
||||
|
||||
@@ -77,6 +77,12 @@ func (b *SBucket) GetCreateAt() time.Time {
|
||||
return b.CreationDate
|
||||
}
|
||||
|
||||
/*
|
||||
service returned error: Status=405 Method Not Allowed, Code=MethodNotAllowed,
|
||||
Message=The specified method is not allowed against this resource.,
|
||||
RequestId=00000175B0E9D138440B9EF092DF8A7A
|
||||
https://support.huaweicloud.com/productdesc-modelarts/modelarts_01_0017.html
|
||||
*/
|
||||
func (b *SBucket) GetStorageClass() string {
|
||||
obscli, err := b.region.getOBSClient()
|
||||
if err != nil {
|
||||
@@ -86,6 +92,7 @@ func (b *SBucket) GetStorageClass() string {
|
||||
output, err := obscli.GetBucketStoragePolicy(b.Name)
|
||||
if err != nil {
|
||||
log.Errorf("obscli.GetBucketStoragePolicy error %s", err)
|
||||
return ""
|
||||
}
|
||||
return output.StorageClass
|
||||
}
|
||||
@@ -593,7 +600,8 @@ func (b *SBucket) GetWebsiteConf() (cloudprovider.SBucketWebsiteConf, error) {
|
||||
}
|
||||
result.Index = out.IndexDocument.Suffix
|
||||
result.ErrorDocument = out.ErrorDocument.Key
|
||||
result.Url = fmt.Sprintf("https://%s.obs-website.%s.myhuaweicloud.com", b.Name, b.region.GetId())
|
||||
endpoint := b.region.client.cpcfg.GetEndpoint("obs-website", b.region.GetId())
|
||||
result.Url = fmt.Sprintf("https://%s.%s", endpoint)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ type Client struct {
|
||||
// 标记初始化状态
|
||||
init bool
|
||||
|
||||
Balances *modules.SBalanceManager
|
||||
Bandwidths *modules.SBandwidthManager
|
||||
Credentials *modules.SCredentialManager
|
||||
Disks *modules.SDiskManager
|
||||
@@ -53,7 +52,6 @@ type Client struct {
|
||||
ElbL7policies *modules.SElbL7policiesManager
|
||||
ElbPolicies *modules.SElbPoliciesManager
|
||||
ElbWhitelist *modules.SElbWhitelistManager
|
||||
Orders *modules.SOrderManager
|
||||
Port *modules.SPortManager
|
||||
Projects *modules.SProjectManager
|
||||
Regions *modules.SRegionManager
|
||||
@@ -153,7 +151,6 @@ func (self *Client) SetHttpClient(httpClient *http.Client) {
|
||||
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)
|
||||
@@ -161,7 +158,6 @@ func (self *Client) SetHttpClient(httpClient *http.Client) {
|
||||
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)
|
||||
@@ -239,7 +235,6 @@ func (self *Client) initManagers() {
|
||||
self.ElbL7policies = modules.NewElbL7policiesManager(self.cfg)
|
||||
self.ElbPolicies = modules.NewElbPoliciesManager(self.cfg)
|
||||
self.ElbWhitelist = modules.NewElbWhitelistManager(self.cfg)
|
||||
self.Orders = modules.NewOrderManager(self.cfg)
|
||||
self.SecurityGroupRules = modules.NewSecgroupRuleManager(self.cfg)
|
||||
self.SecurityGroups = modules.NewSecurityGroupManager(self.cfg)
|
||||
self.NovaSecurityGroups = modules.NewNovaSecurityGroupManager(self.cfg)
|
||||
@@ -247,7 +242,6 @@ func (self *Client) initManagers() {
|
||||
self.Users = modules.NewUserManager(self.cfg)
|
||||
self.Interface = modules.NewInterfaceManager(self.cfg)
|
||||
self.Jobs = modules.NewJobManager(self.cfg)
|
||||
self.Balances = modules.NewBalanceManager(self.cfg)
|
||||
self.Bandwidths = modules.NewBandwidthManager(self.cfg)
|
||||
self.Credentials = modules.NewCredentialManager(self.cfg)
|
||||
self.Port = modules.NewPortManager(self.cfg)
|
||||
|
||||
@@ -28,8 +28,6 @@ import (
|
||||
|
||||
type ServiceNameType string
|
||||
|
||||
const HuaWeiDefaultDomain = "myhuaweicloud.com"
|
||||
|
||||
const (
|
||||
ServiceNameECS ServiceNameType = "ecs" // 弹性云服务
|
||||
ServiceNameCCE ServiceNameType = "cce" // 云容器服务
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
|
||||
)
|
||||
|
||||
/*
|
||||
https://support.huaweicloud.com/api-oce/zh-cn_topic_0075195195.html
|
||||
客户运营能力API的Endpoint为“bss.cn-north-1.myhuaweicloud.com”。该Endpoint为全局Endpoint,中国站所有区域均可使用。
|
||||
如何获取合作伙伴ID https://support.huaweicloud.com/bpconsole_faq/zh-cn_topic_0081005893.html
|
||||
注意事项:
|
||||
客户查询自身的账户余额的时候,只允许使用客户自身的AK/SK或者Token调用。
|
||||
*/
|
||||
type SBalanceManager struct {
|
||||
domainId string // 租户ID
|
||||
SResourceManager
|
||||
}
|
||||
|
||||
type balanceCtx struct {
|
||||
domainId string
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0075213309.html
|
||||
// 这个manager非常特殊。url hardcode
|
||||
func (self *balanceCtx) GetPath() string {
|
||||
return fmt.Sprintf("%s/customer/account-mgr", self.domainId)
|
||||
}
|
||||
|
||||
// 这个manager非常特殊。只有List 和 SetDomainId方法可用。其他方法未验证
|
||||
func NewBalanceManager(cfg manager.IManagerConfig) *SBalanceManager {
|
||||
return &SBalanceManager{SResourceManager: SResourceManager{
|
||||
SBaseManager: NewBaseManager(cfg),
|
||||
ServiceName: ServiceNameBSS,
|
||||
Region: "cn-north-1",
|
||||
ProjectId: "",
|
||||
version: "v1.0",
|
||||
Keyword: "account_balance",
|
||||
KeywordPlural: "account_balances",
|
||||
|
||||
ResourceKeyword: "balances",
|
||||
}}
|
||||
}
|
||||
|
||||
func (self *SBalanceManager) List(querys map[string]string) (*responses.ListResult, error) {
|
||||
if len(self.domainId) == 0 {
|
||||
return nil, fmt.Errorf("domainId is emtpy.Use SetDomainId method to set.")
|
||||
}
|
||||
|
||||
ctx := &balanceCtx{domainId: self.domainId}
|
||||
return self.ListInContext(ctx, querys)
|
||||
}
|
||||
|
||||
func (self *SBalanceManager) SetDomainId(domainId string) {
|
||||
self.domainId = domainId
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/manager"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huaweistack/client/responses"
|
||||
)
|
||||
|
||||
// domian 客户账号ID https://support.huaweicloud.com/oce_faq/zh-cn_topic_0113714840.html
|
||||
type SOrderManager struct {
|
||||
orderCtx manager.IManagerContext
|
||||
SResourceManager
|
||||
}
|
||||
|
||||
type orderCtx struct {
|
||||
domainId string
|
||||
}
|
||||
|
||||
// {domain_id}/common/
|
||||
// 这个manager非常特殊。url hardcode
|
||||
func (self *orderCtx) GetPath() string {
|
||||
return fmt.Sprintf("%s/common", self.domainId)
|
||||
}
|
||||
|
||||
// 客户运营能力API的Endpoint为“bss.cn-north-1.myhuaweicloud.com”。该Endpoint为全局Endpoint,中国站所有区域均可使用。
|
||||
// https://support.huaweicloud.com/api-oce/zh-cn_topic_0084961226.html
|
||||
func NewOrderManager(cfg manager.IManagerConfig) *SOrderManager {
|
||||
return &SOrderManager{SResourceManager: SResourceManager{
|
||||
SBaseManager: NewBaseManager(cfg),
|
||||
ServiceName: ServiceNameBSS,
|
||||
Region: "cn-north-1",
|
||||
ProjectId: "",
|
||||
version: "v1.0",
|
||||
Keyword: "",
|
||||
KeywordPlural: "",
|
||||
|
||||
ResourceKeyword: "order-mgr",
|
||||
}}
|
||||
}
|
||||
|
||||
func (self *SOrderManager) SetDomainId(domainId string) error {
|
||||
if len(domainId) == 0 {
|
||||
return fmt.Errorf("SetDomainId domain id should not be emtpy")
|
||||
}
|
||||
|
||||
self.orderCtx = &orderCtx{domainId: domainId}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 查询客户包周期资源列表 https://support.huaweicloud.com/api-oce/zh-cn_topic_0084961226.html
|
||||
func (self *SOrderManager) List(querys map[string]string) (*responses.ListResult, error) {
|
||||
return nil, fmt.Errorf("Not Suppport List Order")
|
||||
}
|
||||
|
||||
// 查询订单的资源开通详情 https://support.huaweicloud.com/api-oce/api_order_00001.html
|
||||
func (self *SOrderManager) Get(id string, querys map[string]string) (jsonutils.JSONObject, error) {
|
||||
if self.orderCtx == nil {
|
||||
return nil, fmt.Errorf("domainId is emtpy.Use SetDomainId method to set.")
|
||||
}
|
||||
|
||||
// !!!特殊调用
|
||||
return self.GetInContextWithSpec(self.orderCtx, "orders-resource", id, querys, "")
|
||||
}
|
||||
|
||||
func (self *SOrderManager) PerformAction(action string, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
request := self.newRequest("POST", id, action, self.orderCtx)
|
||||
request.SetContent([]byte(getContent(params)))
|
||||
|
||||
return self._do(request, "")
|
||||
}
|
||||
|
||||
func (self *SOrderManager) GetPeriodResourceList(querys map[string]string) (*responses.ListResult, error) {
|
||||
if self.orderCtx == nil {
|
||||
return nil, fmt.Errorf("domainId is emtpy.Use SetDomainId method to set.")
|
||||
}
|
||||
|
||||
return self.ListInContextWithSpec(self.orderCtx, "resources/detail", querys, "data")
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0082522029.html
|
||||
func (self *SOrderManager) RenewPeriodResource(params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if self.orderCtx == nil {
|
||||
return nil, fmt.Errorf("domainId is emtpy.Use SetDomainId method to set.")
|
||||
}
|
||||
|
||||
return self.CreateInContextWithSpec(self.orderCtx, "resources/renew", params, "order_ids")
|
||||
}
|
||||
@@ -161,11 +161,7 @@ func (rds *SDBInstance) GetStatus() string {
|
||||
}
|
||||
|
||||
func (rds *SDBInstance) GetBillingType() string {
|
||||
_, err := rds.region.GetOrderResourceDetail(fmt.Sprintf("%s.vm", rds.Id))
|
||||
if err != nil {
|
||||
return billing_api.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
return billing_api.BILLING_TYPE_PREPAID
|
||||
return billing_api.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
|
||||
func (rds *SDBInstance) GetSecurityGroupIds() ([]string, error) {
|
||||
@@ -185,11 +181,7 @@ func (rds *SDBInstance) fetchFlavor() error {
|
||||
}
|
||||
|
||||
func (rds *SDBInstance) GetExpiredAt() time.Time {
|
||||
order, err := rds.region.GetOrderResourceDetail(fmt.Sprintf("%s.vm", rds.Id))
|
||||
if err != nil {
|
||||
return time.Time{}
|
||||
}
|
||||
return order.ExpireTime
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (rds *SDBInstance) GetStorageType() string {
|
||||
@@ -697,5 +689,5 @@ func (region *SRegion) RecoveryDBInstanceFromBackup(target, origin string, backu
|
||||
}
|
||||
|
||||
func (rds *SDBInstance) Renew(bc billing.SBillingCycle) error {
|
||||
return rds.region.RenewInstance(rds.Id, bc)
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
@@ -185,28 +185,8 @@ func (self *SDisk) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) getResourceDetails() *SResourceDetail {
|
||||
if self.details != nil {
|
||||
return self.details
|
||||
}
|
||||
|
||||
res, err := self.storage.zone.region.GetOrderResourceDetail(self.GetId())
|
||||
if err != nil {
|
||||
log.Debugln(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
self.details = &res
|
||||
return self.details
|
||||
}
|
||||
|
||||
func (self *SDisk) GetBillingType() string {
|
||||
details := self.getResourceDetails()
|
||||
if details == nil {
|
||||
return billing_api.BILLING_TYPE_POSTPAID
|
||||
} else {
|
||||
return billing_api.BILLING_TYPE_PREPAID
|
||||
}
|
||||
return billing_api.BILLING_TYPE_POSTPAID
|
||||
}
|
||||
|
||||
func (self *SDisk) GetCreatedAt() time.Time {
|
||||
@@ -215,11 +195,6 @@ func (self *SDisk) GetCreatedAt() time.Time {
|
||||
|
||||
func (self *SDisk) GetExpiredAt() time.Time {
|
||||
var expiredTime time.Time
|
||||
details := self.getResourceDetails()
|
||||
if details != nil {
|
||||
expiredTime = details.ExpireTime
|
||||
}
|
||||
|
||||
return expiredTime
|
||||
}
|
||||
|
||||
|
||||
@@ -163,15 +163,6 @@ func (self *SElasticcache) GetCreatedAt() time.Time {
|
||||
|
||||
func (self *SElasticcache) GetExpiredAt() time.Time {
|
||||
var expiredTime time.Time
|
||||
if self.ChargingMode == 1 {
|
||||
res, err := self.region.GetOrderResourceDetail(self.GetId())
|
||||
if err != nil {
|
||||
log.Debugln(err)
|
||||
}
|
||||
|
||||
expiredTime = res.ExpireTime
|
||||
}
|
||||
|
||||
return expiredTime
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,8 @@ import (
|
||||
|
||||
/*
|
||||
待解决问题:
|
||||
1.同步的子账户中有一条空记录.需要查原因
|
||||
2.安全组同步需要进一步确认
|
||||
3.实例接口需要进一步确认
|
||||
4.BGP type 目前是hard code在代码中。需要考虑从cloudmeta服务中查询
|
||||
2.VM密码登录不成功(ubuntu不行,centos可以)
|
||||
3.实例绑定eip 查不出来eip?
|
||||
*/
|
||||
|
||||
const (
|
||||
@@ -244,7 +242,7 @@ func getOBSEndpoint(regionId string) string {
|
||||
}
|
||||
|
||||
func (client *SHuaweiClient) getOBSClient(regionId string) (*obs.ObsClient, error) {
|
||||
endpoint := getOBSEndpoint(regionId)
|
||||
endpoint := client.cpcfg.SHuaweiCloudStackEndpoints.GetEndpoint("obs", regionId)
|
||||
return obs.New(client.accessKey, client.accessSecret, endpoint)
|
||||
}
|
||||
|
||||
@@ -322,11 +320,7 @@ func (self *SHuaweiClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error)
|
||||
if strings.ToLower(project.Name) == "mos" {
|
||||
continue
|
||||
}
|
||||
// https://www.huaweicloud.com/notice/2018/20190618171312411.html
|
||||
expiredAt, _ := timeutils.ParseTimeStr("2020-09-16 00:00:00")
|
||||
if !self.ownerCreateTime.IsZero() && self.ownerCreateTime.After(expiredAt) && strings.ToLower(project.Name) == "cn-north-1" {
|
||||
continue
|
||||
}
|
||||
|
||||
s := cloudprovider.SSubAccount{
|
||||
Name: fmt.Sprintf("%s-%s", self.cpcfg.Name, project.Name),
|
||||
Account: fmt.Sprintf("%s/%s", self.accessKey, project.ID),
|
||||
@@ -438,42 +432,6 @@ type SBalance struct {
|
||||
MeasureUnit int64 `json:"measure_unit"`
|
||||
}
|
||||
|
||||
// 这里的余额指的是所有租户的总余额
|
||||
func (self *SHuaweiClient) QueryAccountBalance() (*SAccountBalance, error) {
|
||||
domains, err := self.getEnabledDomains()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &SAccountBalance{}
|
||||
for _, domain := range domains {
|
||||
balances, err := self.queryDomainBalances(domain.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, balance := range balances {
|
||||
result.AvailableAmount += balance.Amount
|
||||
result.CreditAmount += balance.CreditAmount
|
||||
result.DesignatedAmount += balance.DesignatedAmount
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0075213309.html
|
||||
func (self *SHuaweiClient) queryDomainBalances(domainId string) ([]SBalance, error) {
|
||||
huawei, _ := self.newGeneralAPIClient()
|
||||
huawei.Balances.SetDomainId(domainId)
|
||||
balances := make([]SBalance, 0)
|
||||
err := doListAll(huawei.Balances.List, nil, &balances)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return balances, nil
|
||||
}
|
||||
|
||||
func (self *SHuaweiClient) GetVersion() string {
|
||||
return HUAWEI_API_VERSION
|
||||
}
|
||||
|
||||
@@ -167,7 +167,11 @@ func (self *SImage) GetSizeByte() int64 {
|
||||
|
||||
func (self *SImage) getNormalizedImageInfo() *imagetools.ImageInfo {
|
||||
if self.imgInfo == nil {
|
||||
imgInfo := imagetools.NormalizeImageInfo(self.ImageSourceType, self.OSType, self.OSType, self.Platform, "")
|
||||
arch := "x86"
|
||||
if strings.ToLower(self.SupportArm) == "true" {
|
||||
arch = "arm"
|
||||
}
|
||||
imgInfo := imagetools.NormalizeImageInfo(self.ImageSourceType, arch, self.OSType, self.Platform, "")
|
||||
self.imgInfo = &imgInfo
|
||||
}
|
||||
|
||||
@@ -273,10 +277,6 @@ func excludeImage(image SImage) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if len(image.SupportArm) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -421,15 +421,14 @@ func formatVersion(osDist string, osVersion string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// todo: 如何保持同步更新
|
||||
// https://support.huaweicloud.com/api-ims/zh-cn_topic_0031617666.html
|
||||
func stdVersion(osDist string, osVersion string, osArch string) (string, error) {
|
||||
// 架构
|
||||
arch := ""
|
||||
switch osArch {
|
||||
case "64", apis.OS_ARCH_X86_64:
|
||||
case "64", apis.OS_ARCH_X86_64, apis.OS_ARCH_AARCH64, apis.OS_ARCH_ARM:
|
||||
arch = "64bit"
|
||||
case "32", apis.OS_ARCH_X86_32:
|
||||
case "32", apis.OS_ARCH_X86_32, apis.OS_ARCH_AARCH32:
|
||||
arch = "32bit"
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported arch %s.reference: https://support.huaweicloud.com/api-ims/zh-cn_topic_0031617666.html", osArch)
|
||||
|
||||
@@ -354,15 +354,6 @@ func (self *SInstance) GetCreatedAt() time.Time {
|
||||
// charging_mode “0”:按需计费 “1”:按包年包月计费
|
||||
func (self *SInstance) GetExpiredAt() time.Time {
|
||||
var expiredTime time.Time
|
||||
if self.Metadata.ChargingMode == "1" {
|
||||
res, err := self.host.zone.region.GetOrderResourceDetail(self.GetId())
|
||||
if err != nil {
|
||||
log.Debugln(err)
|
||||
}
|
||||
|
||||
expiredTime = res.ExpireTime
|
||||
}
|
||||
|
||||
return expiredTime
|
||||
}
|
||||
|
||||
@@ -765,7 +756,7 @@ func (self *SInstance) CreateDisk(ctx context.Context, sizeMb int, uuid string,
|
||||
}
|
||||
|
||||
func (self *SInstance) Renew(bc billing.SBillingCycle) error {
|
||||
return self.host.zone.region.RenewInstance(self.GetId(), bc)
|
||||
return cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0094148850.html
|
||||
@@ -955,30 +946,7 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st
|
||||
ids, err = self.GetAllSubTaskEntityIDs(self.ecsClient.Servers.ServiceType(), _id, "server_id")
|
||||
} else {
|
||||
// 包年包月
|
||||
err = cloudprovider.WaitCreated(10*time.Second, 300*time.Second, func() bool {
|
||||
log.Debugf("WaitCreated %s", _id)
|
||||
order, e := self.GetOrder(_id)
|
||||
if e != nil {
|
||||
log.Debugf(e.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
if order.TotalSize == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
ids, err = self.getAllResIdsByType(_id, RESOURCE_TYPE_VM)
|
||||
if err != nil {
|
||||
log.Debugln(err)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(ids) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
return "", errors.Wrap(cloudprovider.ErrNotSupported, "CreateInstance")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -1321,43 +1289,6 @@ func (self *SRegion) DetachDisk(instanceId string, diskId string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// // https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0082522029.html
|
||||
// 只支持传入主资源ID, 根据“查询客户包周期资源列表”接口响应参数中的“is_main_resource”来标识。
|
||||
// expire_mode 0:进入宽限期 1:转按需 2:自动退订 3:自动续订(当前只支持ECS、EVS和VPC)
|
||||
func (self *SRegion) RenewInstance(instanceId string, bc billing.SBillingCycle) error {
|
||||
params := jsonutils.NewDict()
|
||||
res := jsonutils.NewArray()
|
||||
res.Add(jsonutils.NewString(instanceId))
|
||||
params.Add(res, "resource_ids")
|
||||
params.Add(jsonutils.NewInt(EXPIRE_MODE_AUTO_UNSUBSCRIBE), "expire_mode") // 自动退订
|
||||
params.Add(jsonutils.NewInt(AUTO_PAY_TRUE), "isAutoPay") // 自动支付
|
||||
month := int64(bc.GetMonths())
|
||||
year := int64(bc.GetYears())
|
||||
|
||||
if month >= 1 && month <= 11 {
|
||||
params.Add(jsonutils.NewInt(PERIOD_TYPE_MONTH), "period_type")
|
||||
params.Add(jsonutils.NewInt(month), "period_num")
|
||||
} else if year >= 1 && year <= 3 {
|
||||
params.Add(jsonutils.NewInt(PERIOD_TYPE_YEAR), "period_type")
|
||||
params.Add(jsonutils.NewInt(year), "period_num")
|
||||
} else {
|
||||
return fmt.Errorf("invalid renew period %d month,must be 1~11 month or 1~3 year", month)
|
||||
}
|
||||
|
||||
domainId, err := self.getDomianId()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = self.ecsClient.Orders.SetDomainId(domainId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = self.ecsClient.Orders.RenewPeriodResource(params)
|
||||
return err
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0065817702.html
|
||||
func (self *SRegion) GetInstanceSecrityGroupIds(instanceId string) ([]string, error) {
|
||||
if len(instanceId) == 0 {
|
||||
@@ -1379,20 +1310,6 @@ func (self *SRegion) GetInstanceSecrityGroupIds(instanceId string) ([]string, er
|
||||
return securitygroupIds, nil
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/api-oce/zh-cn_topic_0082522030.html
|
||||
func (self *SRegion) UnsubscribeInstance(instanceId string, domianId string) (jsonutils.JSONObject, error) {
|
||||
unsubObj := jsonutils.NewDict()
|
||||
unsubObj.Add(jsonutils.NewInt(1), "unSubType")
|
||||
unsubObj.Add(jsonutils.NewInt(5), "unsubscribeReasonType")
|
||||
unsubObj.Add(jsonutils.NewString("no reason"), "unsubscribeReason")
|
||||
resList := jsonutils.NewArray()
|
||||
resList.Add(jsonutils.NewString(instanceId))
|
||||
unsubObj.Add(resList, "resourceIds")
|
||||
|
||||
self.ecsClient.Orders.SetDomainId(domianId)
|
||||
return self.ecsClient.Orders.PerformAction("resources/delete", "", unsubObj)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetProjectId() string {
|
||||
return self.EnterpriseProjectId
|
||||
}
|
||||
|
||||
@@ -111,16 +111,6 @@ func getFlavorLocalCategory(family string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/productdesc-ecs/ecs_01_0066.html
|
||||
// https://support.huaweicloud.com/ecs_faq/ecs_faq_0105.html
|
||||
func GetCpuArch(flavorId string) string {
|
||||
if strings.HasPrefix(flavorId, "k") {
|
||||
return "aarch64"
|
||||
}
|
||||
|
||||
return "x86"
|
||||
}
|
||||
|
||||
func (self *SInstanceType) GetId() string {
|
||||
return self.ID
|
||||
}
|
||||
@@ -177,9 +167,19 @@ func (self *SInstanceType) GetPostpaidStatus() string {
|
||||
return "available"
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/productdesc-ecs/ecs_01_0066.html
|
||||
// https://support.huaweicloud.com/ecs_faq/ecs_faq_0105.html
|
||||
func (self *SInstanceType) GetCpuArch() string {
|
||||
if strings.HasPrefix(self.ID, "k") {
|
||||
return "aarch64"
|
||||
}
|
||||
|
||||
return "x86"
|
||||
}
|
||||
|
||||
func (self *SInstanceType) GetCpuCoreCount() int {
|
||||
count, err := strconv.Atoi(self.Vcpus)
|
||||
if err != nil {
|
||||
if err == nil {
|
||||
return count
|
||||
}
|
||||
return 0
|
||||
|
||||
@@ -16,12 +16,7 @@ package huaweistack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SOrder struct {
|
||||
@@ -73,121 +68,3 @@ func (self *SRegion) getDomianId() (string, error) {
|
||||
|
||||
return domains[0].ID, nil
|
||||
}
|
||||
|
||||
/*
|
||||
获取订单信息 https://support.huaweicloud.com/api-oce/api_order_00001.html
|
||||
*/
|
||||
func (self *SRegion) GetOrder(orderId string) (SOrder, error) {
|
||||
var order SOrder
|
||||
domain, err := self.getDomianId()
|
||||
if err != nil {
|
||||
return order, err
|
||||
}
|
||||
|
||||
err = self.ecsClient.Orders.SetDomainId(domain)
|
||||
if err != nil {
|
||||
return order, err
|
||||
}
|
||||
|
||||
err = DoGet(self.ecsClient.Orders.Get, orderId, nil, &order)
|
||||
return order, err
|
||||
}
|
||||
|
||||
/*
|
||||
获取订单资源详情列表 https://support.huaweicloud.com/api-oce/zh-cn_topic_0084961226.html
|
||||
*/
|
||||
func (self *SRegion) GetOrderResources(orderId string, resource_ids []string, only_main_resource bool) ([]SResourceDetail, error) {
|
||||
domain, err := self.getDomianId()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = self.ecsClient.Orders.SetDomainId(domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resources := make([]SResourceDetail, 0)
|
||||
queries := map[string]string{"customer_id": domain}
|
||||
if len(orderId) > 0 {
|
||||
queries["order_id"] = orderId
|
||||
}
|
||||
|
||||
if len(resource_ids) > 0 {
|
||||
queries["resource_ids"] = strings.Join(resource_ids, ",")
|
||||
}
|
||||
|
||||
if only_main_resource {
|
||||
queries["only_main_resource"] = "1"
|
||||
}
|
||||
|
||||
err = doListAll(self.ecsClient.Orders.GetPeriodResourceList, queries, &resources)
|
||||
return resources, err
|
||||
}
|
||||
|
||||
/*
|
||||
获取资源详情 https://support.huaweicloud.com/api-oce/zh-cn_topic_0084961226.html
|
||||
*/
|
||||
func (self *SRegion) GetOrderResourceDetail(resourceId string) (SResourceDetail, error) {
|
||||
var res SResourceDetail
|
||||
if len(resourceId) == 0 {
|
||||
return res, fmt.Errorf("GetOrderResourceDetail resource id should not be empty")
|
||||
}
|
||||
|
||||
resources, err := self.GetOrderResources("", []string{resourceId}, false)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
switch len(resources) {
|
||||
case 0:
|
||||
return res, cloudprovider.ErrNotFound
|
||||
case 1:
|
||||
return resources[0], nil
|
||||
default:
|
||||
return res, fmt.Errorf("%d resources with id %s found, Expect 1", len(resources), resourceId)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SRegion) GetAllResByOrderId(orderId string) ([]SResource, error) {
|
||||
order, err := self.GetOrder(orderId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("GetAllResByOrderId %#v", order.Resources)
|
||||
return order.Resources, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getAllResByType(orderId string, resourceType string) ([]SResource, error) {
|
||||
res, err := self.GetAllResByOrderId(orderId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := make([]SResource, 0)
|
||||
for i := range res {
|
||||
r := res[i]
|
||||
if r.ResourceType == resourceType {
|
||||
ret = append(ret, r)
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) getAllResIdsByType(orderId string, resourceType string) ([]string, error) {
|
||||
res, err := self.getAllResByType(orderId, resourceType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ids := make([]string, 0)
|
||||
for _, r := range res {
|
||||
if len(r.ResourceID) > 0 {
|
||||
ids = append(ids, r.ResourceID)
|
||||
}
|
||||
}
|
||||
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
@@ -572,18 +572,8 @@ func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP
|
||||
ctype = InternetChargeByBandwidth
|
||||
}
|
||||
|
||||
// todo: 如何避免hardcode。集成到cloudmeta服务中?
|
||||
if len(eip.BGPType) == 0 {
|
||||
switch self.GetId() {
|
||||
case "cn-north-1", "cn-east-2", "cn-south-1":
|
||||
eip.BGPType = "5_sbgp"
|
||||
case "cn-northeast-1":
|
||||
eip.BGPType = "5_telcom"
|
||||
case "cn-north-4", "ap-southeast-1", "ap-southeast-2", "eu-west-0":
|
||||
eip.BGPType = "5_bgp"
|
||||
default:
|
||||
eip.BGPType = "5_bgp"
|
||||
}
|
||||
eip.BGPType = "5_bgp"
|
||||
}
|
||||
|
||||
// 华为云EIP名字最大长度64
|
||||
@@ -989,7 +979,17 @@ func (region *SRegion) GetIBucketByName(name string) (cloudprovider.ICloudBucket
|
||||
}
|
||||
|
||||
func (self *SRegion) GetSkus(zoneId string) ([]cloudprovider.ICloudSku, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
ret := make([]cloudprovider.ICloudSku, 0)
|
||||
flavors, err := self.fetchInstanceTypes(zoneId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetchInstanceTypes")
|
||||
}
|
||||
|
||||
for i := range flavors {
|
||||
ret = append(ret, &flavors[i])
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIElasticcaches() ([]cloudprovider.ICloudElasticcache, error) {
|
||||
@@ -1044,24 +1044,7 @@ func (self *SRegion) GetZoneSupportedDiskTypes(zoneId string) ([]string, error)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetISkus() ([]cloudprovider.ICloudSku, error) {
|
||||
izones, err := self.GetIZones()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetIZones")
|
||||
}
|
||||
|
||||
ret := make([]cloudprovider.ICloudSku, 0)
|
||||
for i := range izones {
|
||||
flavors, err := self.fetchInstanceTypes(izones[i].GetId())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetchInstanceTypes")
|
||||
}
|
||||
|
||||
for i := range flavors {
|
||||
ret = append(ret, &flavors[i])
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
return self.GetSkus("")
|
||||
}
|
||||
|
||||
func (self *SRegion) GetEndpoints() ([]jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -153,19 +153,6 @@ func init() {
|
||||
DOMAIN string `help:"domain ID"`
|
||||
}
|
||||
|
||||
shellutils.R(&InstanceOrderUnsubscribeOptions{}, "instance-order-unsubscribe", "Unsubscribe a prepaid server", func(cli *huawei.SRegion, args *InstanceOrderUnsubscribeOptions) error {
|
||||
instance, e := cli.GetInstanceByID(args.ID)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
_, err := cli.UnsubscribeInstance(instance.GetId(), args.DOMAIN)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
type InstanceSaveImageOptions struct {
|
||||
ID string `help:"Instance ID"`
|
||||
IMAGE_NAME string `help:"Image name"`
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// 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 (
|
||||
huawei "yunion.io/x/onecloud/pkg/multicloud/huaweistack"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type OrderListOptions struct {
|
||||
OrderId string `help:"Order Id"`
|
||||
ResourceIds []string `help:"ResourceIds"`
|
||||
MainResource bool `help:"Main resource"`
|
||||
}
|
||||
shellutils.R(&OrderListOptions{}, "order-list", "List order", func(cli *huawei.SRegion, args *OrderListOptions) error {
|
||||
orders, err := cli.GetOrderResources(args.OrderId, args.ResourceIds, args.MainResource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(orders, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
+7
-6
@@ -20,14 +20,15 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
type AccountBalanceOptions struct {
|
||||
type SkuListOptions struct {
|
||||
}
|
||||
shellutils.R(&AccountBalanceOptions{}, "balance", "Get account balance", func(cli *huawei.SRegion, args *AccountBalanceOptions) error {
|
||||
result, err := cli.GetClient().QueryAccountBalance()
|
||||
if err != nil {
|
||||
return err
|
||||
shellutils.R(&SkuListOptions{}, "sku-list", "List skus", func(cli *huawei.SRegion, args *SkuListOptions) error {
|
||||
skus, e := cli.GetISkus()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printObject(result)
|
||||
|
||||
printList(skus, 0, 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -38,7 +38,8 @@ import (
|
||||
type SStoragecache struct {
|
||||
multicloud.SResourceBase
|
||||
multicloud.HuaweiTags
|
||||
region *SRegion
|
||||
region *SRegion
|
||||
iimages []cloudprovider.ICloudImage
|
||||
}
|
||||
|
||||
func GetBucketName(regionId string, imageId string) string {
|
||||
@@ -69,22 +70,43 @@ func (self *SStoragecache) IsEmulated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SStoragecache) fetchImages() error {
|
||||
imagesGold, err := self.region.GetImages("", ImageOwnerPublic, "", EnvFusionCompute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
imagesSelf, err := self.region.GetImages("", ImageOwnerSelf, "", EnvFusionCompute)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
self.iimages = make([]cloudprovider.ICloudImage, len(imagesGold)+len(imagesSelf))
|
||||
for i := range imagesGold {
|
||||
imagesGold[i].storageCache = self
|
||||
self.iimages[i] = &imagesGold[i]
|
||||
}
|
||||
|
||||
l := len(imagesGold)
|
||||
for i := range imagesSelf {
|
||||
imagesSelf[i].storageCache = self
|
||||
self.iimages[i+l] = &imagesSelf[i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetICloudImages() ([]cloudprovider.ICloudImage, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
if self.iimages == nil {
|
||||
err := self.fetchImages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return self.iimages, nil
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetICustomizedCloudImages() ([]cloudprovider.ICloudImage, error) {
|
||||
imagesSelf, err := self.region.GetImages("", ImageOwnerSelf, "", EnvFusionCompute)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetImages")
|
||||
}
|
||||
|
||||
ret := []cloudprovider.ICloudImage{}
|
||||
for i := range imagesSelf {
|
||||
imagesSelf[i].storageCache = self
|
||||
ret = append(ret, &imagesSelf[i])
|
||||
}
|
||||
return ret, nil
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SStoragecache) GetIImageById(extId string) (cloudprovider.ICloudImage, error) {
|
||||
|
||||
@@ -208,6 +208,10 @@ func (flavor *SFlavor) GetPostpaidStatus() string {
|
||||
return api.SkuStatusAvailable
|
||||
}
|
||||
|
||||
func (flavor *SFlavor) GetCpuArch() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (flavor *SFlavor) GetCpuCoreCount() int {
|
||||
return int(flavor.Vcpus)
|
||||
}
|
||||
|
||||
@@ -166,6 +166,10 @@ func (offering *SInstanceOffering) GetPrepaidStatus() string {
|
||||
return api.SkuStatusSoldout
|
||||
}
|
||||
|
||||
func (offering *SInstanceOffering) GetCpuArch() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (offering *SInstanceOffering) GetPostpaidStatus() string {
|
||||
return api.SkuStatusAvailable
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user