mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
Merge pull request #5590 from ioito/feature/qx-public-cloud-quota
fix: 支持同步云平台配额信息
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
// 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/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type CloudproviderQuotaListOptions struct {
|
||||
options.BaseListOptions
|
||||
Cloudregion string `help:"ID or Name of Cloudregion"`
|
||||
QuotaType string `help:"Quota type"`
|
||||
QuotaRange string `help:"Quota range" choices:"cloudregion|cloudprovider"`
|
||||
}
|
||||
|
||||
R(&CloudproviderQuotaListOptions{}, "cloud-provider-quota-list", "List cloudprovider quota", func(s *mcclient.ClientSession, args *CloudproviderQuotaListOptions) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args.QuotaType) > 0 {
|
||||
params.Add(jsonutils.NewString(args.QuotaType), "quota_type")
|
||||
}
|
||||
|
||||
if len(args.QuotaRange) > 0 {
|
||||
params.Add(jsonutils.NewString(args.QuotaRange), "quota_range")
|
||||
}
|
||||
|
||||
if len(args.Cloudregion) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Cloudregion), "cloudregion")
|
||||
}
|
||||
|
||||
result, err := modules.CloudproviderQuotas.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printList(result, modules.CloudproviderQuotas.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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 compute
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
|
||||
const (
|
||||
CLOUD_PROVIDER_QUOTA_RANGE_CLOUDREGION = "cloudregion"
|
||||
CLOUD_PROVIDER_QUOTA_RANGE_CLOUDPROVIDER = "cloudprovider"
|
||||
)
|
||||
|
||||
type CloudproviderQuotaListInput struct {
|
||||
apis.StandaloneResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
|
||||
ManagedResourceListInput
|
||||
RegionalFilterListInput
|
||||
|
||||
// 配额类型
|
||||
QuotaType string `json:"quota_type"`
|
||||
|
||||
// 配额范围
|
||||
QuotaRange string `json:"quota_range"`
|
||||
}
|
||||
@@ -202,6 +202,7 @@ type ICloudProvider interface {
|
||||
GetStorageClasses(regionId string) []string
|
||||
|
||||
GetCapabilities() []string
|
||||
GetICloudQuotas() ([]ICloudQuota, error)
|
||||
}
|
||||
|
||||
func IsSupportProject(prod ICloudProvider) bool {
|
||||
@@ -301,6 +302,10 @@ func (self *SBaseProvider) GetOnPremiseIRegion() (ICloudRegion, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SBaseProvider) GetICloudQuotas() ([]ICloudQuota, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SBaseProvider) GetCloudRegionExternalIdPrefix() string {
|
||||
return self.factory.GetId()
|
||||
}
|
||||
|
||||
@@ -139,6 +139,8 @@ type ICloudRegion interface {
|
||||
GetICloudEvents(start time.Time, end time.Time, withReadEvent bool) ([]ICloudEvent, error) //获取公有云操作日志接口
|
||||
|
||||
GetCapabilities() []string
|
||||
|
||||
GetICloudQuotas() ([]ICloudQuota, error)
|
||||
}
|
||||
|
||||
type ICloudZone interface {
|
||||
@@ -940,3 +942,11 @@ type ICloudEvent interface {
|
||||
|
||||
GetCreatedAt() time.Time
|
||||
}
|
||||
|
||||
type ICloudQuota interface {
|
||||
GetGlobalId() string
|
||||
GetDesc() string
|
||||
GetQuotaType() string
|
||||
GetMaxQuotaCount() int
|
||||
GetCurrentQuotaUsedCount() int
|
||||
}
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
// 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 models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SCloudproviderQuotaManager struct {
|
||||
db.SStandaloneResourceBaseManager
|
||||
db.SExternalizedResourceBaseManager
|
||||
SManagedResourceBaseManager
|
||||
SCloudregionResourceBaseManager
|
||||
}
|
||||
|
||||
var CloudproviderQuotaManager *SCloudproviderQuotaManager
|
||||
|
||||
func init() {
|
||||
CloudproviderQuotaManager = &SCloudproviderQuotaManager{
|
||||
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
|
||||
SCloudproviderQuota{},
|
||||
"cloudprovider_quotas_tbl",
|
||||
"cloudproviderquota",
|
||||
"cloudproviderquotas",
|
||||
),
|
||||
}
|
||||
CloudproviderQuotaManager.SetVirtualObject(CloudproviderQuotaManager)
|
||||
}
|
||||
|
||||
type SCloudproviderQuota struct {
|
||||
db.SStandaloneResourceBase
|
||||
db.SExternalizedResourceBase
|
||||
SManagedResourceBase
|
||||
SCloudregionResourceBase
|
||||
|
||||
// 配额范围
|
||||
// cloudregion: 区域级别
|
||||
// cloudprovider: 云订阅级别
|
||||
QuotaRange string `width:"32" charset:"ascii" list:"user"`
|
||||
|
||||
// 已使用的配额
|
||||
// -1代表未从云平台拿到已使用配额信息
|
||||
UsedCount int `nullable:"false" default:"0" list:"user"`
|
||||
|
||||
// 最大配额限制
|
||||
MaxCount int `nullable:"false" default:"0" list:"user"`
|
||||
|
||||
// 配额类型
|
||||
QuotaType string `width:"32" charset:"ascii" list:"user"`
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderQuotaManager) GetContextManagers() [][]db.IModelManager {
|
||||
return [][]db.IModelManager{
|
||||
{CloudproviderManager},
|
||||
}
|
||||
}
|
||||
|
||||
func (man *SCloudproviderQuotaManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query api.CloudproviderQuotaListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
|
||||
var err error
|
||||
q, err = man.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = man.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = man.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = man.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
|
||||
if len(query.QuotaType) > 0 {
|
||||
q = q.Equals("quota_type", query.QuotaType)
|
||||
}
|
||||
if len(query.QuotaRange) > 0 {
|
||||
q = q.Equals("quota_range", query.QuotaRange)
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (man *SCloudproviderQuotaManager) OrderByExtraFields(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query api.CloudproviderQuotaListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
q, err := man.SStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = man.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = man.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (man *SCloudproviderQuotaManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
q, err := man.SStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = man.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = man.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
return q, httperrors.ErrNotFound
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderQuotaManager) GetQuotas(provider *SCloudprovider, region *SCloudregion, quotaRange string) ([]SCloudproviderQuota, error) {
|
||||
q := manager.Query()
|
||||
if provider != nil {
|
||||
q = q.Equals("manager_id", provider.Id)
|
||||
}
|
||||
if region != nil {
|
||||
q = q.Equals("cloudregion_id", region.Id)
|
||||
}
|
||||
if len(quotaRange) > 0 {
|
||||
q = q.Equals("quota_range", quotaRange)
|
||||
}
|
||||
quotas := []SCloudproviderQuota{}
|
||||
err := db.FetchModelObjects(manager, q, "as)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return quotas, nil
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderQuotaManager) SyncQuotas(ctx context.Context, userCred mcclient.TokenCredential, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider, region *SCloudregion, quotaRange string, iQuotas []cloudprovider.ICloudQuota) compare.SyncResult {
|
||||
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, provider.GetOwnerId()))
|
||||
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, provider.GetOwnerId()))
|
||||
result := compare.SyncResult{}
|
||||
|
||||
dbQuotas, err := manager.GetQuotas(provider, region, quotaRange)
|
||||
if err != nil {
|
||||
result.Error(err)
|
||||
return result
|
||||
}
|
||||
|
||||
removed := make([]SCloudproviderQuota, 0)
|
||||
commondb := make([]SCloudproviderQuota, 0)
|
||||
commonext := make([]cloudprovider.ICloudQuota, 0)
|
||||
added := make([]cloudprovider.ICloudQuota, 0)
|
||||
err = compare.CompareSets(dbQuotas, iQuotas, &removed, &commondb, &commonext, &added)
|
||||
if err != nil {
|
||||
result.Error(err)
|
||||
return result
|
||||
}
|
||||
|
||||
for i := 0; i < len(removed); i++ {
|
||||
err := removed[i].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
result.DeleteError(err)
|
||||
} else {
|
||||
result.Delete()
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(commondb); i++ {
|
||||
err := commondb[i].SyncWithCloudQuota(ctx, userCred, commonext[i])
|
||||
if err != nil {
|
||||
result.UpdateError(err)
|
||||
continue
|
||||
}
|
||||
result.Update()
|
||||
}
|
||||
|
||||
for i := 0; i < len(added); i++ {
|
||||
err = manager.newFromCloudQuota(ctx, userCred, provider, region, quotaRange, added[i])
|
||||
if err != nil {
|
||||
result.AddError(err)
|
||||
continue
|
||||
}
|
||||
result.Add()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (self *SCloudproviderQuota) SyncWithCloudQuota(ctx context.Context, userCred mcclient.TokenCredential, iQuota cloudprovider.ICloudQuota) error {
|
||||
_, err := db.UpdateWithLock(ctx, self, func() error {
|
||||
self.UsedCount = iQuota.GetCurrentQuotaUsedCount()
|
||||
self.MaxCount = iQuota.GetMaxQuotaCount()
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderQuotaManager) newFromCloudQuota(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, region *SCloudregion, quotaRange string, iQuota cloudprovider.ICloudQuota) error {
|
||||
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
|
||||
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
|
||||
|
||||
quota := SCloudproviderQuota{}
|
||||
quota.SetModelManager(manager, "a)
|
||||
|
||||
quota.Name = iQuota.GetQuotaType()
|
||||
quota.Description = iQuota.GetDesc()
|
||||
quota.ExternalId = iQuota.GetGlobalId()
|
||||
quota.ManagerId = provider.Id
|
||||
quota.QuotaType = iQuota.GetQuotaType()
|
||||
quota.QuotaRange = quotaRange
|
||||
quota.UsedCount = iQuota.GetCurrentQuotaUsedCount()
|
||||
quota.MaxCount = iQuota.GetMaxQuotaCount()
|
||||
if region != nil {
|
||||
quota.CloudregionId = region.Id
|
||||
}
|
||||
|
||||
return manager.TableSpec().Insert("a)
|
||||
}
|
||||
@@ -1287,6 +1287,7 @@ func (self *SCloudprovider) RealDelete(ctx context.Context, userCred mcclient.To
|
||||
CloudproviderRegionManager,
|
||||
ExternalProjectManager,
|
||||
CloudregionManager,
|
||||
CloudproviderQuotaManager,
|
||||
} {
|
||||
err = manager.purgeAll(ctx, userCred, self.Id)
|
||||
if err != nil {
|
||||
|
||||
@@ -87,6 +87,24 @@ func isInCache(pairs []sStoragecacheSyncPair, localCacheId string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func syncRegionQuotas(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, driver cloudprovider.ICloudProvider, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
|
||||
quotas, err := remoteRegion.GetICloudQuotas()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetICloudQuotas for region %s failed %s", remoteRegion.GetName(), err)
|
||||
log.Errorf(msg)
|
||||
return err
|
||||
}
|
||||
result := CloudproviderQuotaManager.SyncQuotas(ctx, userCred, provider.GetOwnerId(), provider, localRegion, api.CLOUD_PROVIDER_QUOTA_RANGE_CLOUDREGION, quotas)
|
||||
syncResults.Add(CloudproviderQuotaManager, result)
|
||||
msg := result.Result()
|
||||
notes := fmt.Sprintf("SyncQuotas for region %s result: %s", localRegion.Name, msg)
|
||||
log.Infof(notes)
|
||||
if result.IsError() {
|
||||
return fmt.Errorf(msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncRegionZones(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) ([]SZone, []cloudprovider.ICloudZone, error) {
|
||||
zones, err := remoteRegion.GetIZones()
|
||||
if err != nil {
|
||||
@@ -1013,6 +1031,8 @@ func syncPublicCloudProviderInfo(
|
||||
syncProjects(ctx, userCred, syncResults, driver, provider)
|
||||
}
|
||||
|
||||
syncRegionQuotas(ctx, userCred, syncResults, driver, provider, localRegion, remoteRegion)
|
||||
|
||||
localZones, remoteZones, _ := syncRegionZones(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
|
||||
|
||||
if !driver.GetFactory().NeedSyncSkuFromCloud() {
|
||||
|
||||
@@ -1630,3 +1630,30 @@ func (manager *SSecurityGroupCacheManager) purgeAll(ctx context.Context, userCre
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (quota *SCloudproviderQuota) purge(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, quota)
|
||||
defer lockman.ReleaseObject(ctx, quota)
|
||||
|
||||
err := quota.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return quota.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderQuotaManager) purgeAll(ctx context.Context, userCred mcclient.TokenCredential, providerId string) error {
|
||||
quotas := []SCloudproviderQuota{}
|
||||
err := fetchByManagerId(manager, providerId, "as)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range quotas {
|
||||
err := quotas[i].purge(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
|
||||
models.GuestTemplateManager,
|
||||
models.ServiceCatalogManager,
|
||||
models.CloudproviderQuotaManager,
|
||||
} {
|
||||
db.RegisterModelManager(manager)
|
||||
handler := db.NewModelHandler(manager)
|
||||
|
||||
@@ -16,12 +16,17 @@ package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
@@ -59,18 +64,47 @@ func taskFail(ctx context.Context, task *CloudProviderSyncInfoTask, provider *mo
|
||||
task.SetStageFailed(ctx, reason)
|
||||
}
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
provider := obj.(*models.SCloudprovider)
|
||||
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNCING_HOST, "", self.UserCred)
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) GetSyncRange() models.SSyncRange {
|
||||
syncRange := models.SSyncRange{}
|
||||
syncRangeJson, _ := self.Params.Get("sync_range")
|
||||
if syncRangeJson != nil {
|
||||
syncRangeJson.Unmarshal(&syncRange)
|
||||
}
|
||||
syncRange.Normalize()
|
||||
return syncRange
|
||||
}
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
provider := obj.(*models.SCloudprovider)
|
||||
|
||||
self.SetStage("OnSyncCloudProviderQuotaInfoComplete", nil)
|
||||
|
||||
taskman.LocalTaskRun(self, func() (jsonutils.JSONObject, error) {
|
||||
p, err := provider.GetProvider()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetProvider")
|
||||
}
|
||||
quotas, err := p.GetICloudQuotas()
|
||||
if err != nil {
|
||||
if errors.Cause(err) != cloudprovider.ErrNotImplemented {
|
||||
return nil, errors.Wrap(err, "GetICloudQuotas")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
result := models.CloudproviderQuotaManager.SyncQuotas(ctx, self.GetUserCred(), provider.GetOwnerId(), provider, nil, api.CLOUD_PROVIDER_QUOTA_RANGE_CLOUDPROVIDER, quotas)
|
||||
msg := result.Result()
|
||||
notes := fmt.Sprintf("SyncQuotas for provider %s result: %s", provider.Name, msg)
|
||||
log.Infof(notes)
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderQuotaInfoComplete(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
provider := obj.(*models.SCloudprovider)
|
||||
syncRange := self.GetSyncRange()
|
||||
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNCING_HOST, "", self.UserCred)
|
||||
self.SetStage("OnSyncCloudProviderInfoComplete", nil)
|
||||
|
||||
taskman.LocalTaskRun(self, func() (jsonutils.JSONObject, error) {
|
||||
@@ -79,6 +113,11 @@ func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStand
|
||||
})
|
||||
}
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderQuotaInfoCompleteFailed(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
log.Errorf("faild to sync provider quotas %s", body.String())
|
||||
self.OnSyncCloudProviderQuotaInfoComplete(ctx, obj, body)
|
||||
}
|
||||
|
||||
func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderInfoComplete(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
|
||||
provider := obj.(*models.SCloudprovider)
|
||||
// provider.MarkEndSync(self.UserCred)
|
||||
@@ -87,86 +126,3 @@ func (self *CloudProviderSyncInfoTask) OnSyncCloudProviderInfoComplete(ctx conte
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, "", self.UserCred)
|
||||
logclient.AddActionLogWithStartable(self, provider, getAction(self.Params), body, self.UserCred, true)
|
||||
}
|
||||
|
||||
/*func logSyncFailed(provider *models.SCloudprovider, task taskman.ITask, reason string) {
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, reason, task.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(task, provider, getAction(task.GetParams()), reason, task.GetUserCred(), false)
|
||||
}
|
||||
|
||||
func syncCloudProviderInfo(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, driver cloudprovider.ICloudProvider, syncRange *models.SSyncRange) {
|
||||
notes := fmt.Sprintf("Start sync host info ...")
|
||||
log.Infof(notes)
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_START, "", task.UserCred)
|
||||
|
||||
if driver.GetFactory().IsOnPremise() {
|
||||
syncOnPremiseCloudProviderInfo(ctx, provider, task, driver, syncRange)
|
||||
} else {
|
||||
syncOutOfPremiseCloudProviderInfo(ctx, provider, task, driver, syncRange)
|
||||
}
|
||||
}
|
||||
|
||||
func syncOnPremiseCloudProviderInfo(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, driver cloudprovider.ICloudProvider, syncRange *models.SSyncRange) {
|
||||
cpr := models.CloudproviderRegionManager.FetchByIdsOrCreate(provider.Id, models.DEFAULT_REGION_ID)
|
||||
cpr.DoSync(ctx, task.UserCred, syncRange)
|
||||
}
|
||||
|
||||
func syncOutOfPremiseCloudProviderInfo(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, driver cloudprovider.ICloudProvider, syncRange *models.SSyncRange) {
|
||||
regions := driver.GetIRegions()
|
||||
|
||||
externalIdPrefix := driver.GetCloudRegionExternalIdPrefix()
|
||||
localRegions, _, cloudProviderRegions, result := models.CloudregionManager.SyncRegions(ctx, task.UserCred, provider, externalIdPrefix, regions)
|
||||
msg := result.Result()
|
||||
log.Infof("SyncRegion result: %s", msg)
|
||||
if result.IsError() {
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
|
||||
// logclient.AddActionLog(provider, getAction(task.Params), "", task.UserCred, true)
|
||||
for i := 0; i < len(localRegions); i += 1 {
|
||||
if len(syncRange.Region) > 0 && !utils.IsInStringArray(localRegions[i].Id, syncRange.Region) {
|
||||
continue
|
||||
}
|
||||
|
||||
cloudProviderRegions[i].DoSync(ctx, task.UserCred, syncRange)
|
||||
}
|
||||
}
|
||||
|
||||
func syncVMDisks(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, driver cloudprovider.ICloudProvider, host *models.SHost, localVM *models.SGuest, remoteVM cloudprovider.ICloudVM, syncRange *models.SSyncRange) {
|
||||
disks, err := remoteVM.GetIDisks()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetIDisks for VM %s failed %s", remoteVM.GetName(), err)
|
||||
log.Errorf(msg)
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
result := localVM.SyncVMDisks(ctx, task.UserCred, driver, host, disks, provider.ProjectId, syncRange.ProjectSync)
|
||||
msg := result.Result()
|
||||
notes := fmt.Sprintf("syncVMDisks for VM %s result: %s", localVM.Name, msg)
|
||||
log.Infof(notes)
|
||||
if result.IsError() {
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
|
||||
// logclient.AddActionLog(provider, getAction(task.Params), notes, task.UserCred, true)
|
||||
}
|
||||
|
||||
func syncVMEip(ctx context.Context, provider *models.SCloudprovider, task *CloudProviderSyncInfoTask, localVM *models.SGuest, remoteVM cloudprovider.ICloudVM) {
|
||||
eip, err := remoteVM.GetIEIP()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetIEIP for VM %s failed %s", remoteVM.GetName(), err)
|
||||
log.Errorf(msg)
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
result := localVM.SyncVMEip(ctx, task.UserCred, provider, eip, provider.ProjectId)
|
||||
msg := result.Result()
|
||||
log.Infof("syncVMEip for VM %s result: %s", localVM.Name, msg)
|
||||
if result.IsError() {
|
||||
logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
|
||||
}*/
|
||||
|
||||
@@ -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 modules
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
|
||||
type CloudproviderQuotasManager struct {
|
||||
modulebase.ResourceManager
|
||||
}
|
||||
|
||||
var (
|
||||
CloudproviderQuotas CloudproviderQuotasManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
CloudproviderQuotas = CloudproviderQuotasManager{NewComputeManager("cloudproviderquota", "cloudproviderquotas",
|
||||
[]string{"Id", "Name", "Quota_Range", "Quota_Type", "Max_Count", "Used_Count"},
|
||||
[]string{})}
|
||||
|
||||
registerCompute(&CloudproviderQuotas)
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// 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 aliyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type ValueItem struct {
|
||||
Value string
|
||||
DiskCategory string
|
||||
}
|
||||
|
||||
type AttributeValues struct {
|
||||
ValueItem []ValueItem
|
||||
}
|
||||
|
||||
type SAccountAttributeItem struct {
|
||||
AttributeValues AttributeValues
|
||||
AttributeName string
|
||||
}
|
||||
|
||||
type SQuota struct {
|
||||
Name string
|
||||
UsedCount int
|
||||
MaxCount int
|
||||
}
|
||||
|
||||
func (q *SQuota) GetGlobalId() string {
|
||||
return q.Name
|
||||
}
|
||||
|
||||
func (q *SQuota) GetDesc() string {
|
||||
return q.Name
|
||||
}
|
||||
|
||||
func (q *SQuota) GetQuotaType() string {
|
||||
return q.Name
|
||||
}
|
||||
|
||||
func (q *SQuota) GetMaxQuotaCount() int {
|
||||
return q.MaxCount
|
||||
}
|
||||
|
||||
func (q *SQuota) GetCurrentQuotaUsedCount() int {
|
||||
return q.UsedCount
|
||||
}
|
||||
|
||||
func (region *SRegion) GetAccountAttributes() ([]SAccountAttributeItem, error) {
|
||||
params := map[string]string{
|
||||
"RegionId": region.RegionId,
|
||||
}
|
||||
resp, err := region.ecsRequest("DescribeAccountAttributes", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ecsRequest")
|
||||
}
|
||||
quotas := []SAccountAttributeItem{}
|
||||
err = resp.Unmarshal("as, "AccountAttributeItems", "AccountAttributeItem")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "resp.Unmarshal")
|
||||
}
|
||||
return quotas, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) GetQuotas() ([]SQuota, error) {
|
||||
attrs, err := region.GetAccountAttributes()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetAccountAttributes")
|
||||
}
|
||||
quotas := map[string]SQuota{}
|
||||
for _, attr := range attrs {
|
||||
for _, item := range attr.AttributeValues.ValueItem {
|
||||
value, err := strconv.ParseInt(item.Value, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
used := false
|
||||
name := attr.AttributeName
|
||||
if strings.HasPrefix(name, "used-") {
|
||||
used = true
|
||||
name = strings.TrimPrefix(name, "used-")
|
||||
}
|
||||
if len(item.DiskCategory) > 0 {
|
||||
name = fmt.Sprintf("%s/%s", name, item.DiskCategory)
|
||||
}
|
||||
if _, ok := quotas[name]; !ok {
|
||||
quotas[name] = SQuota{
|
||||
Name: name,
|
||||
UsedCount: -1,
|
||||
}
|
||||
}
|
||||
quota := quotas[name]
|
||||
if used {
|
||||
quota.UsedCount = int(value)
|
||||
} else {
|
||||
quota.MaxCount = int(value)
|
||||
}
|
||||
quotas[name] = quota
|
||||
}
|
||||
}
|
||||
ret := []SQuota{}
|
||||
for _, quota := range quotas {
|
||||
ret = append(ret, quota)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
quotas, err := region.GetQuotas()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetQuotas")
|
||||
}
|
||||
ret := []cloudprovider.ICloudQuota{}
|
||||
for i := range quotas {
|
||||
ret = append(ret, "as[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -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/multicloud/aliyun"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type QuotaListOptions struct {
|
||||
}
|
||||
shellutils.R(&QuotaListOptions{}, "quota-list", "List quota", func(cli *aliyun.SRegion, args *QuotaListOptions) error {
|
||||
quotas, err := cli.GetQuotas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(quotas, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
func init() {
|
||||
type RouteTableListOptions struct {
|
||||
VpcId string `vpc id`
|
||||
VpcId string `help:"vpc id"`
|
||||
}
|
||||
shellutils.R(&RouteTableListOptions{}, "routetable-list", "List route tables", func(cli *aws.SRegion, args *RouteTableListOptions) error {
|
||||
routetables, err := cli.GetRouteTables(args.VpcId, false)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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/multicloud/azure"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type UsageListOptions struct {
|
||||
TYPE string `choices:"Microsoft.Network|Microsoft.Compute|Microsoft.Storage"`
|
||||
}
|
||||
shellutils.R(&UsageListOptions{}, "usage-list", "List usage", func(cli *azure.SRegion, args *UsageListOptions) error {
|
||||
usage, err := cli.GetUsage(args.TYPE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(usage, 0, 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// 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 azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type UsageName struct {
|
||||
Value string
|
||||
LocalizedValue string
|
||||
}
|
||||
|
||||
// {"value":[{"unit":"Count","currentValue":0,"limit":250,"name":{"value":"StorageAccounts","localizedValue":"Storage Accounts"}}]}
|
||||
type SUsage struct {
|
||||
Unit string
|
||||
CurrentValue int
|
||||
Limit int
|
||||
Name UsageName
|
||||
}
|
||||
|
||||
func (u *SUsage) GetGlobalId() string {
|
||||
return strings.ToLower(u.Name.Value)
|
||||
}
|
||||
|
||||
func (u *SUsage) GetQuotaType() string {
|
||||
return u.Name.Value
|
||||
}
|
||||
|
||||
func (u *SUsage) GetDesc() string {
|
||||
return u.Name.LocalizedValue
|
||||
}
|
||||
|
||||
func (u *SUsage) GetMaxQuotaCount() int {
|
||||
return u.Limit
|
||||
}
|
||||
|
||||
func (u *SUsage) GetCurrentQuotaUsedCount() int {
|
||||
return u.CurrentValue
|
||||
}
|
||||
|
||||
func (region *SRegion) GetUsage(resourceType string) ([]SUsage, error) {
|
||||
usage := []SUsage{}
|
||||
resource := fmt.Sprintf("%s/locations/%s/usages", resourceType, region.Name)
|
||||
err := region.client.ListAll(resource, &usage)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "ListAll(%s)", resource)
|
||||
}
|
||||
return usage, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
ret := []cloudprovider.ICloudQuota{}
|
||||
for _, resourceType := range []string{"Microsoft.Network", "Microsoft.Storage", "Microsoft.Compute", "Microsoft.Storage"} {
|
||||
usages, err := region.GetUsage(resourceType)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetUsage")
|
||||
}
|
||||
for i := range usages {
|
||||
ret = append(ret, &usages[i])
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// 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 google
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SQuota struct {
|
||||
Metric string
|
||||
Limit int
|
||||
Usage int
|
||||
Owner string
|
||||
}
|
||||
|
||||
func (q *SQuota) GetGlobalId() string {
|
||||
return strings.ToLower(q.Metric)
|
||||
}
|
||||
|
||||
func (q *SQuota) GetName() string {
|
||||
return q.Metric
|
||||
}
|
||||
|
||||
func (q *SQuota) GetDesc() string {
|
||||
return q.Metric
|
||||
}
|
||||
|
||||
func (q *SQuota) GetQuotaType() string {
|
||||
return q.Metric
|
||||
}
|
||||
|
||||
func (q *SQuota) GetMaxQuotaCount() int {
|
||||
return q.Limit
|
||||
}
|
||||
|
||||
func (q *SQuota) GetCurrentQuotaUsedCount() int {
|
||||
return q.Usage
|
||||
}
|
||||
|
||||
func (region *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
ret := []cloudprovider.ICloudQuota{}
|
||||
for i := range region.Quotas {
|
||||
ret = append(ret, ®ion.Quotas[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -35,6 +35,7 @@ type SRegion struct {
|
||||
client *SGoogleClient
|
||||
|
||||
capabilities []string
|
||||
Quotas []SQuota
|
||||
|
||||
Description string
|
||||
ID string
|
||||
|
||||
@@ -81,6 +81,7 @@ type Client struct {
|
||||
DBInstanceJob *modules.SDBInstanceJobManager
|
||||
Traces *modules.STraceManager
|
||||
CloudEye *modules.SCloudEyeManager
|
||||
Quotas *modules.SQuotaManager
|
||||
}
|
||||
|
||||
func (self *Client) SetHttpClient(httpClient *http.Client) {
|
||||
@@ -210,6 +211,7 @@ func (self *Client) initManagers() {
|
||||
self.DBInstanceJob = modules.NewDBInstanceJobManager(self.regionId, self.projectId, self.signer, self.debug)
|
||||
self.Traces = modules.NewTraceManager(self.regionId, self.projectId, self.signer, self.debug)
|
||||
self.CloudEye = modules.NewCloudEyeManager(self.regionId, self.projectId, self.signer, self.debug)
|
||||
self.Quotas = modules.NewQuotaManager(self.regionId, self.projectId, self.signer, self.debug)
|
||||
}
|
||||
|
||||
self.init = true
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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 (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
|
||||
)
|
||||
|
||||
type SQuotaManager struct {
|
||||
SResourceManager
|
||||
}
|
||||
|
||||
func NewQuotaManager(regionId string, projectId string, signer auth.Signer, debug bool) *SQuotaManager {
|
||||
return &SQuotaManager{SResourceManager: SResourceManager{
|
||||
SBaseManager: NewBaseManager(signer, debug),
|
||||
ServiceName: ServiceNameEVS,
|
||||
Region: regionId,
|
||||
ProjectId: projectId,
|
||||
version: "v1",
|
||||
Keyword: "quotas",
|
||||
KeywordPlural: "quotas",
|
||||
|
||||
ResourceKeyword: "quotas",
|
||||
}}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
// 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 huawei
|
||||
|
||||
import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SQuota struct {
|
||||
Min int
|
||||
Quota int
|
||||
Type string
|
||||
Used int
|
||||
}
|
||||
|
||||
func (q *SQuota) GetGlobalId() string {
|
||||
return q.Type
|
||||
}
|
||||
|
||||
func (q *SQuota) GetQuotaType() string {
|
||||
return q.Type
|
||||
}
|
||||
|
||||
func (q *SQuota) GetName() string {
|
||||
return q.Type
|
||||
}
|
||||
|
||||
func (q *SQuota) GetDesc() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (q *SQuota) GetMaxQuotaCount() int {
|
||||
return q.Quota
|
||||
}
|
||||
|
||||
func (q *SQuota) GetCurrentQuotaUsedCount() int {
|
||||
return q.Used
|
||||
}
|
||||
|
||||
func (self *SRegion) GetQuotas() ([]SQuota, error) {
|
||||
quotas := []SQuota{}
|
||||
params := map[string]string{}
|
||||
result, err := self.ecsClient.Quotas.Get("", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Quotas.List")
|
||||
}
|
||||
|
||||
err = result.Unmarshal("as, "resources")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "result.Unmarshal")
|
||||
}
|
||||
|
||||
return quotas, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
quotas, err := region.GetQuotas()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetQuotas")
|
||||
}
|
||||
ret := []cloudprovider.ICloudQuota{}
|
||||
for i := range quotas {
|
||||
ret = append(ret, "as[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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/multicloud/huawei"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type QuotaListOptions struct {
|
||||
}
|
||||
shellutils.R(&QuotaListOptions{}, "quota-list", "List Quotas", func(cli *huawei.SRegion, args *QuotaListOptions) error {
|
||||
quotas, err := cli.GetQuotas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(quotas, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
@@ -15,28 +15,66 @@
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/util/version"
|
||||
)
|
||||
|
||||
type SQuota struct {
|
||||
FixedIps int
|
||||
Floatingips int
|
||||
Networks int
|
||||
Port int
|
||||
RbacPolicy int
|
||||
Router int
|
||||
SecurityGroups int
|
||||
SecurityGroupRules int
|
||||
type QuotaDetail struct {
|
||||
Reserved int
|
||||
Limit int
|
||||
InUse int
|
||||
}
|
||||
|
||||
func (region *SRegion) GetQuota() (*SQuota, error) {
|
||||
_, resp, err := region.Get("compute", "/os-quota-sets/"+region.client.tokenCredential.GetTenantId(), "", nil)
|
||||
type QuotaSet struct {
|
||||
InjectedFileContentBytes QuotaDetail
|
||||
MetadataItems QuotaDetail
|
||||
ServerGroupMembers QuotaDetail
|
||||
ServerGroups QuotaDetail
|
||||
Ram QuotaDetail
|
||||
FloatingIps QuotaDetail
|
||||
KeyPairs QuotaDetail
|
||||
Id string
|
||||
Instances QuotaDetail
|
||||
SecurityGroupRules QuotaDetail
|
||||
InjectedFiles QuotaDetail
|
||||
Cores QuotaDetail
|
||||
FixedIps QuotaDetail
|
||||
InjectedFilePathBytes QuotaDetail
|
||||
SecurityGroups QuotaDetail
|
||||
}
|
||||
|
||||
type SQuota struct {
|
||||
Cores int
|
||||
Instances int
|
||||
KeyPairs int
|
||||
FixedIps int
|
||||
MetadataItems int
|
||||
Ram int
|
||||
ServerGroups int
|
||||
ServerGroupMembers int
|
||||
InjectedFileContentBytes int
|
||||
InjectedFilePathBytes int
|
||||
InjectedFiles int
|
||||
Floatingips int
|
||||
Networks int
|
||||
Port int
|
||||
RbacPolicy int
|
||||
Router int
|
||||
SecurityGroups int
|
||||
SecurityGroupRules int
|
||||
}
|
||||
|
||||
func (region *SRegion) GetQuota() (*QuotaSet, error) {
|
||||
_, resp, err := region.Get("compute", fmt.Sprintf("/os-quota-sets/%s/detail", region.client.tokenCredential.GetTenantId()), "", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
quota := &SQuota{}
|
||||
quota := &QuotaSet{}
|
||||
return quota, resp.Unmarshal(quota, "quota_set")
|
||||
}
|
||||
|
||||
@@ -74,3 +112,58 @@ func (region *SRegion) SetQuota(quota *SQuota) error {
|
||||
_, _, err := region.Update("compute", "/os-quota-sets/"+region.client.tokenCredential.GetTenantId(), maxVersion, jsonutils.Marshal(params))
|
||||
return err
|
||||
}
|
||||
|
||||
type IQuota struct {
|
||||
Name string
|
||||
Limit int
|
||||
InUse int
|
||||
}
|
||||
|
||||
func (iq *IQuota) GetGlobalId() string {
|
||||
return iq.Name
|
||||
}
|
||||
|
||||
func (iq *IQuota) GetName() string {
|
||||
return iq.Name
|
||||
}
|
||||
|
||||
func (iq *IQuota) GetDesc() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (iq *IQuota) GetQuotaType() string {
|
||||
return iq.Name
|
||||
}
|
||||
|
||||
func (iq *IQuota) GetMaxQuotaCount() int {
|
||||
return iq.Limit
|
||||
}
|
||||
|
||||
func (iq *IQuota) GetCurrentQuotaUsedCount() int {
|
||||
return iq.InUse
|
||||
}
|
||||
|
||||
func (region *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
quota, err := region.GetQuota()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetQuota")
|
||||
}
|
||||
|
||||
ret := []cloudprovider.ICloudQuota{}
|
||||
|
||||
ret = append(ret, &IQuota{Name: "injected_file_content_bytes", Limit: quota.InjectedFileContentBytes.Limit, InUse: quota.InjectedFileContentBytes.InUse})
|
||||
ret = append(ret, &IQuota{Name: "metadata_items", Limit: quota.MetadataItems.Limit, InUse: quota.MetadataItems.InUse})
|
||||
ret = append(ret, &IQuota{Name: "server_group_members", Limit: quota.ServerGroupMembers.Limit, InUse: quota.ServerGroupMembers.InUse})
|
||||
ret = append(ret, &IQuota{Name: "server_groups", Limit: quota.ServerGroups.Limit, InUse: quota.ServerGroups.InUse})
|
||||
ret = append(ret, &IQuota{Name: "ram", Limit: quota.Ram.Limit, InUse: quota.Ram.InUse})
|
||||
ret = append(ret, &IQuota{Name: "floating_ips", Limit: quota.FloatingIps.Limit, InUse: quota.FloatingIps.InUse})
|
||||
ret = append(ret, &IQuota{Name: "key_pairs", Limit: quota.KeyPairs.Limit, InUse: quota.KeyPairs.InUse})
|
||||
ret = append(ret, &IQuota{Name: "instances", Limit: quota.Instances.Limit, InUse: quota.Instances.InUse})
|
||||
ret = append(ret, &IQuota{Name: "security_group_rules", Limit: quota.SecurityGroupRules.Limit, InUse: quota.SecurityGroupRules.InUse})
|
||||
ret = append(ret, &IQuota{Name: "injected_files", Limit: quota.InjectedFiles.Limit, InUse: quota.InjectedFiles.InUse})
|
||||
ret = append(ret, &IQuota{Name: "cores", Limit: quota.Cores.Limit, InUse: quota.Cores.InUse})
|
||||
ret = append(ret, &IQuota{Name: "fixed_ips", Limit: quota.FixedIps.Limit, InUse: quota.FixedIps.InUse})
|
||||
ret = append(ret, &IQuota{Name: "injected_file_path_bytes", Limit: quota.InjectedFilePathBytes.Limit, InUse: quota.InjectedFilePathBytes.InUse})
|
||||
ret = append(ret, &IQuota{Name: "security_groups", Limit: quota.SecurityGroups.Limit, InUse: quota.SecurityGroups.InUse})
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
// 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 qcloud
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type ImageQuota struct {
|
||||
region *SRegion
|
||||
ImageNumQuota int
|
||||
}
|
||||
|
||||
func (iq *ImageQuota) GetGlobalId() string {
|
||||
return "ImageNumQuota"
|
||||
}
|
||||
|
||||
func (iq *ImageQuota) GetName() string {
|
||||
return "ImageNumQuota"
|
||||
}
|
||||
|
||||
func (iq *ImageQuota) GetDesc() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (iq *ImageQuota) GetQuotaType() string {
|
||||
return "ImageNumQuota"
|
||||
}
|
||||
|
||||
func (iq *ImageQuota) GetMaxQuotaCount() int {
|
||||
return iq.ImageNumQuota
|
||||
}
|
||||
|
||||
func (iq *ImageQuota) GetCurrentQuotaUsedCount() int {
|
||||
_, count, err := iq.region.GetImages("", "PRIVATE_IMAGE", nil, "", 0, iq.ImageNumQuota)
|
||||
if err != nil {
|
||||
log.Errorf("get private image error: %v", err)
|
||||
return -1
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func (region *SRegion) GetImageQuota() (*ImageQuota, error) {
|
||||
params := map[string]string{}
|
||||
resp, err := region.cvmRequest("DescribeImageQuota", params, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "DescribeImageQuota")
|
||||
}
|
||||
imageQuota := &ImageQuota{region: region}
|
||||
return imageQuota, resp.Unmarshal(imageQuota)
|
||||
}
|
||||
|
||||
type QuotaSet struct {
|
||||
QuotaId string
|
||||
QuotaCurrent int
|
||||
QuotaLimit int
|
||||
}
|
||||
|
||||
func (qs *QuotaSet) GetGlobalId() string {
|
||||
return strings.ToLower(qs.QuotaId)
|
||||
}
|
||||
|
||||
func (qs *QuotaSet) GetName() string {
|
||||
return qs.QuotaId
|
||||
}
|
||||
|
||||
func (qs *QuotaSet) GetDesc() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (qs *QuotaSet) GetQuotaType() string {
|
||||
return qs.QuotaId
|
||||
}
|
||||
|
||||
func (qs *QuotaSet) GetMaxQuotaCount() int {
|
||||
return qs.QuotaLimit
|
||||
}
|
||||
|
||||
func (qs *QuotaSet) GetCurrentQuotaUsedCount() int {
|
||||
return qs.QuotaCurrent
|
||||
}
|
||||
|
||||
func (region *SRegion) GetQuota(action string) ([]QuotaSet, error) {
|
||||
params := map[string]string{}
|
||||
resp, err := region.vpcRequest("DescribeAddressQuota", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "DescribeAddressQuota")
|
||||
}
|
||||
quotas := []QuotaSet{}
|
||||
err = resp.Unmarshal("as, "QuotaSet")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "resp.Unmarshal")
|
||||
}
|
||||
return quotas, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
ret := []cloudprovider.ICloudQuota{}
|
||||
imageQ, err := region.GetImageQuota()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetImageQuota")
|
||||
}
|
||||
ret = append(ret, imageQ)
|
||||
for _, action := range []string{"DescribeAddressQuota", "DescribeBandwidthPackageQuota"} {
|
||||
quotas, err := region.GetQuota(action)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetQuota(%s)", action)
|
||||
}
|
||||
for i := range quotas {
|
||||
ret = append(ret, "as[i])
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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/multicloud/qcloud"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type ImageQuotaShowOptions struct {
|
||||
}
|
||||
shellutils.R(&ImageQuotaShowOptions{}, "image-quota", "Show image quota", func(cli *qcloud.SRegion, args *ImageQuotaShowOptions) error {
|
||||
quota, err := cli.GetImageQuota()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(quota)
|
||||
return nil
|
||||
})
|
||||
|
||||
type QuotaListOptions struct {
|
||||
ACTION string `choices:"DescribeAddressQuota|DescribeBandwidthPackageQuota"`
|
||||
}
|
||||
|
||||
shellutils.R(&QuotaListOptions{}, "quota-list", "List quotas", func(cli *qcloud.SRegion, args *QuotaListOptions) error {
|
||||
quotas, err := cli.GetQuota(args.ACTION)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(quotas, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
@@ -138,3 +138,7 @@ func (self *SRegion) GetIElasticcacheById(id string) (cloudprovider.ICloudElasti
|
||||
func (self *SRegion) GetICloudEvents(start time.Time, end time.Time, withReadEvent bool) ([]cloudprovider.ICloudEvent, error) {
|
||||
return nil, fmt.Errorf("Not Implemented GetICloudEvnets")
|
||||
}
|
||||
|
||||
func (self *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
return nil, fmt.Errorf("Not Implemented GetICloudQuotas")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
// 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 zstack
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
/*
|
||||
"uuid":"132e0ad32b2242c4a648440be917ec4a",
|
||||
"name":"pci.num",
|
||||
"identityUuid":"2dce5dc485554d21a3796500c1db007a",
|
||||
"identityType":"AccountVO",
|
||||
"value":0,
|
||||
"lastOpDate":"Dec 28, 2019 2:26:03 PM",
|
||||
"createDate":"Dec 28, 2019 2:26:03 PM"
|
||||
*/
|
||||
|
||||
type SQuota struct {
|
||||
Uuid string
|
||||
Name string
|
||||
IdentityUuid string
|
||||
IdentityType string
|
||||
Value int
|
||||
}
|
||||
|
||||
func (q *SQuota) GetGlobalId() string {
|
||||
return q.Uuid
|
||||
}
|
||||
|
||||
func (q *SQuota) GetName() string {
|
||||
return q.Name
|
||||
}
|
||||
|
||||
func (q *SQuota) GetDesc() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (q *SQuota) GetQuotaType() string {
|
||||
return q.Name
|
||||
}
|
||||
|
||||
func (q *SQuota) GetMaxQuotaCount() int {
|
||||
return q.Value
|
||||
}
|
||||
|
||||
func (q *SQuota) GetCurrentQuotaUsedCount() int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func (region *SRegion) GetQuotas() ([]SQuota, error) {
|
||||
quotas := []SQuota{}
|
||||
params := url.Values{}
|
||||
err := region.client.listAll("accounts/quotas", params, "as)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return quotas, nil
|
||||
}
|
||||
|
||||
type SUserAccount struct {
|
||||
Uuid string
|
||||
}
|
||||
|
||||
func (region *SRegion) GetUserAccount(name string) ([]SUserAccount, error) {
|
||||
users := []SUserAccount{}
|
||||
params := url.Values{}
|
||||
if len(name) > 0 {
|
||||
params.Add("q", "name="+name)
|
||||
}
|
||||
err := region.client.listAll("accounts/users", params, &users)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "users.list")
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) GetICloudQuotas() ([]cloudprovider.ICloudQuota, error) {
|
||||
quotas, err := region.GetQuotas()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetQuotas")
|
||||
}
|
||||
ret := []cloudprovider.ICloudQuota{}
|
||||
for i := range quotas {
|
||||
ret = append(ret, "as[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -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/multicloud/zstack"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type QuotaListOptions struct {
|
||||
}
|
||||
shellutils.R(&QuotaListOptions{}, "quota-list", "List quotas", func(cli *zstack.SRegion, args *QuotaListOptions) error {
|
||||
quotas, err := cli.GetQuotas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(quotas, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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/multicloud/zstack"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type UserListOptions struct {
|
||||
Name string
|
||||
}
|
||||
shellutils.R(&UserListOptions{}, "user-list", "List users", func(cli *zstack.SRegion, args *UserListOptions) error {
|
||||
users, err := cli.GetUserAccount(args.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(users, 0, 0, 0, nil)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user