Merge pull request #1196 from ioito/hotfix/qx-cloudprovider-health-status

fix balance permission error
This commit is contained in:
yunion-ci-robot
2019-06-15 21:19:52 +08:00
committed by GitHub
13 changed files with 71 additions and 22 deletions
+8 -6
View File
@@ -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,
+1
View File
@@ -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")
+1 -1
View File
@@ -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))
+6 -3
View File
@@ -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()
+1 -1
View File
@@ -567,7 +567,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))
}
+1 -1
View File
@@ -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")))
+2 -2
View File
@@ -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()))
}
+2 -2
View File
@@ -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)
}
}
+7 -4
View File
@@ -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
}
+3
View File
@@ -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
}
+4
View File
@@ -807,3 +807,7 @@ func (self *SRegion) GetInstanceStatus(instanceId string) (string, error) {
}
return instance.InstanceState, nil
}
func (self *SRegion) QueryAccountBalance() (*SAccountBalance, error) {
return self.client.QueryAccountBalance()
}
+33
View File
@@ -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
})
}