mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-30 17:13:08 +08:00
fix: 1. quota add API 2. tenant cache refresh 3. domain quota not initialize
This commit is contained in:
@@ -62,6 +62,7 @@ func init() {
|
||||
type QuotaSetOptions struct {
|
||||
Tenant string `help:"Tenant name or ID to set quota" json:"tenant,omitempty"`
|
||||
ProjectDomain string `help:"Domain name or ID to set quota" json:"domain,omitempty"`
|
||||
Action string `help:"quota set action" choices:"add|reset"`
|
||||
QuotaBaseOptions
|
||||
}
|
||||
R(&QuotaSetOptions{}, "quota-set", "Set quota for tenant", func(s *mcclient.ClientSession, args *QuotaSetOptions) error {
|
||||
|
||||
+3
-3
@@ -281,8 +281,8 @@ paths:
|
||||
/quotas/projects/{project_id}:
|
||||
$ref: "./quotas/projectquotas.yaml"
|
||||
/quotas/domains/{domain_id}:
|
||||
$ref: "./quotas/projectquotas.yaml"
|
||||
$ref: "./quotas/domainquotas.yaml"
|
||||
/quotas/projects:
|
||||
$ref: "./quotas/projectquotalist.yaml"
|
||||
/quotas/domains:
|
||||
$ref: "./quotas/quotalist.yaml"
|
||||
/quotas/projects:
|
||||
$ref: "./quotas/quotalist.yaml"
|
||||
|
||||
@@ -18,3 +18,38 @@ domain_id:
|
||||
type: string
|
||||
description: 查询指定域的配额
|
||||
|
||||
project_domain:
|
||||
name: project_domain
|
||||
in: query
|
||||
type: string
|
||||
description: 指定查询的域名称或者ID
|
||||
|
||||
quotas:
|
||||
name: quotas
|
||||
in: body
|
||||
required: true
|
||||
type: object
|
||||
description: 设置配额信息
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
description: 设置配额的方式,可能值为set,add和reset,分别代表设置,增加和重置为初始值
|
||||
default: set
|
||||
cpu:
|
||||
type: integer
|
||||
description: 设置CPU配额,单位为个
|
||||
memory:
|
||||
type: integer
|
||||
description: 设置内存配额,单位为MB
|
||||
storage:
|
||||
type: integer
|
||||
description: 设置磁盘配额,单位为MB
|
||||
isolated_device:
|
||||
type: integer
|
||||
description: 设置GPU配额,单位为块
|
||||
snapshot:
|
||||
type: integer
|
||||
description: 设置快照配额,单位为MB
|
||||
image:
|
||||
type: integer
|
||||
description: 设置镜像配额,单位为个
|
||||
|
||||
@@ -9,3 +9,14 @@ get:
|
||||
$ref: "../schemas/quota.yaml#/QuotaGetResponse"
|
||||
tags:
|
||||
- quota
|
||||
|
||||
post:
|
||||
summary: 设置指定域的配额
|
||||
parameters:
|
||||
- $ref: "../parameters/quota.yaml#/domain_id"
|
||||
- $ref: "../parameters/quota.yaml#/quotas"
|
||||
responses:
|
||||
200:
|
||||
description: 设置成功
|
||||
tags:
|
||||
- quota
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
get:
|
||||
summary: 获取当前域或者指定域下所有项目的配额信息
|
||||
parameters:
|
||||
- $ref: "../parameters/quota.yaml#/project_domain"
|
||||
responses:
|
||||
200:
|
||||
description: 配额信息
|
||||
schema:
|
||||
$ref: "../schemas/quota.yaml#/QuotaListResponse"
|
||||
tags:
|
||||
- quota
|
||||
@@ -1,7 +1,7 @@
|
||||
get:
|
||||
summary: 获得指定项目的配额
|
||||
parameters:
|
||||
$ref: "../parameters/quota.yaml#/project_id"
|
||||
- $ref: "../parameters/quota.yaml#/project_id"
|
||||
responses:
|
||||
200:
|
||||
description: 配额信息
|
||||
@@ -9,3 +9,14 @@ get:
|
||||
$ref: "../schemas/quota.yaml#/QuotaGetResponse"
|
||||
tags:
|
||||
- quota
|
||||
|
||||
post:
|
||||
summary: 设置指定项目的配额
|
||||
parameters:
|
||||
- $ref: "../parameters/quota.yaml#/project_id"
|
||||
- $ref: "../parameters/quota.yaml#/quotas"
|
||||
responses:
|
||||
200:
|
||||
description: 设置成功
|
||||
tags:
|
||||
- quota
|
||||
|
||||
@@ -4,6 +4,6 @@ get:
|
||||
200:
|
||||
description: 配额信息
|
||||
schema:
|
||||
$ref: "../schemas/quota.yaml#/QuotaGetResponse"
|
||||
$ref: "../schemas/quota.yaml#/QuotaListResponse"
|
||||
tags:
|
||||
- quota
|
||||
|
||||
+16
-2
@@ -1,14 +1,28 @@
|
||||
QuotaListResponse:
|
||||
type: object
|
||||
properties:
|
||||
quotas:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/quota'
|
||||
|
||||
QuotaGetResponse:
|
||||
type: object
|
||||
properties:
|
||||
quotas:
|
||||
type: object
|
||||
$ref: '#/Quota'
|
||||
$ref: '#/quota'
|
||||
|
||||
Quota:
|
||||
quota:
|
||||
type: object
|
||||
description: 配额信息
|
||||
properties:
|
||||
domain_id:
|
||||
type: string
|
||||
description: 在配额列表中,只是当前配额的适用域ID
|
||||
project_id:
|
||||
type: string
|
||||
description: 在配额列表中,只是当前配额的适用项目ID
|
||||
cpu:
|
||||
type: integer
|
||||
description: CPU配额
|
||||
|
||||
@@ -5,12 +5,12 @@ post:
|
||||
name: storage
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../schemas/storage.yaml#StorageCreate'
|
||||
$ref: '../schemas/storage.yaml#/StorageCreate'
|
||||
response:
|
||||
200:
|
||||
description: 新建存储的信息
|
||||
schema:
|
||||
$ref: '../schemas/storage.yaml#StorageResponse'
|
||||
$ref: '../schemas/storage.yaml#/StorageResponse'
|
||||
tags:
|
||||
- storages
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
|
||||
common_options "yunion.io/x/onecloud/pkg/cloudcommon/options"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
@@ -70,6 +71,8 @@ func InitAuth(options *common_options.CommonOptions, authComplete auth.AuthCompl
|
||||
|
||||
authComplete()
|
||||
|
||||
consts.SetTenantCacheExpireSeconds(options.TenantCacheExpireSeconds)
|
||||
|
||||
InitBaseAuth(&options.BaseOptions)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,16 @@
|
||||
|
||||
package consts
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
globalRegion = ""
|
||||
|
||||
globalServiceType = ""
|
||||
|
||||
tenantCacheExpireSeconds = 900
|
||||
)
|
||||
|
||||
func SetRegion(region string) {
|
||||
@@ -35,3 +41,11 @@ func SetServiceType(srvType string) {
|
||||
func GetServiceType() string {
|
||||
return globalServiceType
|
||||
}
|
||||
|
||||
func SetTenantCacheExpireSeconds(sec int) {
|
||||
tenantCacheExpireSeconds = sec
|
||||
}
|
||||
|
||||
func GetTenantCacheExpireSeconds() time.Duration {
|
||||
return time.Duration(tenantCacheExpireSeconds) * time.Second
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type SKeystoneCacheObjectManager struct {
|
||||
SStandaloneResourceBaseManager
|
||||
}
|
||||
@@ -23,6 +27,8 @@ type SKeystoneCacheObject struct {
|
||||
|
||||
DomainId string `width:"128" charset:"ascii" nullable:"true"`
|
||||
Domain string `width:"128" charset:"utf8" nullable:"true"`
|
||||
|
||||
LastCheck time.Time `nullable:"true"`
|
||||
}
|
||||
|
||||
func NewKeystoneCacheObjectManager(dt interface{}, tableName string, keyword string, keywordPlural string) SKeystoneCacheObjectManager {
|
||||
@@ -37,16 +43,3 @@ func NewKeystoneCacheObject(id string, name string, domainId string, domain stri
|
||||
obj.DomainId = domainId
|
||||
return obj
|
||||
}
|
||||
|
||||
func (manager *SKeystoneCacheObjectManager) BatchFetchNames(idStrs []string) []string {
|
||||
t := manager.TableSpec().Instance()
|
||||
results, err := t.Query(t.Field("name")).In("id", idStrs).AllStringMap()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ret := make([]string, len(results))
|
||||
for i, obj := range results {
|
||||
ret[i] = obj["name"]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
)
|
||||
|
||||
const (
|
||||
QUOTA_ACTION_ADD = "add"
|
||||
QUOTA_ACTION_RESET = "reset"
|
||||
)
|
||||
|
||||
func AddQuotaHandler(manager *SQuotaBaseManager, prefix string, app *appsrv.Application) {
|
||||
app.AddHandler2("GET",
|
||||
fmt.Sprintf("%s/%s", prefix, manager.KeywordPlural()),
|
||||
@@ -232,7 +237,15 @@ func (manager *SQuotaBaseManager) setQuotaHanlder(ctx context.Context, w http.Re
|
||||
httperrors.GeneralServerError(w, err)
|
||||
return
|
||||
}
|
||||
oquota.Update(quota)
|
||||
action, _ := body.GetString(manager.KeywordPlural(), "action")
|
||||
switch action {
|
||||
case QUOTA_ACTION_ADD:
|
||||
oquota.Add(quota)
|
||||
case QUOTA_ACTION_RESET:
|
||||
oquota.FetchSystemQuota(scope, ownerId)
|
||||
default:
|
||||
oquota.Update(quota)
|
||||
}
|
||||
|
||||
if scope == rbacutils.ScopeProject {
|
||||
total, err := manager.getDomainTotalQuota(ctx, ownerId.GetProjectDomainId(), []string{ownerId.GetProjectId()})
|
||||
@@ -396,13 +409,9 @@ func (manager *SQuotaBaseManager) listQuotas(ctx context.Context, targetDomainId
|
||||
// dsable platform
|
||||
q = q.IsNullOrEmpty("platform")
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
if err != sql.ErrNoRows {
|
||||
log.Errorf("query quotas fail %s", err)
|
||||
return nil, httperrors.NewInternalServerError("query quotas %s", err)
|
||||
} else {
|
||||
return []jsonutils.JSONObject{}, nil
|
||||
}
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Errorf("query quotas fail %s", err)
|
||||
return nil, httperrors.NewInternalServerError("query quotas %s", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -453,7 +462,25 @@ func (manager *SQuotaBaseManager) listQuotas(ctx context.Context, targetDomainId
|
||||
}
|
||||
ret = append(ret, quota)
|
||||
}
|
||||
|
||||
if len(ret) == 0 && len(targetDomainId) > 0 {
|
||||
// return the initial quota of targetDomainId
|
||||
scope := rbacutils.ScopeDomain
|
||||
owner := db.SOwnerId{
|
||||
DomainId: targetDomainId,
|
||||
}
|
||||
platform := []string{}
|
||||
quota, _, err := manager.queryQuota(ctx, scope, &owner, platform)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInternalServerError("query domain initial quotas %s", err)
|
||||
}
|
||||
quota.Set("domain_id", jsonutils.NewString(targetDomainId))
|
||||
domain, err := db.TenantCacheManager.FetchDomainById(ctx, targetDomainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
quota.Set("project_domain", jsonutils.NewString(domain.Name))
|
||||
ret = append(ret, quota)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ func (manager *SQuotaBaseManager) PostUsageJob(scope rbacutils.TRbacScope, owner
|
||||
// check existence of project
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion(), "v1")
|
||||
if scope == rbacutils.ScopeDomain {
|
||||
domain, err := modules.Domains.Get(s, ownerId.GetProjectDomainId(), nil)
|
||||
domain, err := modules.Domains.GetById(s, ownerId.GetProjectDomainId(), nil)
|
||||
if err == nil {
|
||||
// update cache
|
||||
domainId, _ := domain.GetString("id")
|
||||
@@ -106,7 +106,7 @@ func (manager *SQuotaBaseManager) PostUsageJob(scope rbacutils.TRbacScope, owner
|
||||
save = false
|
||||
}
|
||||
} else {
|
||||
proj, err := modules.Projects.Get(s, ownerId.GetProjectId(), nil)
|
||||
proj, err := modules.Projects.GetById(s, ownerId.GetProjectId(), nil)
|
||||
if err == nil {
|
||||
// update cache
|
||||
projId, _ := proj.GetString("id")
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
@@ -102,24 +103,35 @@ func (manager *STenantCacheManager) fetchTenant(ctx context.Context, idStr strin
|
||||
q = q.NotEquals("domain_id", identityapi.KeystoneDomainRoot)
|
||||
}
|
||||
q = filter(q)
|
||||
tenant, err := NewModelObject(manager)
|
||||
tobj, err := NewModelObject(manager)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewModelObject")
|
||||
}
|
||||
err = q.First(tenant)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
if isDomain {
|
||||
return manager.fetchDomainFromKeystone(ctx, idStr)
|
||||
} else {
|
||||
return manager.fetchTenantFromKeystone(ctx, idStr)
|
||||
}
|
||||
} else {
|
||||
return nil, errors.Wrap(err, "query")
|
||||
err = q.First(tobj)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "query")
|
||||
} else if tobj != nil {
|
||||
tenant := tobj.(*STenant)
|
||||
if !tenant.IsExpired() {
|
||||
return tenant, nil
|
||||
}
|
||||
} else {
|
||||
return tenant.(*STenant), nil
|
||||
}
|
||||
if isDomain {
|
||||
return manager.fetchDomainFromKeystone(ctx, idStr)
|
||||
} else {
|
||||
return manager.fetchTenantFromKeystone(ctx, idStr)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *STenant) IsExpired() bool {
|
||||
if t.LastCheck.IsZero() {
|
||||
return true
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
if t.LastCheck.Add(consts.GetTenantCacheExpireSeconds()).Before(now) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (manager *STenantCacheManager) FetchTenantByIdOrName(ctx context.Context, idStr string) (*STenant, error) {
|
||||
@@ -154,7 +166,7 @@ func (manager *STenantCacheManager) fetchTenantFromKeystone(ctx context.Context,
|
||||
return nil, fmt.Errorf("Empty idStr")
|
||||
}
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion(), "v1")
|
||||
tenant, err := modules.Projects.Get(s, idStr, nil)
|
||||
tenant, err := modules.Projects.GetById(s, idStr, nil)
|
||||
if err != nil {
|
||||
if je, ok := err.(*httputils.JSONClientError); ok && je.Code == 404 {
|
||||
return nil, sql.ErrNoRows
|
||||
@@ -162,10 +174,10 @@ func (manager *STenantCacheManager) fetchTenantFromKeystone(ctx context.Context,
|
||||
log.Errorf("fetch project %s fail %s", idStr, err)
|
||||
return nil, errors.Wrap(err, "modules.Projects.Get")
|
||||
}
|
||||
tenantId, err := tenant.GetString("id")
|
||||
tenantName, err := tenant.GetString("name")
|
||||
domainId, err := tenant.GetString("domain_id")
|
||||
domainName, err := tenant.GetString("domain")
|
||||
tenantId, _ := tenant.GetString("id")
|
||||
tenantName, _ := tenant.GetString("name")
|
||||
domainId, _ := tenant.GetString("domain_id")
|
||||
domainName, _ := tenant.GetString("project_domain")
|
||||
// manager.Save(ctx, domainId, domainName, identityapi.KeystoneDomainRoot, identityapi.KeystoneDomainRoot)
|
||||
return manager.Save(ctx, tenantId, tenantName, domainId, domainName)
|
||||
}
|
||||
@@ -202,7 +214,7 @@ func (manager *STenantCacheManager) fetchDomainFromKeystone(ctx context.Context,
|
||||
return nil, fmt.Errorf("Empty idStr")
|
||||
}
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion(), "v1")
|
||||
tenant, err := modules.Domains.Get(s, idStr, nil)
|
||||
tenant, err := modules.Domains.GetById(s, idStr, nil)
|
||||
if err != nil {
|
||||
if je, ok := err.(*httputils.JSONClientError); ok && je.Code == 404 {
|
||||
return nil, sql.ErrNoRows
|
||||
@@ -239,9 +251,14 @@ func (manager *STenantCacheManager) Save(ctx context.Context, idStr string, name
|
||||
log.Errorf("FetchTenantbyId fail %s", err)
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
if err == nil {
|
||||
obj := objo.(*STenant)
|
||||
if obj.Id == idStr && obj.Name == name && obj.Domain == domain && obj.DomainId == domainId {
|
||||
Update(obj, func() error {
|
||||
obj.LastCheck = now
|
||||
return nil
|
||||
})
|
||||
return obj, nil
|
||||
}
|
||||
_, err = Update(obj, func() error {
|
||||
@@ -249,6 +266,7 @@ func (manager *STenantCacheManager) Save(ctx context.Context, idStr string, name
|
||||
obj.Name = name
|
||||
obj.Domain = domain
|
||||
obj.DomainId = domainId
|
||||
obj.LastCheck = now
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -263,6 +281,7 @@ func (manager *STenantCacheManager) Save(ctx context.Context, idStr string, name
|
||||
obj.Name = name
|
||||
obj.Domain = domain
|
||||
obj.DomainId = domainId
|
||||
obj.LastCheck = now
|
||||
err = manager.TableSpec().Insert(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -218,7 +218,8 @@ func (manager *SVirtualResourceBaseManager) FetchCustomizeColumns(ctx context.Co
|
||||
}
|
||||
|
||||
func FetchProjects(projectIds []string, isDomain bool) map[string]STenant {
|
||||
q := TenantCacheManager.Query().In("id", projectIds)
|
||||
deadline := time.Now().UTC().Add(-consts.GetTenantCacheExpireSeconds())
|
||||
q := TenantCacheManager.Query().In("id", projectIds).GT("last_check", deadline)
|
||||
if isDomain {
|
||||
q = q.Equals("domain_id", identityapi.KeystoneDomainRoot)
|
||||
} else {
|
||||
@@ -233,6 +234,21 @@ func FetchProjects(projectIds []string, isDomain bool) map[string]STenant {
|
||||
for i := range projects {
|
||||
ret[projects[i].Id] = projects[i]
|
||||
}
|
||||
ctx := context.Background()
|
||||
for _, pid := range projectIds {
|
||||
if _, ok := ret[pid]; !ok {
|
||||
// not found
|
||||
var t *STenant
|
||||
if isDomain {
|
||||
t, _ = TenantCacheManager.fetchDomainFromKeystone(ctx, pid)
|
||||
} else {
|
||||
t, _ = TenantCacheManager.fetchTenantFromKeystone(ctx, pid)
|
||||
}
|
||||
if t != nil {
|
||||
ret[t.Id] = *t
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ type CommonOptions struct {
|
||||
AdminProjectDomain string `help:"Domain of Admin project"`
|
||||
AuthTokenCacheSize uint32 `help:"Auth token Cache Size" default:"2048"`
|
||||
|
||||
TenantCacheExpireSeconds int `help:"expire seconds of cached tenant/domain info. defailt 15 minutes" default:"900"`
|
||||
|
||||
BaseOptions
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ func verifyTokensV3(ctx context.Context, w http.ResponseWriter, r *http.Request)
|
||||
httperrors.InvalidCredentialError(w, "invalid project")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
} else if len(token.DomainId) > 0 {
|
||||
domain, err = models.DomainManager.FetchDomainById(token.DomainId)
|
||||
if err != nil {
|
||||
httperrors.InvalidCredentialError(w, "invalid domain")
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package mcclient
|
||||
|
||||
type IServiceCatalog interface {
|
||||
Len() int
|
||||
GetServiceURL(service, region, zone, endpointType string) (string, error)
|
||||
GetServiceURLs(service, region, zone, endpointType string) ([]string, error)
|
||||
}
|
||||
|
||||
@@ -234,10 +234,11 @@ func (this *Client) unmarshalV3Token(rbody jsonutils.JSONObject, tokenId string)
|
||||
err = fmt.Errorf("Invalid response when unmarshal V3 Token: %v", err)
|
||||
}
|
||||
cata := cred.GetServiceCatalog()
|
||||
if cata == nil {
|
||||
log.Fatalf("No srvice catalog avaiable")
|
||||
if cata == nil || cata.Len() == 0 {
|
||||
log.Warningf("No service catalog avaiable")
|
||||
} else {
|
||||
this.serviceCatalog = cata
|
||||
}
|
||||
this.serviceCatalog = cata
|
||||
return
|
||||
}
|
||||
|
||||
@@ -250,10 +251,11 @@ func (this *Client) unmarshalV2Token(rbody jsonutils.JSONObject) (cred TokenCred
|
||||
err = fmt.Errorf("Invalid response when unmarshal V2 Token: %s", err)
|
||||
}
|
||||
cata := cred.GetServiceCatalog()
|
||||
if cata == nil {
|
||||
log.Fatalf("No srvice catalog avaiable")
|
||||
if cata == nil || cata.Len() == 0 {
|
||||
log.Warningf("No srvice catalog avaiable")
|
||||
} else {
|
||||
this.serviceCatalog = cata
|
||||
}
|
||||
this.serviceCatalog = cata
|
||||
return
|
||||
}
|
||||
err = fmt.Errorf("Invalid response: no access object")
|
||||
@@ -308,10 +310,11 @@ func (this *Client) SetProject(tenantId, tenantName, tenantDomain string, token
|
||||
func (this *Client) NewSession(ctx context.Context, region, zone, endpointType string, token TokenCredential, apiVersion string) *ClientSession {
|
||||
cata := token.GetServiceCatalog()
|
||||
if this.serviceCatalog == nil {
|
||||
if cata == nil {
|
||||
log.Fatalf("Missing service catalog in token")
|
||||
if cata == nil || cata.Len() == 0 {
|
||||
log.Warningf("Missing service catalog in token")
|
||||
} else {
|
||||
this.serviceCatalog = cata
|
||||
}
|
||||
this.serviceCatalog = cata
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
|
||||
@@ -172,6 +172,10 @@ func (this *TokenCredentialV2) IsAllow(scope rbacutils.TRbacScope, service strin
|
||||
}
|
||||
}
|
||||
|
||||
func (this *TokenCredentialV2) Len() int {
|
||||
return this.ServiceCatalog.Len()
|
||||
}
|
||||
|
||||
func (this *TokenCredentialV2) GetServiceURL(service, region, zone, endpointType string) (string, error) {
|
||||
return this.ServiceCatalog.GetServiceURL(service, region, zone, endpointType)
|
||||
}
|
||||
@@ -272,6 +276,10 @@ func (catalog KeystoneServiceCatalogV2) getServiceEndpoint(service, region, zone
|
||||
}
|
||||
}
|
||||
|
||||
func (catalog KeystoneServiceCatalogV2) Len() int {
|
||||
return len(catalog)
|
||||
}
|
||||
|
||||
func (catalog KeystoneServiceCatalogV2) GetServiceURL(service, region, zone, endpointType string) (string, error) {
|
||||
ep, err := catalog.getServiceEndpoint(service, region, zone)
|
||||
if err != nil {
|
||||
|
||||
@@ -176,6 +176,10 @@ func (this *TokenCredentialV3) GetRegions() []string {
|
||||
return this.Token.Catalog.getRegions()
|
||||
}
|
||||
|
||||
func (this *TokenCredentialV3) Len() int {
|
||||
return this.Token.Catalog.Len()
|
||||
}
|
||||
|
||||
func (this *TokenCredentialV3) GetServiceURL(service, region, zone, endpointType string) (string, error) {
|
||||
return this.Token.Catalog.GetServiceURL(service, region, zone, endpointType)
|
||||
}
|
||||
@@ -293,6 +297,10 @@ func Id2RegionZone(id string) (string, string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (catalog KeystoneServiceCatalogV3) Len() int {
|
||||
return len(catalog)
|
||||
}
|
||||
|
||||
func (catalog KeystoneServiceCatalogV3) GetServiceURL(service, region, zone, endpointType string) (string, error) {
|
||||
urls, err := catalog.GetServiceURLs(service, region, zone, endpointType)
|
||||
if err != nil {
|
||||
|
||||
@@ -137,6 +137,10 @@ func (self *SSimpleToken) GetRegions() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSimpleToken) Len() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *SSimpleToken) GetServiceURL(service, region, zone, endpointType string) (string, error) {
|
||||
return "", fmt.Errorf("Not available")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user