diff --git a/pkg/cloudcommon/db/modelbase.go b/pkg/cloudcommon/db/modelbase.go index fa7a772f3c..bb1faf3012 100644 --- a/pkg/cloudcommon/db/modelbase.go +++ b/pkg/cloudcommon/db/modelbase.go @@ -33,6 +33,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/policy" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/logclient" "yunion.io/x/onecloud/pkg/util/splitable" "yunion.io/x/onecloud/pkg/util/stringutils2" ) @@ -517,6 +518,9 @@ func (manager *SModelBaseManager) GetPropertySplitableExport(ctx context.Context if err != nil { return nil, errors.Wrapf(err, "q.AllStringMap") } + exportId := fmt.Sprintf("%s(%d-%d)", metas[i].Table, metas[i].Start, metas[i].End) + obj := logclient.NewSimpleObject(exportId, exportId, manager.Keyword()) + logclient.AddActionLogWithContext(ctx, obj, logclient.ACT_EXPORT, nil, userCred, true) return jsonutils.Marshal(resp), nil } } diff --git a/pkg/keystone/models/policies.go b/pkg/keystone/models/policies.go index bcf0172dc7..2e33979e4a 100644 --- a/pkg/keystone/models/policies.go +++ b/pkg/keystone/models/policies.go @@ -242,7 +242,7 @@ func (manager *SPolicyManager) FetchEnabledPolicies() ([]SPolicy, error) { } func validatePolicyVioldatePrivilege(userCred mcclient.TokenCredential, policyScope rbacscope.TRbacScope, policy *rbacutils.SPolicy) error { - if options.Options.NoPolicyViolationCheck { + if options.Options.NoPolicyViolationCheck || options.Options.ThreeAdminRoleSystem { return nil } if userCred.GetUserName() == api.SystemAdminUser && userCred.GetDomainId() == api.DEFAULT_DOMAIN_ID { diff --git a/pkg/keystone/models/projects.go b/pkg/keystone/models/projects.go index 3a295ee9b3..199bcba6ac 100644 --- a/pkg/keystone/models/projects.go +++ b/pkg/keystone/models/projects.go @@ -568,10 +568,41 @@ func (self *SProject) PostCreate( } } +func threeMemberSystemValidateJoinProject(userCred mcclient.TokenCredential, project *SProject, roleIds []string) error { + _, assignPolicies, _ := RolePolicyManager.GetMatchPolicyGroup2(false, roleIds, project.Id, "", time.Time{}, false) + assignScope := assignPolicies.HighestScope() + var checkRoles []string + if assignScope == rbacscope.ScopeSystem { + checkRoles = options.Options.SystemThreeAdminRoleNames + } else if assignScope == rbacscope.ScopeDomain { + checkRoles = options.Options.DomainThreeAdminRoleNames + } else { + return nil + } + var contains []string + for _, roleName := range checkRoles { + role, err := RoleManager.FetchRoleByName(roleName, "", "") + if err != nil { + return httperrors.NewResourceNotFoundError2(RoleManager.Keyword(), roleName) + } + _, adminPolicies, _ := RolePolicyManager.GetMatchPolicyGroup2(false, []string{role.Id}, project.Id, "", time.Time{}, false) + if adminPolicies[assignScope].Contains(assignPolicies[assignScope]) { + contains = append(contains, roleName) + } + } + if len(contains) != 1 { + return errors.Wrapf(httperrors.ErrNotSufficientPrivilege, "assigning roles violates three-member policy: %s", contains) + } + return nil +} + func validateJoinProject(userCred mcclient.TokenCredential, project *SProject, roleIds []string) error { if options.Options.NoPolicyViolationCheck { return nil } + if options.Options.ThreeAdminRoleSystem { + return threeMemberSystemValidateJoinProject(userCred, project, roleIds) + } _, opsPolicies, _ := RolePolicyManager.GetMatchPolicyGroup(userCred, time.Time{}, false) _, assignPolicies, _ := RolePolicyManager.GetMatchPolicyGroup2(false, roleIds, project.Id, "", time.Time{}, false) opsScope := opsPolicies.HighestScope() diff --git a/pkg/keystone/options/options.go b/pkg/keystone/options/options.go index ee89039450..5fd9660007 100644 --- a/pkg/keystone/options/options.go +++ b/pkg/keystone/options/options.go @@ -66,6 +66,10 @@ type SKeystoneOptions struct { NoPolicyViolationCheck bool `help:"do not check policy violation when modify or assign policy" default:"false"` + ThreeAdminRoleSystem bool `help:"do not check policy violation when modify or assign policy" default:"false"` + SystemThreeAdminRoleNames []string `help:"Name of system three-admin roles" default:"sys_secadmin,sys_opsadmin,sys_adtadmin"` + DomainThreeAdminRoleNames []string `help:"Name of system three-admin roles" default:"domain_secadmin,domain_opsadmin,domain_adtadmin"` + LdapSearchPageSize uint32 `help:"pagination size for LDAP search" default:"100"` ProjectAdminRole string `help:"name of role to be saved as admin user of project" default:"project_owner"` diff --git a/pkg/util/logclient/consts.go b/pkg/util/logclient/consts.go index 443f0c7255..a939cb5fe7 100644 --- a/pkg/util/logclient/consts.go +++ b/pkg/util/logclient/consts.go @@ -242,4 +242,6 @@ const ( ACT_IP_MAC_BIND = "ip_mac_bind" // 程序内初始化notifyconfigmap错误 ACT_INIT_NOTIFY_CONFIGMAP = "init_notify_configmap" + + ACT_EXPORT = "export" ) diff --git a/pkg/util/logclient/logclient.go b/pkg/util/logclient/logclient.go index 99597593c4..e37a892435 100644 --- a/pkg/util/logclient/logclient.go +++ b/pkg/util/logclient/logclient.go @@ -128,7 +128,10 @@ func AddActionLogWithStartable2(task IStartable, model IObject, action string, i // } func addLog(model IObject, action string, iNotes interface{}, userCred mcclient.TokenCredential, success bool, startTime time.Time, module IModule, severity api.TEventSeverity, kind api.TEventKind) { - if !consts.OpsLogEnabled() { + // avoid log loop + if !consts.OpsLogEnabled() && utils.IsInStringArray(action, []string{ + ACT_CREATE, + }) { return } if ok, _ := utils.InStringArray(model.Keyword(), BLACK_LIST_OBJ_TYPE); ok {