mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
fix balance permission error
This commit is contained in:
@@ -39,17 +39,19 @@ const (
|
||||
CLOUD_PROVIDER_UCLOUD = "Ucloud"
|
||||
CLOUD_PROVIDER_ZSTACK = "ZStack"
|
||||
|
||||
CLOUD_PROVIDER_HEALTH_NORMAL = "normal" // 远端处于健康状态
|
||||
CLOUD_PROVIDER_HEALTH_INSUFFICIENT = "insufficient" // 不足按需资源余额
|
||||
CLOUD_PROVIDER_HEALTH_SUSPENDED = "suspended" // 远端处于冻结状态
|
||||
CLOUD_PROVIDER_HEALTH_ARREARS = "arrears" // 远端处于欠费状态
|
||||
CLOUD_PROVIDER_HEALTH_UNKNOWN = "unknown" // 未知状态,查询失败
|
||||
CLOUD_PROVIDER_HEALTH_NORMAL = "normal" // 远端处于健康状态
|
||||
CLOUD_PROVIDER_HEALTH_INSUFFICIENT = "insufficient" // 不足按需资源余额
|
||||
CLOUD_PROVIDER_HEALTH_SUSPENDED = "suspended" // 远端处于冻结状态
|
||||
CLOUD_PROVIDER_HEALTH_ARREARS = "arrears" // 远端处于欠费状态
|
||||
CLOUD_PROVIDER_HEALTH_UNKNOWN = "unknown" // 未知状态,查询失败
|
||||
CLOUD_PROVIDER_HEALTH_NO_PERMISSION = "no permission" // 没有权限获取账单信息
|
||||
|
||||
ZSTACK_BRAND_DSTACK = "DStack"
|
||||
)
|
||||
|
||||
var (
|
||||
CLOUD_PROVIDER_VALID_STATUS = []string{CLOUD_PROVIDER_CONNECTED}
|
||||
CLOUD_PROVIDER_VALID_STATUS = []string{CLOUD_PROVIDER_CONNECTED}
|
||||
CLOUD_PROVIDER_VALID_HEALTH_STATUS = []string{CLOUD_PROVIDER_HEALTH_NORMAL, CLOUD_PROVIDER_HEALTH_NO_PERMISSION}
|
||||
|
||||
CLOUD_PROVIDERS = []string{
|
||||
CLOUD_PROVIDER_ONECLOUD,
|
||||
|
||||
@@ -34,3 +34,4 @@ var ErrTimeout = errors.New("timeout")
|
||||
var ErrNotImplemented = errors.New("Not implemented")
|
||||
var ErrNotSupported = errors.New("Not supported")
|
||||
var ErrInvalidProvider = errors.New("Invalid provider")
|
||||
var ErrNoBalancePermission = errors.New("No balance permission")
|
||||
|
||||
@@ -510,7 +510,7 @@ func (image *SCachedimage) getValidStoragecache() []SStoragecache {
|
||||
q = q.Join(storagecacheimages, sqlchemy.Equals(storagecaches.Field("id"), storagecacheimages.Field("storagecache_id")))
|
||||
q = q.Filter(sqlchemy.IsTrue(providers.Field("enabled")))
|
||||
q = q.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
|
||||
q = q.Filter(sqlchemy.Equals(providers.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
|
||||
q = q.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
|
||||
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("cachedimage_id"), image.Id))
|
||||
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("status"), api.CACHED_IMAGE_STATUS_READY))
|
||||
|
||||
|
||||
@@ -1204,11 +1204,14 @@ func (account *SCloudaccount) probeAccountStatus(ctx context.Context, userCred m
|
||||
}
|
||||
balance, status, err := manager.GetBalance()
|
||||
if err != nil {
|
||||
if err != cloudprovider.ErrNotSupported {
|
||||
switch err {
|
||||
case cloudprovider.ErrNotSupported:
|
||||
status = api.CLOUD_PROVIDER_HEALTH_NORMAL
|
||||
case cloudprovider.ErrNoBalancePermission:
|
||||
status = api.CLOUD_PROVIDER_HEALTH_NO_PERMISSION
|
||||
default:
|
||||
log.Errorf("manager.GetBalance %s fail %s", account.Name, err)
|
||||
status = api.CLOUD_PROVIDER_HEALTH_UNKNOWN
|
||||
} else {
|
||||
status = api.CLOUD_PROVIDER_HEALTH_NORMAL
|
||||
}
|
||||
}
|
||||
version := manager.GetVersion()
|
||||
|
||||
@@ -542,7 +542,7 @@ func (manager *SCloudregionManager) ListItemFilter(ctx context.Context, q *sqlch
|
||||
}
|
||||
sq = sq.Filter(sqlchemy.IsTrue(providers.Field("enabled")))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
|
||||
sq = sq.Filter(sqlchemy.Equals(providers.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
|
||||
if usableVpc {
|
||||
sq = sq.Filter(sqlchemy.Equals(vpcs.Field("status"), api.VPC_STATUS_AVAILABLE))
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ func (manager *SHostManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu
|
||||
hostQ1 = hostQ1.Join(networks, sqlchemy.Equals(hostwires.Field("wire_id"), networks.Field("wire_id")))
|
||||
hostQ1 = hostQ1.Filter(sqlchemy.IsTrue(providers.Field("enabled")))
|
||||
hostQ1 = hostQ1.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
|
||||
hostQ1 = hostQ1.Filter(sqlchemy.Equals(providers.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
|
||||
hostQ1 = hostQ1.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
|
||||
hostQ1 = hostQ1.Filter(sqlchemy.Equals(networks.Field("status"), api.NETWORK_STATUS_AVAILABLE))
|
||||
hostQ1 = hostQ1.Filter(sqlchemy.IsTrue(hosts.Field("enabled")))
|
||||
|
||||
|
||||
@@ -493,7 +493,7 @@ func networkUsableRegionQueries(f sqlchemy.IQueryField) []sqlchemy.ICondition {
|
||||
sq = sq.Filter(sqlchemy.Equals(networks.Field("status"), api.NETWORK_STATUS_AVAILABLE))
|
||||
sq = sq.Filter(sqlchemy.IsTrue(providers.Field("enabled")))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
|
||||
sq = sq.Filter(sqlchemy.Equals(providers.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
|
||||
sq = sq.Filter(sqlchemy.Equals(vpcs.Field("status"), api.VPC_STATUS_AVAILABLE))
|
||||
|
||||
sq2 := vpcs.Query(sqlchemy.DISTINCT("cloudregion_id", vpcs.Field("cloudregion_id")))
|
||||
@@ -518,7 +518,7 @@ func providerFilter(q *sqlchemy.SQuery, provider string, public_cloud bool) *sql
|
||||
subq = subq.Join(providerTable, sqlchemy.Equals(providerRegionTable.Field("cloudprovider_id"), providerTable.Field("id")))
|
||||
subq = subq.Filter(sqlchemy.IsTrue(providerTable.Field("enabled")))
|
||||
subq = subq.Filter(sqlchemy.In(providerTable.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
|
||||
subq = subq.Filter(sqlchemy.Equals(providerTable.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
|
||||
subq = subq.Filter(sqlchemy.In(providerTable.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
|
||||
q = q.Filter(sqlchemy.In(q.Field("cloudregion_id"), subq.SubQuery()))
|
||||
}
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ func usableZoneQ1(providers, vpcs, wires, networks *sqlchemy.SSubQuery, usableNe
|
||||
sq = sq.Filter(sqlchemy.IsNotEmpty(wires.Field("zone_id")))
|
||||
sq = sq.Filter(sqlchemy.IsTrue(providers.Field("enabled")))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
|
||||
sq = sq.Filter(sqlchemy.Equals(providers.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
|
||||
if usableVpc {
|
||||
sq = sq.Filter(sqlchemy.Equals(vpcs.Field("status"), api.VPC_STATUS_AVAILABLE))
|
||||
}
|
||||
@@ -491,7 +491,7 @@ func usableZoneQ3(providers, vpcs, wires, networks, zones *sqlchemy.SSubQuery, u
|
||||
sq = sq.Filter(sqlchemy.IsNullOrEmpty(wires.Field("zone_id")))
|
||||
sq = sq.Filter(sqlchemy.IsTrue(providers.Field("enabled")))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
|
||||
sq = sq.Filter(sqlchemy.Equals(providers.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
|
||||
sq = sq.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
|
||||
if usableVpc {
|
||||
sq = sq.Filter(sqlchemy.Equals(vpcs.Field("status"), api.VPC_STATUS_AVAILABLE))
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ func (p *StatusPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []core
|
||||
if !utils.IsInStringArray(cloudprovider.Status, api.CLOUD_PROVIDER_VALID_STATUS) {
|
||||
h.Exclude2("cloud_provider_status", cloudprovider.Status, api.CLOUD_PROVIDER_VALID_STATUS)
|
||||
}
|
||||
if cloudprovider.HealthStatus != api.CLOUD_PROVIDER_HEALTH_NORMAL {
|
||||
h.Exclude2("cloud_provider_health_status", cloudprovider.HealthStatus, api.CLOUD_PROVIDER_HEALTH_NORMAL)
|
||||
if !utils.IsInStringArray(cloudprovider.HealthStatus, api.CLOUD_PROVIDER_VALID_HEALTH_STATUS) {
|
||||
h.Exclude2("cloud_provider_health_status", cloudprovider.HealthStatus, api.CLOUD_PROVIDER_VALID_HEALTH_STATUS)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ package aliyun
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
@@ -66,14 +68,15 @@ type SPrepaidCard struct {
|
||||
func (self *SAliyunClient) QueryAccountBalance() (*SAccountBalance, error) {
|
||||
body, err := self.businessRequest("QueryAccountBalance", nil)
|
||||
if err != nil {
|
||||
log.Errorf("QueryAccountBalance fail %s", err)
|
||||
return nil, err
|
||||
if isError(err, "NotApplicable") {
|
||||
return nil, cloudprovider.ErrNoBalancePermission
|
||||
}
|
||||
return nil, errors.Wrapf(err, "QueryAccountBalance")
|
||||
}
|
||||
balance := SAccountBalance{}
|
||||
err = body.Unmarshal(&balance, "Data")
|
||||
if err != nil {
|
||||
log.Errorf("Unmarshal AccountBalance fail %s", err)
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "Unmarshal AccountBalance")
|
||||
}
|
||||
return &balance, nil
|
||||
}
|
||||
|
||||
@@ -540,6 +540,9 @@ func (client *SQcloudClient) QueryAccountBalance() (*SAccountBalance, error) {
|
||||
balance := SAccountBalance{}
|
||||
body, err := client.billingRequest("DescribeAccountBalance", nil)
|
||||
if err != nil {
|
||||
if isError(err, []string{"UnauthorizedOperation.NotFinanceAuth"}) {
|
||||
return nil, cloudprovider.ErrNoBalancePermission
|
||||
}
|
||||
log.Errorf("DescribeAccountBalance fail %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -799,3 +799,7 @@ func (self *SRegion) GetInstanceStatus(instanceId string) (string, error) {
|
||||
}
|
||||
return instance.InstanceState, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) QueryAccountBalance() (*SAccountBalance, error) {
|
||||
return self.client.QueryAccountBalance()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/util/qcloud"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type BalanceOptions struct {
|
||||
}
|
||||
shellutils.R(&BalanceOptions{}, "balance-show", "Show balance", func(cli *qcloud.SRegion, args *BalanceOptions) error {
|
||||
balance, err := cli.QueryAccountBalance()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(balance)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user