From 856420f6750f25b388bbc0b11cd0310db9613436 Mon Sep 17 00:00:00 2001 From: ioito Date: Fri, 5 Jul 2019 14:14:05 +0800 Subject: [PATCH] fix cache domain tenants --- pkg/cloudcommon/db/tenantcache.go | 47 +++++++++++++++++++++++++++-- pkg/compute/models/cloudaccounts.go | 16 ++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/pkg/cloudcommon/db/tenantcache.go b/pkg/cloudcommon/db/tenantcache.go index 38ef6c5840..8a0daf303e 100644 --- a/pkg/cloudcommon/db/tenantcache.go +++ b/pkg/cloudcommon/db/tenantcache.go @@ -21,6 +21,8 @@ import ( "runtime/debug" "time" + "yunion.io/x/jsonutils" + "github.com/pkg/errors" "yunion.io/x/log" @@ -316,13 +318,54 @@ func (tenant *STenant) GetDomainId() string { return tenant.DomainId } -func (manager *STenantCacheManager) FindFirstProjectOfDomain(domainId string) (*STenant, error) { +func (manager *STenantCacheManager) findFirstProjectOfDomain(domainId string) (*STenant, error) { q := manager.Query().Equals("domain_id", domainId) tenant := STenant{} tenant.SetModelManager(manager, &tenant) err := q.First(&tenant) if err != nil { - return nil, errors.Wrap(err, "queryFirst") + return nil, err } return &tenant, nil } + +func (manager *STenantCacheManager) fetchDomainTenantsFromKeystone(domainId string) error { + if len(domainId) == 0 { + log.Debugf("fetch empty domain!!!!") + debug.PrintStack() + return fmt.Errorf("Empty domainId") + } + + s := auth.GetAdminSession(context.Background(), consts.GetRegion(), "v1") + params := jsonutils.Marshal(map[string]string{"domain_id": domainId}) + tenants, err := modules.Projects.List(s, params) + if err != nil { + return errors.Wrap(err, "Projects.List") + } + for _, tenant := range tenants.Data { + tenantId, _ := tenant.GetString("id") + tenantName, _ := tenant.GetString("name") + domainId, _ := tenant.GetString("domain_id") + domainName, _ := tenant.GetString("project_domain") + _, err = manager.Save(context.Background(), tenantId, tenantName, domainId, domainName) + if err != nil { + return err + } + } + return nil +} + +func (manager *STenantCacheManager) FindFirstProjectOfDomain(domainId string) (*STenant, error) { + tenant, err := manager.findFirstProjectOfDomain(domainId) + if err != nil { + if err == sql.ErrNoRows { + err = manager.fetchDomainTenantsFromKeystone(domainId) + if err != nil { + return nil, errors.Wrap(err, "fetchDomainTenantsFromKeystone") + } + return manager.findFirstProjectOfDomain(domainId) + } + return nil, errors.Wrap(err, "findFirstProjectOfDomain.queryFirst") + } + return tenant, nil +} diff --git a/pkg/compute/models/cloudaccounts.go b/pkg/compute/models/cloudaccounts.go index 6e044dfad0..cea7a47f66 100644 --- a/pkg/compute/models/cloudaccounts.go +++ b/pkg/compute/models/cloudaccounts.go @@ -33,6 +33,7 @@ import ( "yunion.io/x/sqlchemy" api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudcommon/consts" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" @@ -41,6 +42,7 @@ import ( "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/auth" + "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/stringutils2" ) @@ -307,6 +309,20 @@ func (manager *SCloudaccountManager) ValidateCreateData(ctx context.Context, use } data.Set("sync_interval_seconds", jsonutils.NewInt(syncIntervalSecs)) + if !jsonutils.QueryBoolean(query, "auto_create_project", false) { + if userCred.GetProjectDomainId() != ownerId.GetProjectDomainId() { + s := auth.GetAdminSession(ctx, consts.GetRegion(), "v1") + params := jsonutils.Marshal(map[string]string{"domain_id": ownerId.GetProjectDomainId()}) + tenants, err := modules.Projects.List(s, params) + if err != nil { + return nil, err + } + if tenants.Total == 0 { + return nil, httperrors.NewInputParameterError("There are no projects under the domain %s", ownerId.GetProjectDomainId()) + } + } + } + return manager.SEnabledStatusStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data) }