diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index d7f6c336e3..996c94fe08 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -800,6 +800,7 @@ type ICloudSku interface { GetPrepaidStatus() string GetPostpaidStatus() string + GetCpuArch() string GetCpuCoreCount() int GetMemorySizeMB() int diff --git a/pkg/compute/guestdrivers/huaweistack.go b/pkg/compute/guestdrivers/huaweistack.go index c3aff11151..9840b6473e 100644 --- a/pkg/compute/guestdrivers/huaweistack.go +++ b/pkg/compute/guestdrivers/huaweistack.go @@ -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 } diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 67798aa0c8..f96b476832 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -1907,7 +1907,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) @@ -1922,7 +1922,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) diff --git a/pkg/compute/models/loadbalancercachedacls.go b/pkg/compute/models/loadbalancercachedacls.go index 2357340c0b..6f074e7e19 100644 --- a/pkg/compute/models/loadbalancercachedacls.go +++ b/pkg/compute/models/loadbalancercachedacls.go @@ -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 @@ -313,7 +314,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() @@ -349,7 +350,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 { diff --git a/pkg/compute/models/loadbalancerlistenerrules.go b/pkg/compute/models/loadbalancerlistenerrules.go index 7582808512..bd0e43653f 100644 --- a/pkg/compute/models/loadbalancerlistenerrules.go +++ b/pkg/compute/models/loadbalancerlistenerrules.go @@ -740,7 +740,7 @@ func (lbr *SLoadbalancerListenerRule) constructFieldsFromCloudListenerRule(userC } 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 { @@ -782,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 { diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index 850a738aee..d96302ccd3 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -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("")) } @@ -1016,7 +1016,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() } @@ -1059,7 +1059,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) @@ -1151,7 +1151,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) }) diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index e7a606ab32..40dfa58811 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -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) diff --git a/pkg/compute/models/mount_targets.go b/pkg/compute/models/mount_targets.go index 925ae9ff99..273ac38c36 100644 --- a/pkg/compute/models/mount_targets.go +++ b/pkg/compute/models/mount_targets.go @@ -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) diff --git a/pkg/compute/models/purge.go b/pkg/compute/models/purge.go index beb4db9763..c5effca85d 100644 --- a/pkg/compute/models/purge.go +++ b/pkg/compute/models/purge.go @@ -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) } diff --git a/pkg/compute/models/skus.go b/pkg/compute/models/skus.go index 702ede8141..17e03bd978 100644 --- a/pkg/compute/models/skus.go +++ b/pkg/compute/models/skus.go @@ -1091,6 +1091,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() diff --git a/pkg/compute/models/zones.go b/pkg/compute/models/zones.go index b8135d8ffb..bb48661f9b 100644 --- a/pkg/compute/models/zones.go +++ b/pkg/compute/models/zones.go @@ -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) } diff --git a/pkg/compute/regiondrivers/huaweistack.go b/pkg/compute/regiondrivers/huaweistack.go index 49a237f8df..de9b420ed7 100644 --- a/pkg/compute/regiondrivers/huaweistack.go +++ b/pkg/compute/regiondrivers/huaweistack.go @@ -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 +} diff --git a/pkg/compute/tasks/loadbalancer_listener_create_task.go b/pkg/compute/tasks/loadbalancer_listener_create_task.go index fa9e86bfd1..e5a1033cec 100644 --- a/pkg/compute/tasks/loadbalancer_listener_create_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_create_task.go @@ -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 diff --git a/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go b/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go index fdb0f052fc..a95e4dedfe 100644 --- a/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go +++ b/pkg/compute/tasks/loadbalancer_listener_rule_create_task.go @@ -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 diff --git a/pkg/multicloud/apsara/instancetype.go b/pkg/multicloud/apsara/instancetype.go index de42f724ce..abd064dbdb 100644 --- a/pkg/multicloud/apsara/instancetype.go +++ b/pkg/multicloud/apsara/instancetype.go @@ -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) } diff --git a/pkg/multicloud/cloudpods/sku.go b/pkg/multicloud/cloudpods/sku.go index cb5e78a86d..66be3b9929 100644 --- a/pkg/multicloud/cloudpods/sku.go +++ b/pkg/multicloud/cloudpods/sku.go @@ -61,6 +61,10 @@ func (self *SServerSku) GetPostpaidStatus() string { return self.PostpaidStatus } +func (self *SServerSku) GetCpuArch() string { + return "x86" +} + func (self *SServerSku) GetCpuCoreCount() int { return self.CpuCoreCount } diff --git a/pkg/multicloud/huawei/bucket.go b/pkg/multicloud/huawei/bucket.go index 66ca5e237b..ec1dadb1b7 100644 --- a/pkg/multicloud/huawei/bucket.go +++ b/pkg/multicloud/huawei/bucket.go @@ -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 } diff --git a/pkg/multicloud/huaweistack/bucket.go b/pkg/multicloud/huaweistack/bucket.go index 0158963ed3..3ff8bef53a 100644 --- a/pkg/multicloud/huaweistack/bucket.go +++ b/pkg/multicloud/huaweistack/bucket.go @@ -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 } diff --git a/pkg/multicloud/huaweistack/client/client.go b/pkg/multicloud/huaweistack/client/client.go index aa7e79b3f4..d808e837bc 100644 --- a/pkg/multicloud/huaweistack/client/client.go +++ b/pkg/multicloud/huaweistack/client/client.go @@ -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) diff --git a/pkg/multicloud/huaweistack/client/modules/manager_resource.go b/pkg/multicloud/huaweistack/client/modules/manager_resource.go index 376c33e4fb..b50c322aba 100644 --- a/pkg/multicloud/huaweistack/client/modules/manager_resource.go +++ b/pkg/multicloud/huaweistack/client/modules/manager_resource.go @@ -28,8 +28,6 @@ import ( type ServiceNameType string -const HuaWeiDefaultDomain = "myhuaweicloud.com" - const ( ServiceNameECS ServiceNameType = "ecs" // 弹性云服务 ServiceNameCCE ServiceNameType = "cce" // 云容器服务 diff --git a/pkg/multicloud/huaweistack/client/modules/mod_balances.go b/pkg/multicloud/huaweistack/client/modules/mod_balances.go deleted file mode 100644 index 23dbce872e..0000000000 --- a/pkg/multicloud/huaweistack/client/modules/mod_balances.go +++ /dev/null @@ -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 -} diff --git a/pkg/multicloud/huaweistack/client/modules/mod_orders.go b/pkg/multicloud/huaweistack/client/modules/mod_orders.go deleted file mode 100644 index ebcfea08f3..0000000000 --- a/pkg/multicloud/huaweistack/client/modules/mod_orders.go +++ /dev/null @@ -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") -} diff --git a/pkg/multicloud/huaweistack/dbinstance.go b/pkg/multicloud/huaweistack/dbinstance.go index f015e6e44f..41298389e1 100644 --- a/pkg/multicloud/huaweistack/dbinstance.go +++ b/pkg/multicloud/huaweistack/dbinstance.go @@ -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 } diff --git a/pkg/multicloud/huaweistack/disk.go b/pkg/multicloud/huaweistack/disk.go index 8d388c75db..d966ce9dc5 100644 --- a/pkg/multicloud/huaweistack/disk.go +++ b/pkg/multicloud/huaweistack/disk.go @@ -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 } diff --git a/pkg/multicloud/huaweistack/elasticcache_instance.go b/pkg/multicloud/huaweistack/elasticcache_instance.go index 24feb34a6e..3218b09b68 100644 --- a/pkg/multicloud/huaweistack/elasticcache_instance.go +++ b/pkg/multicloud/huaweistack/elasticcache_instance.go @@ -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 } diff --git a/pkg/multicloud/huaweistack/huawei.go b/pkg/multicloud/huaweistack/huawei.go index cb66b66acd..75f540aa48 100644 --- a/pkg/multicloud/huaweistack/huawei.go +++ b/pkg/multicloud/huaweistack/huawei.go @@ -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 } diff --git a/pkg/multicloud/huaweistack/image.go b/pkg/multicloud/huaweistack/image.go index d1bd0dadf5..60348ff0a5 100644 --- a/pkg/multicloud/huaweistack/image.go +++ b/pkg/multicloud/huaweistack/image.go @@ -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) diff --git a/pkg/multicloud/huaweistack/instance.go b/pkg/multicloud/huaweistack/instance.go index ebea15d913..39fb9fc3ba 100644 --- a/pkg/multicloud/huaweistack/instance.go +++ b/pkg/multicloud/huaweistack/instance.go @@ -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 } diff --git a/pkg/multicloud/huaweistack/instancetype.go b/pkg/multicloud/huaweistack/instancetype.go index fe83a5327c..830d2eebcc 100644 --- a/pkg/multicloud/huaweistack/instancetype.go +++ b/pkg/multicloud/huaweistack/instancetype.go @@ -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 diff --git a/pkg/multicloud/huaweistack/order.go b/pkg/multicloud/huaweistack/order.go index 198641903d..1b783b24d5 100644 --- a/pkg/multicloud/huaweistack/order.go +++ b/pkg/multicloud/huaweistack/order.go @@ -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 -} diff --git a/pkg/multicloud/huaweistack/region.go b/pkg/multicloud/huaweistack/region.go index dcdad7a068..d39f6558ed 100644 --- a/pkg/multicloud/huaweistack/region.go +++ b/pkg/multicloud/huaweistack/region.go @@ -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) { diff --git a/pkg/multicloud/huaweistack/shell/instance.go b/pkg/multicloud/huaweistack/shell/instance.go index b559b9cdd6..f9ce186c22 100644 --- a/pkg/multicloud/huaweistack/shell/instance.go +++ b/pkg/multicloud/huaweistack/shell/instance.go @@ -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"` diff --git a/pkg/multicloud/huaweistack/shell/order.go b/pkg/multicloud/huaweistack/shell/order.go deleted file mode 100644 index bde61f3df0..0000000000 --- a/pkg/multicloud/huaweistack/shell/order.go +++ /dev/null @@ -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 - }) -} diff --git a/pkg/multicloud/huaweistack/shell/business.go b/pkg/multicloud/huaweistack/shell/skus.go similarity index 72% rename from pkg/multicloud/huaweistack/shell/business.go rename to pkg/multicloud/huaweistack/shell/skus.go index e08454ee0a..55909a8d2d 100644 --- a/pkg/multicloud/huaweistack/shell/business.go +++ b/pkg/multicloud/huaweistack/shell/skus.go @@ -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 }) } diff --git a/pkg/multicloud/huaweistack/storagecache.go b/pkg/multicloud/huaweistack/storagecache.go index 25a7a222bf..b8f2bb4c13 100644 --- a/pkg/multicloud/huaweistack/storagecache.go +++ b/pkg/multicloud/huaweistack/storagecache.go @@ -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) { diff --git a/pkg/multicloud/openstack/flavor.go b/pkg/multicloud/openstack/flavor.go index 1d5213bef2..abc19322a4 100644 --- a/pkg/multicloud/openstack/flavor.go +++ b/pkg/multicloud/openstack/flavor.go @@ -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) } diff --git a/pkg/multicloud/zstack/offering.go b/pkg/multicloud/zstack/offering.go index 5c5d11e356..f6d0839eb1 100644 --- a/pkg/multicloud/zstack/offering.go +++ b/pkg/multicloud/zstack/offering.go @@ -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 }