Merge pull request #803 in YUNIONIO/onecloud from ~QIUJIAN/onecloud:hotfix/qj-resolve-conflict-2.4.0-20181220 to release/2.4.0

* commit '8c65ead4b873f4b63ede4840f5bc82d5ae9196f0':
  腾讯云支持余额查询
  cloudaccount增加更多统计信息
  添加cloudaccount项目信息
This commit is contained in:
邱剑
2018-12-21 11:08:18 +08:00
11 changed files with 184 additions and 14 deletions
+1
View File
@@ -23,6 +23,7 @@ type ICloudProvider interface {
GetId() string
GetName() string
GetSysInfo() (jsonutils.JSONObject, error)
GetVersion() string
IsPublicCloud() bool
IsOnPremiseInfrastructure() bool
+125 -9
View File
@@ -51,9 +51,7 @@ type SCloudaccount struct {
BalanceKey string `width:"256" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"`
LastSync time.Time `get:"admin" list:"admin"` // = Column(DateTime, nullable=True)
Version string `width:"32" charset:"ascii" nullable:"true" list:"admin"` // Column(VARCHAR(32, charset='ascii'), nullable=True)
Sysinfo jsonutils.JSONObject `get:"admin"` // Column(JSONEncodedDict, nullable=True)
// Sysinfo jsonutils.JSONObject `get:"admin"` // Column(JSONEncodedDict, nullable=True)
Provider string `width:"64" charset:"ascii" list:"admin" create:"admin_required"`
}
@@ -502,12 +500,12 @@ func getSubAccounts(name, accessUrl, account, secret, provider string) ([]cloudp
return iprovider.GetSubAccounts()
}
func (self *SCloudaccount) SaveSysInfo(info jsonutils.JSONObject) {
/*func (self *SCloudaccount) SaveSysInfo(info jsonutils.JSONObject) {
self.GetModelManager().TableSpec().Update(self, func() error {
self.Sysinfo = info
return nil
})
}
}*/
func (manager *SCloudaccountManager) FetchCloudaccountById(accountId string) *SCloudaccount {
providerObj, err := manager.FetchById(accountId)
@@ -529,10 +527,113 @@ func (manager *SCloudaccountManager) FetchCloudaccountByIdOrName(accountId strin
return providerObj.(*SCloudaccount)
}
func (self *SCloudaccount) getProviderCount() int {
q := CloudproviderManager.Query().Equals("cloudaccount_id", self.Id)
return q.Count()
}
func (self *SCloudaccount) getHostCount() int {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := HostManager.Query().In("manager_id", subq)
return q.Count()
}
func (self *SCloudaccount) getVpcCount() int {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := VpcManager.Query().In("manager_id", subq)
return q.Count()
}
func (self *SCloudaccount) getStorageCount() int {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := StorageManager.Query().In("manager_id", subq)
return q.Count()
}
func (self *SCloudaccount) getStoragecacheCount() int {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := StoragecacheManager.Query().In("manager_id", subq)
return q.Count()
}
func (self *SCloudaccount) getEipCount() int {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := ElasticipManager.Query().In("manager_id", subq)
return q.Count()
}
func (self *SCloudaccount) getRoutetableCount() int {
subq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
q := RouteTableManager.Query().In("manager_id", subq)
return q.Count()
}
func (self *SCloudaccount) getGuestCount() int {
subsubq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
subq := HostManager.Query("id").In("manager_id", subsubq).SubQuery()
q := GuestManager.Query().In("host_id", subq)
return q.Count()
}
func (self *SCloudaccount) getDiskCount() int {
subsubq := CloudproviderManager.Query("id").Equals("cloudaccount_id", self.Id).SubQuery()
subq := StorageManager.Query("id").In("manager_id", subsubq).SubQuery()
q := DiskManager.Query().In("storage_id", subq)
return q.Count()
}
func (self *SCloudaccount) getProjectIds() []string {
q := CloudproviderManager.Query("tenant_id").Equals("cloudaccount_id", self.Id).Distinct()
rows, err := q.Rows()
if err != nil {
return nil
}
ret := make([]string, 0)
for rows.Next() {
var projId string
err := rows.Scan(&projId)
if err != nil {
return nil
}
ret = append(ret, projId)
}
return ret
}
func (self *SCloudaccount) getVersion() string {
q := CloudproviderManager.Query("version").Equals("cloudaccount_id", self.Id).Distinct()
rows, err := q.Rows()
if err != nil {
return ""
}
ret := make([]string, 0)
for rows.Next() {
var projId string
err := rows.Scan(&projId)
if err != nil {
return ""
}
ret = append(ret, projId)
}
return strings.Join(ret, ",")
}
func (self *SCloudaccount) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
providers := self.GetCloudproviders()
extra.Add(jsonutils.NewInt(int64(len(providers))), "account_count")
extra.Add(jsonutils.Marshal(providers), "accounts")
extra.Add(jsonutils.NewInt(int64(self.getProviderCount())), "provider_count")
extra.Add(jsonutils.NewInt(int64(self.getHostCount())), "host_count")
extra.Add(jsonutils.NewInt(int64(self.getGuestCount())), "guest_count")
extra.Add(jsonutils.NewInt(int64(self.getDiskCount())), "disk_count")
extra.Add(jsonutils.NewString(self.getVersion()), "version")
projects := jsonutils.NewArray()
for _, projectId := range self.getProjectIds() {
if proj, _ := db.TenantCacheManager.FetchTenantById(context.Background(), projectId); proj != nil {
projJson := jsonutils.NewDict()
projJson.Add(jsonutils.NewString(proj.Name), "tenant")
projJson.Add(jsonutils.NewString(proj.Id), "tenant_id")
projects.Add(projJson)
}
}
extra.Add(projects, "projects")
return extra
}
@@ -578,7 +679,7 @@ func migrateCloudprovider(cloudprovider *SCloudprovider) error {
account.AccessUrl = cloudprovider.AccessUrl
account.Account = mainAccount
account.LastSync = cloudprovider.LastSync
account.Sysinfo = cloudprovider.Sysinfo
// account.Sysinfo = cloudprovider.Sysinfo
account.Provider = cloudprovider.Provider
account.Name = providerName
account.Status = cloudprovider.Status
@@ -704,3 +805,18 @@ func (self *SCloudaccount) GetVCenterAccessInfo(privateId string) (SVCenterAcces
return info, nil
}
func (self *SCloudaccount) AllowPerformChangeProject(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsAdminAllowPerform(userCred, self, "change-project")
}
func (self *SCloudaccount) PerformChangeProject(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
providers := self.GetCloudproviders()
if len(providers) > 1 {
return nil, httperrors.NewInvalidStatusError("multiple subaccounts")
}
if len(providers) == 0 {
return nil, httperrors.NewInvalidStatusError("no subaccount")
}
return providers[0].PerformChangeProject(ctx, userCred, query, data)
}
+2 -1
View File
@@ -450,9 +450,10 @@ func (self *SCloudprovider) GetCloudaccount() *SCloudaccount {
return CloudaccountManager.FetchCloudaccountById(self.CloudaccountId)
}
func (self *SCloudprovider) SaveSysInfo(info jsonutils.JSONObject) {
func (self *SCloudprovider) SaveSysInfo(info jsonutils.JSONObject, version string) {
self.GetModelManager().TableSpec().Update(self, func() error {
self.Sysinfo = info
self.Version = version
return nil
})
}
@@ -60,13 +60,14 @@ func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStand
return
}
version := driver.GetVersion()
sysinfo, err := driver.GetSysInfo()
if err != nil {
reason := fmt.Sprintf("provider get sysinfo error %s", err)
taskFail(ctx, self, provider, reason)
return
} else {
provider.SaveSysInfo(sysinfo)
provider.SaveSysInfo(sysinfo, version)
}
syncRangeJson, _ := self.Params.Get("sync_range")
+4
View File
@@ -79,6 +79,10 @@ func (self *SAliyunProvider) GetSysInfo() (jsonutils.JSONObject, error) {
return info, nil
}
func (self *SAliyunProvider) GetVersion() string {
return aliyun.ALIYUN_API_VERSION
}
func (self *SAliyunProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
return self.client.GetSubAccounts()
}
+4
View File
@@ -58,6 +58,10 @@ func (self *SAwsProvider) GetSysInfo() (jsonutils.JSONObject, error) {
return info, nil
}
func (self *SAwsProvider) GetVersion() string {
return aws.AWS_API_VERSION
}
func (self *SAwsProvider) IsPublicCloud() bool {
return true
}
+4
View File
@@ -61,6 +61,10 @@ func (self *SAzureProvider) GetSysInfo() (jsonutils.JSONObject, error) {
return info, nil
}
func (self *SAzureProvider) GetVersion() string {
return azure.AZURE_API_VERSION
}
func (self *SAzureProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
return self.client.GetSubAccounts()
}
+4
View File
@@ -106,6 +106,10 @@ func (cli *SESXiClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
return []cloudprovider.SSubAccount{subAccount}, nil
}
func (cli *SESXiClient) GetVersion() string {
return cli.client.ServiceContent.About.Version
}
func (cli *SESXiClient) About() jsonutils.JSONObject {
about := jsonutils.Marshal(&cli.client.ServiceContent.About)
aboutDict := about.(*jsonutils.JSONDict)
+4
View File
@@ -88,6 +88,10 @@ func (self *SESXiProvider) GetSysInfo() (jsonutils.JSONObject, error) {
return self.client.About(), nil
}
func (self *SESXiProvider) GetVersion() string {
return self.client.GetVersion()
}
func (self *SESXiProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
return self.client.GetSubAccounts()
}
+9 -1
View File
@@ -64,6 +64,10 @@ func (self *SQcloudProvider) GetSysInfo() (jsonutils.JSONObject, error) {
return info, nil
}
func (self *SQcloudProvider) GetVersion() string {
return qcloud.QCLOUD_API_VERSION
}
func (self *SQcloudProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) {
return self.client.GetSubAccounts()
}
@@ -77,7 +81,11 @@ func (self *SQcloudProvider) GetIRegionById(id string) (cloudprovider.ICloudRegi
}
func (self *SQcloudProvider) GetBalance() (float64, error) {
return 0.0, nil
balance, err := self.client.QueryAccountBalance()
if err != nil {
return 0.0, err
}
return balance.AvailableAmount, nil
}
func (self *SQcloudProvider) GetOnPremiseIRegion() (cloudprovider.ICloudRegion, error) {
+25 -2
View File
@@ -22,7 +22,8 @@ const (
QCLOUD_DEFAULT_REGION = "ap-beijing"
QCLOUD_API_VERSION = "2017-03-12"
QCLOUD_API_VERSION = "2017-03-12"
QCLOUD_BILLING_API_VERSION = "2018-07-09"
)
type SQcloudClient struct {
@@ -71,6 +72,11 @@ func cbsRequest(client *common.Client, apiName string, params map[string]string)
return _jsonRequest(client, domain, QCLOUD_API_VERSION, apiName, params)
}
func billingRequest(client *common.Client, apiName string, params map[string]string) (jsonutils.JSONObject, error) {
domain := "billing.tencentcloudapi.com"
return _jsonRequest(client, domain, QCLOUD_BILLING_API_VERSION, apiName, params)
}
type QcloudResponse struct {
*tchttp.BaseResponse
Response *interface{} `json:"Response"`
@@ -147,6 +153,14 @@ func (client *SQcloudClient) cbsRequest(apiName string, params map[string]string
return cbsRequest(cli, apiName, params)
}
func (client *SQcloudClient) billingRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
cli, err := client.getDefaultClient()
if err != nil {
return nil, err
}
return billingRequest(cli, apiName, params)
}
func (client *SQcloudClient) jsonRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
cli, err := client.getDefaultClient()
if err != nil {
@@ -264,5 +278,14 @@ type SAccountBalance struct {
}
func (client *SQcloudClient) QueryAccountBalance() (*SAccountBalance, error) {
return nil, nil
balance := SAccountBalance{}
body, err := client.billingRequest("DescribeAccountBalance", nil)
if err != nil {
log.Errorf("DescribeAccountBalance fail %s", err)
return nil, err
}
log.Debugf("%s", body)
balanceCent, _ := body.Float("Balance")
balance.AvailableAmount = balanceCent / 100.0
return &balance, nil
}