From 7232695dfbe15d4a440fcf6c950508a8d848cc2a Mon Sep 17 00:00:00 2001 From: Qu Xuan Date: Fri, 4 Sep 2020 20:17:45 +0800 Subject: [PATCH] fix: cloudid optimized --- pkg/apis/cloudid/cloudgroup.go | 1 + pkg/apis/cloudid/cloudgroupcache.go | 1 + pkg/cloudid/models/cloudgroup.go | 13 +++- pkg/cloudid/models/cloudgroupcaches.go | 19 +++++- pkg/cloudid/options/options.go | 11 ++++ pkg/cloudid/service/service.go | 7 +- .../tasks/cloudgroup_sync_status_task.go | 66 +++++++++++++++++++ .../tasks/cloudgroupcache_sync_status_task.go | 1 + pkg/multicloud/aliyun/ram_user.go | 11 +++- pkg/multicloud/aliyun/shell/ram_user.go | 9 +++ pkg/multicloud/aws/iam_user.go | 11 +++- 11 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 pkg/cloudid/tasks/cloudgroup_sync_status_task.go diff --git a/pkg/apis/cloudid/cloudgroup.go b/pkg/apis/cloudid/cloudgroup.go index 903d589b67..c753a52963 100644 --- a/pkg/apis/cloudid/cloudgroup.go +++ b/pkg/apis/cloudid/cloudgroup.go @@ -24,6 +24,7 @@ const ( CLOUD_GROUP_STATUS_SYNC_POLICIES_FAILED = "sync_policies_failed" // 同步权限失败 CLOUD_GROUP_STATUS_SYNC_USERS = "sync_users" // 同步用户中 CLOUD_GROUP_STATUS_SYNC_USERS_FAILED = "sync_users_failed" // 同步用户失败 + CLOUD_GROUP_STATUS_SYNC_STATUS = "sync_status" // 同步状态 ) type CloudgroupJointResourceDetails struct { diff --git a/pkg/apis/cloudid/cloudgroupcache.go b/pkg/apis/cloudid/cloudgroupcache.go index 9ea69ed128..42a78d8eec 100644 --- a/pkg/apis/cloudid/cloudgroupcache.go +++ b/pkg/apis/cloudid/cloudgroupcache.go @@ -17,6 +17,7 @@ package cloudid import "yunion.io/x/onecloud/pkg/apis" const ( + CLOUD_GROUP_CACHE_STATUS_AVAILABLE = "available" // 正常 CLOUD_GROUP_CACHE_STATUS_CREATING = "creating" // 创建中 CLOUD_GROUP_CACHE_STATUS_CREATE_FAILED = "create_failed" // 创建失败 CLOUD_GROUP_CACHE_STATUS_DELETING = "deleting" // 删除中 diff --git a/pkg/cloudid/models/cloudgroup.go b/pkg/cloudid/models/cloudgroup.go index 4664d2e085..44c830ffa0 100644 --- a/pkg/cloudid/models/cloudgroup.go +++ b/pkg/cloudid/models/cloudgroup.go @@ -480,10 +480,19 @@ func (self *SCloudgroup) AllowPerformSyncstatus(ctx context.Context, userCred mc return db.IsDomainAllowPerform(userCred, self, "syncstatus") } +func (self *SCloudgroup) StartCloudgroupSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error { + task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupSyncstatusTask", self, userCred, nil, parentTaskId, "", nil) + if err != nil { + return errors.Wrap(err, "NewTask") + } + self.SetStatus(userCred, api.CLOUD_GROUP_STATUS_SYNC_STATUS, "") + task.ScheduleRun(nil) + return nil +} + // 恢复权限组状态 func (self *SCloudgroup) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSyncstatusInput) (jsonutils.JSONObject, error) { - self.SetStatus(userCred, api.CLOUD_USER_STATUS_AVAILABLE, "syncstatus") - return nil, nil + return nil, self.StartCloudgroupSyncstatusTask(ctx, userCred, "") } func (self *SCloudgroup) AllowPerformRemoveUser(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { diff --git a/pkg/cloudid/models/cloudgroupcaches.go b/pkg/cloudid/models/cloudgroupcaches.go index 7c8328cf40..5a77752af7 100644 --- a/pkg/cloudid/models/cloudgroupcaches.go +++ b/pkg/cloudid/models/cloudgroupcaches.go @@ -34,6 +34,7 @@ import ( "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/logclient" "yunion.io/x/onecloud/pkg/util/rand" + "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/stringutils2" ) @@ -112,6 +113,18 @@ func (self *SCloudgroupcache) CustomizeDelete(ctx context.Context, userCred mccl return self.StartCloudgroupcacheDeleteTask(ctx, userCred, "") } +func (manager *SCloudgroupcacheManager) ResourceScope() rbacutils.TRbacScope { + return rbacutils.ScopeDomain +} + +func (self *SCloudgroupcache) GetOwnerId() mcclient.IIdentityProvider { + group, err := self.GetCloudgroup() + if err != nil { + return nil + } + return group.GetOwnerId() +} + func (self *SCloudgroupcache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { return nil } @@ -126,7 +139,7 @@ func (manager *SCloudgroupcacheManager) newFromCloudgroup(ctx context.Context, u cache.CloudgroupId = group.Id cache.Name = iGroup.GetName() cache.Description = iGroup.GetDescription() - cache.Status = api.CLOUD_GROUP_STATUS_AVAILABLE + cache.Status = api.CLOUD_GROUP_CACHE_STATUS_AVAILABLE cache.ExternalId = iGroup.GetGlobalId() cache.CloudaccountId = cloudaccountId return cache, manager.TableSpec().Insert(ctx, cache) @@ -136,7 +149,7 @@ func (self *SCloudgroupcache) syncWithCloudgroupcache(ctx context.Context, userC _, err := db.Update(self, func() error { self.Name = iGroup.GetName() self.Description = iGroup.GetDescription() - self.Status = api.CLOUD_GROUP_STATUS_AVAILABLE + self.Status = api.CLOUD_GROUP_CACHE_STATUS_AVAILABLE return nil }) return err @@ -271,7 +284,7 @@ func (self *SCloudgroupcache) GetOrCreateICloudgroup(ctx context.Context, userCr } _, err = db.Update(self, func() error { self.ExternalId = iGroup.GetGlobalId() - self.Status = api.CLOUD_GROUP_STATUS_AVAILABLE + self.Status = api.CLOUD_GROUP_CACHE_STATUS_AVAILABLE return nil }) if err != nil { diff --git a/pkg/cloudid/options/options.go b/pkg/cloudid/options/options.go index 712035bcbc..640a682d97 100644 --- a/pkg/cloudid/options/options.go +++ b/pkg/cloudid/options/options.go @@ -32,3 +32,14 @@ type SCloudIdOptions struct { var ( Options SCloudIdOptions ) + +func OnOptionsChange(oldO, newO interface{}) bool { + oldOpts := oldO.(*SCloudIdOptions) + newOpts := newO.(*SCloudIdOptions) + + changed := false + if common_options.OnCommonOptionsChange(&oldOpts.CommonOptions, &newOpts.CommonOptions) { + changed = true + } + return changed +} diff --git a/pkg/cloudid/service/service.go b/pkg/cloudid/service/service.go index 5b3d28ddd0..8edd05dace 100644 --- a/pkg/cloudid/service/service.go +++ b/pkg/cloudid/service/service.go @@ -20,7 +20,7 @@ import ( "yunion.io/x/log" - "yunion.io/x/onecloud/pkg/apis/cloudid" + api "yunion.io/x/onecloud/pkg/apis/cloudid" "yunion.io/x/onecloud/pkg/cloudcommon" common_app "yunion.io/x/onecloud/pkg/cloudcommon/app" "yunion.io/x/onecloud/pkg/cloudcommon/cronman" @@ -39,11 +39,12 @@ func StartService() { dbOpts := &opts.DBOptions baseOpts := &opts.BaseOptions commonOpts := &opts.CommonOptions - common_options.ParseOptions(opts, os.Args, "cloudid.conf", cloudid.SERVICE_TYPE) + common_options.ParseOptions(opts, os.Args, "cloudid.conf", api.SERVICE_TYPE) common_app.InitAuth(commonOpts, func() { log.Infof("Auth complete!!") }) + common_options.StartOptionManager(opts, opts.ConfigSyncPeriodSeconds, api.SERVICE_TYPE, api.SERVICE_VERSION, options.OnOptionsChange) app := common_app.InitApp(baseOpts, false) InitHandlers(app) @@ -51,7 +52,7 @@ func StartService() { db.EnsureAppInitSyncDB(app, dbOpts, models.InitDB) defer cloudcommon.CloseDB() - err := saml.InitSAML(app, cloudid.SAML_IDP_PREFIX) + err := saml.InitSAML(app, api.SAML_IDP_PREFIX) if err != nil { log.Errorf("SAML initialization fail %s", err) return diff --git a/pkg/cloudid/tasks/cloudgroup_sync_status_task.go b/pkg/cloudid/tasks/cloudgroup_sync_status_task.go new file mode 100644 index 0000000000..9b586a21e3 --- /dev/null +++ b/pkg/cloudid/tasks/cloudgroup_sync_status_task.go @@ -0,0 +1,66 @@ +// 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 tasks + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + api "yunion.io/x/onecloud/pkg/apis/cloudid" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudid/models" +) + +type CloudgroupSyncstatusTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(CloudgroupSyncstatusTask{}) +} + +func (self *CloudgroupSyncstatusTask) taskFailed(ctx context.Context, group *models.SCloudgroup, err error) { + group.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_AVAILABLE, err.Error()) + self.SetStageFailed(ctx, jsonutils.NewString(err.Error())) +} + +func (self *CloudgroupSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { + group := obj.(*models.SCloudgroup) + + caches, err := group.GetCloudgroupcaches() + if err != nil { + self.taskFailed(ctx, group, errors.Wrapf(err, "GetCloudgroupcaches")) + return + } + + for i := range caches { + if len(caches[i].ExternalId) > 0 { + _, err := caches[i].GetICloudgroup() + if err != nil { + caches[i].SetStatus(self.GetUserCred(), api.CLOUD_GROUP_CACHE_STATUS_UNKNOWN, errors.Wrap(err, "GetICloudgroup").Error()) + continue + } + if caches[i].Status != api.CLOUD_GROUP_CACHE_STATUS_AVAILABLE { + caches[i].SetStatus(self.GetUserCred(), api.CLOUD_GROUP_CACHE_STATUS_AVAILABLE, "") + } + } + } + + group.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_AVAILABLE, "") + self.SetStageComplete(ctx, nil) +} diff --git a/pkg/cloudid/tasks/cloudgroupcache_sync_status_task.go b/pkg/cloudid/tasks/cloudgroupcache_sync_status_task.go index 33d78bb54d..696ab513b8 100644 --- a/pkg/cloudid/tasks/cloudgroupcache_sync_status_task.go +++ b/pkg/cloudid/tasks/cloudgroupcache_sync_status_task.go @@ -48,5 +48,6 @@ func (self *CloudgroupcacheSyncstatusTask) OnInit(ctx context.Context, obj db.IS self.taskFailed(ctx, cache, errors.Wrap(err, "GetICloudgroup")) return } + cache.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_CACHE_STATUS_AVAILABLE, "") self.SetStageComplete(ctx, nil) } diff --git a/pkg/multicloud/aliyun/ram_user.go b/pkg/multicloud/aliyun/ram_user.go index 99f4bfca7b..f597702433 100644 --- a/pkg/multicloud/aliyun/ram_user.go +++ b/pkg/multicloud/aliyun/ram_user.go @@ -86,7 +86,16 @@ func (user *SUser) Delete() error { } func (user *SUser) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) { - return []cloudprovider.ICloudgroup{}, nil + groups, err := user.client.ListGroupsForUser(user.UserName) + if err != nil { + return nil, errors.Wrapf(err, "ListGroupsForUser") + } + ret := []cloudprovider.ICloudgroup{} + for i := range groups { + groups[i].client = user.client + ret = append(ret, &groups[i]) + } + return ret, nil } func (user *SUser) UpdatePassword(password string) error { diff --git a/pkg/multicloud/aliyun/shell/ram_user.go b/pkg/multicloud/aliyun/shell/ram_user.go index a30c9f6d0f..a82c54419b 100644 --- a/pkg/multicloud/aliyun/shell/ram_user.go +++ b/pkg/multicloud/aliyun/shell/ram_user.go @@ -67,6 +67,15 @@ func init() { NAME string } + shellutils.R(&ClouduserOptions{}, "cloud-user-group-list", "List Cloud user groups", func(cli *aliyun.SRegion, args *ClouduserOptions) error { + groups, err := cli.GetClient().ListGroupsForUser(args.NAME) + if err != nil { + return err + } + printList(groups, 0, 0, 0, nil) + return nil + }) + shellutils.R(&ClouduserOptions{}, "cloud-user-delete", "Delete Cloud user", func(cli *aliyun.SRegion, args *ClouduserOptions) error { return cli.GetClient().DeleteClouduser(args.NAME) }) diff --git a/pkg/multicloud/aws/iam_user.go b/pkg/multicloud/aws/iam_user.go index 730b44b23e..b5bb1353d8 100644 --- a/pkg/multicloud/aws/iam_user.go +++ b/pkg/multicloud/aws/iam_user.go @@ -78,7 +78,16 @@ func (user *SUser) IsConsoleLogin() bool { } func (user *SUser) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) { - return []cloudprovider.ICloudgroup{}, nil + groups, err := user.ListGroups() + if err != nil { + return nil, errors.Wrapf(err, "ListGroups") + } + ret := []cloudprovider.ICloudgroup{} + for i := range groups { + groups[i].client = user.client + ret = append(ret, &groups[i]) + } + return ret, nil } func (self *SUser) ListPolicies() ([]SAttachedPolicy, error) {