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:
Zexi Li
2021-08-12 15:43:25 +08:00
committed by GitHub
36 changed files with 137 additions and 622 deletions
+1
View File
@@ -755,6 +755,7 @@ type ICloudSku interface {
GetPrepaidStatus() string
GetPostpaidStatus() string
GetCpuArch() string
GetCpuCoreCount() int
GetMemorySizeMB() int
+5 -1
View File
@@ -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
}
+2 -2
View File
@@ -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)
+4 -3
View File
@@ -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 {
+4 -4
View File
@@ -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)
})
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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)
}
+1
View File
@@ -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()
+1 -1
View File
@@ -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)
}
+4
View File
@@ -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
+4
View File
@@ -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)
}
+1
View File
@@ -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
}
+9 -1
View File
@@ -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")
}
+3 -11
View File
@@ -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
}
+1 -26
View File
@@ -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
}
+4 -46
View File
@@ -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
}
+7 -8
View File
@@ -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)
+2 -85
View File
@@ -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
}
+11 -11
View File
@@ -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
-123
View File
@@ -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
}
+13 -30
View File
@@ -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"`
-36
View File
@@ -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
})
}
@@ -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
})
}
+35 -13
View File
@@ -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) {
+4
View File
@@ -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)
}
+4
View File
@@ -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
}