mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
Merge pull request #2357 from swordqiu/hotfix/qj-new-apis-for-project-user-group-roles
fix: deprecate old user/group joint project API, create new action apis
This commit is contained in:
@@ -17,6 +17,7 @@ package shell
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
@@ -133,4 +134,61 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&GroupShowOptions{}, "group-project-list", "List projects of group", func(s *mcclient.ClientSession, args *GroupShowOptions) error {
|
||||
query := jsonutils.NewDict()
|
||||
if len(args.Domain) > 0 {
|
||||
domainId, err := modules.Domains.GetId(s, args.Domain, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
query.Add(jsonutils.NewString(domainId), "domain_id")
|
||||
}
|
||||
uid, err := modules.Groups.GetId(s, args.ID, query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
projects, e := modules.Groups.GetProjects(s, uid)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
printList(projects, modules.Projects.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
type GroupJoinProjectOptions struct {
|
||||
Group string `help:"Group Id or name" optional:"false" positional:"true"`
|
||||
Project []string `help:"Projects to join" nargs:"+"`
|
||||
Role []string `help:"User join project with roles" nargs:"+"`
|
||||
}
|
||||
R(&GroupJoinProjectOptions{}, "group-join-project", "Group join projects with roles", func(s *mcclient.ClientSession, args *GroupJoinProjectOptions) error {
|
||||
input := api.SJoinProjectsInput{}
|
||||
input.Projects = args.Project
|
||||
input.Roles = args.Role
|
||||
result, err := modules.Groups.PerformAction(s, args.Group, "join", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type GroupLeaveProjectsOptions struct {
|
||||
Group string `help:"group id or name" optional:"false" positional:"true"`
|
||||
Project string `help:"project id or name" optional:"false" positional:"true"`
|
||||
Role []string `help:"roles to remove" nargs:"+"`
|
||||
}
|
||||
R(&GroupLeaveProjectsOptions{}, "group-leave-project", "Leave a group from projects", func(s *mcclient.ClientSession, args *GroupLeaveProjectsOptions) error {
|
||||
input := api.SLeaveProjectsInput{}
|
||||
input.ProjectRoles = make([]api.SProjectRole, len(args.Role))
|
||||
for i := range args.Role {
|
||||
input.ProjectRoles[i].Project = args.Project
|
||||
input.ProjectRoles[i].Role = args.Role[i]
|
||||
}
|
||||
result, err := modules.Groups.PerformAction(s, args.Group, "leave", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package shell
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
@@ -364,6 +365,7 @@ func init() {
|
||||
return nil
|
||||
})*/
|
||||
|
||||
// Deprecated
|
||||
type ProjectBatchJoinOptions struct {
|
||||
Ids []string `help:"user ids or group ids"`
|
||||
Resource string `help:"resource type" choices:"users|groups"`
|
||||
@@ -378,4 +380,55 @@ func init() {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
type ProjectAddUserGroupOptions struct {
|
||||
Project string `help:"ID or name of project to add users/groups" positional:"true" optional:"false"`
|
||||
User []string `help:"ID of user to add"`
|
||||
Group []string `help:"ID of group to add"`
|
||||
Role []string `help:"ID of role to add"`
|
||||
}
|
||||
R(&ProjectAddUserGroupOptions{}, "project-add-user-group", "Batch add users/groups to project", func(s *mcclient.ClientSession, args *ProjectAddUserGroupOptions) error {
|
||||
input := api.SProjectAddUserGroupInput{}
|
||||
input.Users = args.User
|
||||
input.Groups = args.Group
|
||||
input.Roles = args.Role
|
||||
err := input.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Projects.PerformAction(s, args.Project, "join", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type ProjectRemoveUserGroup struct {
|
||||
Project string `help:"ID or name of project to remove user/group" optional:"false" positional:"true"`
|
||||
User string `help:"user to remove"`
|
||||
Group string `help:"group to remove"`
|
||||
Role []string `help:"roles to remove"`
|
||||
}
|
||||
R(&ProjectRemoveUserGroup{}, "project-remove-user-group", "Remove users/groups from project", func(s *mcclient.ClientSession, args *ProjectRemoveUserGroup) error {
|
||||
input := api.SProjectRemoveUserGroupInput{}
|
||||
input.UserRoles = make([]api.SUserRole, len(args.Role))
|
||||
input.GroupRoles = make([]api.SGroupRole, len(args.Role))
|
||||
for i := range args.Role {
|
||||
input.UserRoles[i].User = args.User
|
||||
input.UserRoles[i].Role = args.Role[i]
|
||||
input.GroupRoles[i].Group = args.Group
|
||||
input.GroupRoles[i].Role = args.Role[i]
|
||||
}
|
||||
err := input.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Projects.PerformAction(s, args.Project, "leave", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package shell
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
@@ -361,4 +362,41 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type UserJoinProjectOptions struct {
|
||||
User string `help:"User Id or name" optional:"false" positional:"true"`
|
||||
Project []string `help:"Projects to join" nargs:"+"`
|
||||
Role []string `help:"User join project with roles" nargs:"+"`
|
||||
}
|
||||
R(&UserJoinProjectOptions{}, "user-join-project", "User join projects with roles", func(s *mcclient.ClientSession, args *UserJoinProjectOptions) error {
|
||||
input := api.SJoinProjectsInput{}
|
||||
input.Projects = args.Project
|
||||
input.Roles = args.Role
|
||||
result, err := modules.UsersV3.PerformAction(s, args.User, "join", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type UserLeaveProjectsOptions struct {
|
||||
User string `help:"user id or name" optional:"false" positional:"true"`
|
||||
Project string `help:"project id or name" optional:"false" positional:"true"`
|
||||
Role []string `help:"roles to remove" nargs:"+"`
|
||||
}
|
||||
R(&UserLeaveProjectsOptions{}, "user-leave-project", "Leave a user from projects", func(s *mcclient.ClientSession, args *UserLeaveProjectsOptions) error {
|
||||
input := api.SLeaveProjectsInput{}
|
||||
input.ProjectRoles = make([]api.SProjectRole, len(args.Role))
|
||||
for i := range args.Role {
|
||||
input.ProjectRoles[i].Project = args.Project
|
||||
input.ProjectRoles[i].Role = args.Role[i]
|
||||
}
|
||||
result, err := modules.UsersV3.PerformAction(s, args.User, "leave", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
post:
|
||||
summary: 将组以多个角色加入多个项目
|
||||
parameters:
|
||||
- $ref: '../parameters/group.yaml#/group_id'
|
||||
- name: group
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectJoinRequestInput"
|
||||
responses:
|
||||
200:
|
||||
description: 组信息
|
||||
schema:
|
||||
$ref: "../schemas/group.yaml#/GroupGetResponse"
|
||||
tags:
|
||||
- groups
|
||||
@@ -0,0 +1,16 @@
|
||||
post:
|
||||
summary: 将组的多个角色从多个项目中删除
|
||||
parameters:
|
||||
- $ref: '../parameters/group.yaml#/group_id'
|
||||
- name: group
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectLeaveRequestInput"
|
||||
responses:
|
||||
200:
|
||||
description: 组信息
|
||||
schema:
|
||||
$ref: "../schemas/group.yaml#/GroupGetResponse"
|
||||
tags:
|
||||
- groups
|
||||
@@ -0,0 +1,16 @@
|
||||
post:
|
||||
summary: 将多个用户和组以多个角色加入指定项目
|
||||
parameters:
|
||||
- $ref: '../parameters/project.yaml#/project_id'
|
||||
- name: project
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectJoinUserGroupRequestInput"
|
||||
responses:
|
||||
200:
|
||||
description: 项目信息
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectGetResponse"
|
||||
tags:
|
||||
- projects
|
||||
@@ -0,0 +1,16 @@
|
||||
post:
|
||||
summary: 将多个用户和组以多个角色从指定项目删除
|
||||
parameters:
|
||||
- $ref: '../parameters/project.yaml#/project_id'
|
||||
- name: project
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectRemoveUserGroupRequestInput"
|
||||
responses:
|
||||
200:
|
||||
description: 项目信息
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectGetResponse"
|
||||
tags:
|
||||
- projects
|
||||
@@ -1,4 +1,5 @@
|
||||
put:
|
||||
deprecated: true
|
||||
summary: 将组以指定角色加入项目
|
||||
parameters:
|
||||
- $ref: '../parameters/identity.yaml#/project_id'
|
||||
@@ -11,6 +12,7 @@ put:
|
||||
- roles
|
||||
|
||||
delete:
|
||||
deprecated: true
|
||||
summary: 将组在项目中的角色删除
|
||||
parameters:
|
||||
- $ref: '../parameters/identity.yaml#/project_id'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
put:
|
||||
deprecated: true
|
||||
summary: 将用户以指定角色加入项目
|
||||
parameters:
|
||||
- $ref: '../parameters/identity.yaml#/project_id'
|
||||
@@ -11,6 +12,7 @@ put:
|
||||
- roles
|
||||
|
||||
delete:
|
||||
deprecated: true
|
||||
summary: 将用户在项目中的角色删除
|
||||
parameters:
|
||||
- $ref: '../parameters/identity.yaml#/project_id'
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
post:
|
||||
summary: 将用户以多个角色加入多个项目
|
||||
parameters:
|
||||
- $ref: '../parameters/user.yaml#/user_id'
|
||||
- name: user
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectJoinRequestInput"
|
||||
responses:
|
||||
200:
|
||||
description: 用户信息
|
||||
schema:
|
||||
$ref: "../schemas/user.yaml#/UserGetResponse"
|
||||
tags:
|
||||
- users
|
||||
@@ -0,0 +1,16 @@
|
||||
post:
|
||||
summary: 将用户的多个角色从多个项目中删除
|
||||
parameters:
|
||||
- $ref: '../parameters/user.yaml#/user_id'
|
||||
- name: user
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../schemas/project.yaml#/ProjectLeaveRequestInput"
|
||||
responses:
|
||||
200:
|
||||
description: 用户信息
|
||||
schema:
|
||||
$ref: "../schemas/user.yaml#/UserGetResponse"
|
||||
tags:
|
||||
- users
|
||||
@@ -312,11 +312,19 @@ paths:
|
||||
$ref: "./identity/users.yaml"
|
||||
/users/{user_id}:
|
||||
$ref: "./identity/user.yaml"
|
||||
/users/{user_id}/join:
|
||||
$ref: "./identity/user_join.yaml"
|
||||
/users/{user_id}/leave:
|
||||
$ref: "./identity/user_leave.yaml"
|
||||
|
||||
/groups:
|
||||
$ref: "./identity/groups.yaml"
|
||||
/groups/{group_id}:
|
||||
$ref: "./identity/group.yaml"
|
||||
/groups/{group_id}/join:
|
||||
$ref: "./identity/group_join.yaml"
|
||||
/groups/{group_id}/leave:
|
||||
$ref: "./identity/group_leave.yaml"
|
||||
/groups/{group_id}/users/{user_id}:
|
||||
$ref: "./identity/groupuser.yaml"
|
||||
|
||||
@@ -324,6 +332,10 @@ paths:
|
||||
$ref: "./identity/projects.yaml"
|
||||
/projects/{project_id}:
|
||||
$ref: "./identity/project.yaml"
|
||||
/projects/{project_id}/join:
|
||||
$ref: "./identity/project_join.yaml"
|
||||
/projects/{project_id}/leave:
|
||||
$ref: "./identity/project_leave.yaml"
|
||||
|
||||
/roles:
|
||||
$ref: "./identity/roles.yaml"
|
||||
|
||||
@@ -57,3 +57,84 @@ Project:
|
||||
can_delete:
|
||||
type: boolean
|
||||
description: 是否可以删除
|
||||
|
||||
ProjectJoinRequestInput:
|
||||
type: object
|
||||
description: 用户或组批量加入项目的请求body
|
||||
properties:
|
||||
projects:
|
||||
type: array
|
||||
description: 项目列表
|
||||
items:
|
||||
type: string
|
||||
roles:
|
||||
type: array
|
||||
description: 角色列表
|
||||
items:
|
||||
type: string
|
||||
|
||||
ProjectLeaveRequestInput:
|
||||
type: object
|
||||
description: 用户或组批量移除项目的请求body
|
||||
properties:
|
||||
project_roles:
|
||||
type: array
|
||||
description: 移除的项目和角色列表
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
project:
|
||||
type: string
|
||||
description: 项目ID或名称
|
||||
role:
|
||||
type: string
|
||||
description: 角色ID或名称
|
||||
|
||||
ProjectJoinUserGroupRequestInput:
|
||||
type: object
|
||||
description: 将多个用户或组批量加入指定项目的请求body
|
||||
properties:
|
||||
users:
|
||||
type: array
|
||||
description: 加入的用户列表
|
||||
items:
|
||||
type: string
|
||||
groups:
|
||||
type: array
|
||||
description: 加入的组列表
|
||||
items:
|
||||
type: string
|
||||
roles:
|
||||
type: array
|
||||
description: 加入的角色列表
|
||||
items:
|
||||
type: string
|
||||
|
||||
ProjectRemoveUserGroupRequestInput:
|
||||
type: object
|
||||
description: 将多个用户或组从指定项目移除的请求body
|
||||
properties:
|
||||
user_roles:
|
||||
type: array
|
||||
description: 用户和角色列表
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
type: string
|
||||
description: 用户ID或名称
|
||||
role:
|
||||
type: string
|
||||
description: 角色ID或名称
|
||||
group_roles:
|
||||
type: array
|
||||
description: 组和角色列表
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
group:
|
||||
type: string
|
||||
description: 组ID或名称
|
||||
role:
|
||||
type: string
|
||||
description: 角色ID或名称
|
||||
|
||||
@@ -153,6 +153,6 @@ require (
|
||||
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d
|
||||
yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224
|
||||
yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e
|
||||
yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe
|
||||
yunion.io/x/sqlchemy v0.0.0-20190817082003-905772542cba
|
||||
yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3
|
||||
)
|
||||
|
||||
@@ -587,7 +587,7 @@ yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224 h1:dAeUov/CtKcPaOapGVG7+NRqmU
|
||||
yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e h1:Jk82txl4vaL/MoVV3+GweEcCmLOcqo5XYF8tlBD/1hY=
|
||||
yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
||||
yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe h1:gslRYwVFAQI29PZL56mfBe+zpgbtIMSL1zSEnBbF1bI=
|
||||
yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/sqlchemy v0.0.0-20190817082003-905772542cba h1:vPCRA59Kq9Hv24ef/G92sCgqmBYmZyLSVP902EUDimw=
|
||||
yunion.io/x/sqlchemy v0.0.0-20190817082003-905772542cba/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3 h1:bfC8EhXYvyGYldRWlzxiCM39Zfj3s3+zham9mW2h2LE=
|
||||
yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
// 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 identity
|
||||
|
||||
import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SJoinProjectsInput struct {
|
||||
Projects []string
|
||||
Roles []string
|
||||
}
|
||||
|
||||
func (input SJoinProjectsInput) Validate() error {
|
||||
if len(input.Projects) == 0 {
|
||||
return errors.Error("empty projects")
|
||||
}
|
||||
if len(input.Roles) == 0 {
|
||||
return errors.Error("empty roles")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SProjectRole struct {
|
||||
Project string
|
||||
Role string
|
||||
}
|
||||
type SLeaveProjectsInput struct {
|
||||
ProjectRoles []SProjectRole
|
||||
}
|
||||
|
||||
func (input SLeaveProjectsInput) Validate() error {
|
||||
if len(input.ProjectRoles) == 0 {
|
||||
return errors.Error("empty project_roles")
|
||||
}
|
||||
for i := range input.ProjectRoles {
|
||||
if len(input.ProjectRoles[i].Project) == 0 {
|
||||
return errors.Error("no project in project_roles")
|
||||
}
|
||||
if len(input.ProjectRoles[i].Role) == 0 {
|
||||
return errors.Error("no role in project_roles")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SProjectAddUserGroupInput struct {
|
||||
Users []string
|
||||
Groups []string
|
||||
Roles []string
|
||||
}
|
||||
|
||||
func (input SProjectAddUserGroupInput) Validate() error {
|
||||
if len(input.Users) == 0 && len(input.Groups) == 0 {
|
||||
return errors.Error("empty user and group")
|
||||
}
|
||||
if len(input.Roles) == 0 {
|
||||
return errors.Error("invalid roles")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SUserRole struct {
|
||||
User string
|
||||
Role string
|
||||
}
|
||||
type SGroupRole struct {
|
||||
Group string
|
||||
Role string
|
||||
}
|
||||
|
||||
type SProjectRemoveUserGroupInput struct {
|
||||
UserRoles []SUserRole
|
||||
GroupRoles []SGroupRole
|
||||
}
|
||||
|
||||
func (input SProjectRemoveUserGroupInput) Validate() error {
|
||||
if len(input.UserRoles) == 0 && len(input.GroupRoles) == 0 {
|
||||
return errors.Error("empty input")
|
||||
}
|
||||
for i := range input.UserRoles {
|
||||
if len(input.UserRoles[i].User) == 0 {
|
||||
return errors.Error("empty user")
|
||||
}
|
||||
if len(input.UserRoles[i].Role) == 0 {
|
||||
return errors.Error("empty role")
|
||||
}
|
||||
}
|
||||
for i := range input.GroupRoles {
|
||||
if len(input.GroupRoles[i].Group) == 0 {
|
||||
return errors.Error("empty group")
|
||||
}
|
||||
if len(input.GroupRoles[i].Role) == 0 {
|
||||
return errors.Error("empty role")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -417,7 +417,7 @@ func fetchContextObject(manager IModelManager, ctx context.Context, userCred mcc
|
||||
return nil, httperrors.NewInternalServerError("No context manager")
|
||||
}
|
||||
for i := 0; i < len(ctxMans); i += 1 {
|
||||
for j := 0; j < len(ctxMans); j += 1 {
|
||||
for j := 0; j < len(ctxMans[i]); j += 1 {
|
||||
if ctxMans[i][j].KeywordPlural() == ctxId.Type {
|
||||
ctxObj, err := fetchItem(ctxMans[i][j], ctx, userCred, ctxId.Id, nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// 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 (
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// 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 (
|
||||
|
||||
@@ -259,11 +259,12 @@ func (manager *SAssignmentManager) projectAddUser(ctx context.Context, userCred
|
||||
}
|
||||
}
|
||||
err = manager.add(api.AssignmentUserProject, user.Id, project.Id, role.Id)
|
||||
if err == nil {
|
||||
db.OpsLog.LogEvent(user, db.ACT_ATTACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_ATTACH, user.GetShortDesc(ctx), userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.add")
|
||||
}
|
||||
return err
|
||||
db.OpsLog.LogEvent(user, db.ACT_ATTACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_ATTACH, user.GetShortDesc(ctx), userCred)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SAssignmentManager) batchRemove(actorId string, typeStrs []string) error {
|
||||
@@ -333,11 +334,12 @@ func (manager *SAssignmentManager) projectRemoveUser(ctx context.Context, userCr
|
||||
}
|
||||
}
|
||||
err := manager.remove(api.AssignmentUserProject, user.Id, project.Id, role.Id)
|
||||
if err == nil {
|
||||
db.OpsLog.LogEvent(user, db.ACT_DETACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_DETACH, user.GetShortDesc(ctx), userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.remove")
|
||||
}
|
||||
return err
|
||||
db.OpsLog.LogEvent(user, db.ACT_DETACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_DETACH, user.GetShortDesc(ctx), userCred)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SAssignmentManager) projectAddGroup(ctx context.Context, userCred mcclient.TokenCredential, project *SProject, group *SGroup, role *SRole) error {
|
||||
@@ -357,11 +359,12 @@ func (manager *SAssignmentManager) projectAddGroup(ctx context.Context, userCred
|
||||
}
|
||||
}
|
||||
err = manager.add(api.AssignmentGroupProject, group.Id, project.Id, role.Id)
|
||||
if err == nil {
|
||||
db.OpsLog.LogEvent(group, db.ACT_ATTACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_ATTACH, group.GetShortDesc(ctx), userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.add")
|
||||
}
|
||||
return err
|
||||
db.OpsLog.LogEvent(group, db.ACT_ATTACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_ATTACH, group.GetShortDesc(ctx), userCred)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SAssignmentManager) projectRemoveGroup(ctx context.Context, userCred mcclient.TokenCredential, project *SProject, group *SGroup, role *SRole) error {
|
||||
@@ -378,11 +381,12 @@ func (manager *SAssignmentManager) projectRemoveGroup(ctx context.Context, userC
|
||||
}
|
||||
}
|
||||
err := manager.remove(api.AssignmentGroupProject, group.Id, project.Id, role.Id)
|
||||
if err == nil {
|
||||
db.OpsLog.LogEvent(group, db.ACT_DETACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_DETACH, group.GetShortDesc(ctx), userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "manager.remove")
|
||||
}
|
||||
return err
|
||||
db.OpsLog.LogEvent(group, db.ACT_DETACH, project.GetShortDesc(ctx), userCred)
|
||||
db.OpsLog.LogEvent(project, db.ACT_DETACH, group.GetShortDesc(ctx), userCred)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SAssignmentManager) remove(typeStr, actorId, projectId, roleId string) error {
|
||||
@@ -412,7 +416,11 @@ func (manager *SAssignmentManager) add(typeStr, actorId, projectId, roleId strin
|
||||
Inherited: tristate.False,
|
||||
}
|
||||
assign.SetModelManager(manager, &assign)
|
||||
return manager.TableSpec().InsertOrUpdate(&assign)
|
||||
err := manager.TableSpec().InsertOrUpdate(&assign)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "InsertOrUpdate")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddAdhocHandlers(version string, app *appsrv.Application) {
|
||||
|
||||
@@ -278,3 +278,45 @@ func (manager *SGroupManager) FetchGroupsInDomain(domainId string, excludes []st
|
||||
func (group *SGroup) UnlinkIdp(idpId string) error {
|
||||
return IdmappingManager.deleteAny(idpId, api.IdMappingEntityGroup, group.Id)
|
||||
}
|
||||
|
||||
func (group *SGroup) AllowPerformJoin(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) bool {
|
||||
return db.IsAdminAllowPerform(userCred, group, "join")
|
||||
}
|
||||
|
||||
func (group *SGroup) PerformJoin(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
err := joinProjects(group, false, ctx, userCred, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (group *SGroup) AllowPerformLeave(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) bool {
|
||||
return db.IsAdminAllowPerform(userCred, group, "leave")
|
||||
}
|
||||
|
||||
func (group *SGroup) PerformLeave(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
err := leaveProjects(group, false, ctx, userCred, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -89,9 +89,9 @@ func (model *SIdentityBaseResource) GetIIdentityModel() IIdentityModel {
|
||||
return model.GetVirtualObject().(IIdentityModel)
|
||||
}
|
||||
|
||||
func (model *SIdentityBaseResource) IsOwner(userCred mcclient.TokenCredential) bool {
|
||||
return userCred.GetProjectDomainId() == model.DomainId
|
||||
}
|
||||
// func (model *SIdentityBaseResource) IsOwner(userCred mcclient.TokenCredential) bool {
|
||||
// return userCred.GetProjectDomainId() == model.DomainId
|
||||
// }
|
||||
|
||||
func (model *SIdentityBaseResource) GetDomain() *SDomain {
|
||||
if len(model.DomainId) > 0 && model.DomainId != api.KeystoneDomainRoot {
|
||||
@@ -109,11 +109,11 @@ func (manager *SIdentityBaseResourceManager) GetIIdentityModelManager() IIdentit
|
||||
}
|
||||
|
||||
func (manager *SIdentityBaseResourceManager) FetchByName(userCred mcclient.IIdentityProvider, idStr string) (db.IModel, error) {
|
||||
return db.FetchByName(manager, userCred, idStr)
|
||||
return db.FetchByName(manager.GetIIdentityModelManager(), userCred, idStr)
|
||||
}
|
||||
|
||||
func (manager *SIdentityBaseResourceManager) FetchByIdOrName(userCred mcclient.IIdentityProvider, idStr string) (db.IModel, error) {
|
||||
return db.FetchByIdOrName(manager, userCred, idStr)
|
||||
return db.FetchByIdOrName(manager.GetIIdentityModelManager(), userCred, idStr)
|
||||
}
|
||||
|
||||
func (manager *SIdentityBaseResourceManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
|
||||
|
||||
@@ -361,3 +361,154 @@ func (manager *SProjectManager) ValidateCreateData(ctx context.Context, userCred
|
||||
}
|
||||
return manager.SIdentityBaseResourceManager.ValidateCreateData(ctx, userCred, ownerId, query, data)
|
||||
}
|
||||
|
||||
func (project *SProject) AllowPerformJoin(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) bool {
|
||||
return db.IsAdminAllowPerform(userCred, project, "join")
|
||||
}
|
||||
|
||||
func (project *SProject) PerformJoin(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
input := api.SProjectAddUserGroupInput{}
|
||||
err := data.Unmarshal(&input)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("unmarshal project add user group input error %s", err)
|
||||
}
|
||||
err = input.Validate()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
roles := make([]*SRole, 0)
|
||||
for i := range input.Roles {
|
||||
obj, err := RoleManager.FetchByIdOrName(userCred, input.Roles[i])
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(RoleManager.Keyword(), input.Roles[i])
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
roles = append(roles, obj.(*SRole))
|
||||
}
|
||||
users := make([]*SUser, 0)
|
||||
for i := range input.Users {
|
||||
obj, err := UserManager.FetchByIdOrName(userCred, input.Users[i])
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(UserManager.Keyword(), input.Users[i])
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
users = append(users, obj.(*SUser))
|
||||
}
|
||||
groups := make([]*SGroup, 0)
|
||||
for i := range input.Groups {
|
||||
obj, err := GroupManager.FetchByIdOrName(userCred, input.Groups[i])
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(GroupManager.Keyword(), input.Groups[i])
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
groups = append(groups, obj.(*SGroup))
|
||||
}
|
||||
|
||||
for i := range users {
|
||||
for j := range roles {
|
||||
err = AssignmentManager.projectAddUser(ctx, userCred, project, users[i], roles[j])
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range groups {
|
||||
for j := range roles {
|
||||
err = AssignmentManager.projectAddGroup(ctx, userCred, project, groups[i], roles[j])
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (project *SProject) AllowPerformLeave(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) bool {
|
||||
return db.IsAdminAllowPerform(userCred, project, "leave")
|
||||
}
|
||||
|
||||
func (project *SProject) PerformLeave(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
input := api.SProjectRemoveUserGroupInput{}
|
||||
err := data.Unmarshal(&input)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("unmarshal project remove usergroup input error %s", err)
|
||||
}
|
||||
err = input.Validate()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
|
||||
for i := range input.UserRoles {
|
||||
userObj, err := UserManager.FetchByIdOrName(userCred, input.UserRoles[i].User)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(UserManager.Keyword(), input.UserRoles[i].User)
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
roleObj, err := RoleManager.FetchByIdOrName(userCred, input.UserRoles[i].Role)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(RoleManager.Keyword(), input.UserRoles[i].Role)
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
err = AssignmentManager.projectRemoveUser(ctx, userCred, project, userObj.(*SUser), roleObj.(*SRole))
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
for i := range input.GroupRoles {
|
||||
groupObj, err := GroupManager.FetchByIdOrName(userCred, input.GroupRoles[i].Group)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(GroupManager.Keyword(), input.GroupRoles[i].Group)
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
roleObj, err := RoleManager.FetchByIdOrName(userCred, input.GroupRoles[i].Role)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2(RoleManager.Keyword(), input.GroupRoles[i].Role)
|
||||
} else {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
err = AssignmentManager.projectRemoveGroup(ctx, userCred, project, groupObj.(*SGroup), roleObj.(*SRole))
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -682,3 +682,134 @@ func (manager *SUserManager) FetchUsersInDomain(domainId string, excludes []stri
|
||||
func (user *SUser) UnlinkIdp(idpId string) error {
|
||||
return IdmappingManager.deleteAny(idpId, api.IdMappingEntityUser, user.Id)
|
||||
}
|
||||
|
||||
func (user *SUser) AllowPerformJoin(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) bool {
|
||||
return db.IsAdminAllowPerform(userCred, user, "join")
|
||||
}
|
||||
|
||||
func (user *SUser) PerformJoin(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
err := joinProjects(user, true, ctx, userCred, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func joinProjects(ident db.IModel, isUser bool, ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) error {
|
||||
input := api.SJoinProjectsInput{}
|
||||
err := data.Unmarshal(&input)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError("unmarshal input error %s", err)
|
||||
}
|
||||
|
||||
err = input.Validate()
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
|
||||
projects := make([]*SProject, 0)
|
||||
roles := make([]*SRole, 0)
|
||||
|
||||
for i := range input.Projects {
|
||||
obj, err := ProjectManager.FetchByIdOrName(userCred, input.Projects[i])
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return httperrors.NewResourceNotFoundError2(ProjectManager.Keyword(), input.Projects[i])
|
||||
} else {
|
||||
return httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
projects = append(projects, obj.(*SProject))
|
||||
}
|
||||
for i := range input.Roles {
|
||||
obj, err := RoleManager.FetchByIdOrName(userCred, input.Roles[i])
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return httperrors.NewResourceNotFoundError2(RoleManager.Keyword(), input.Roles[i])
|
||||
} else {
|
||||
return httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
roles = append(roles, obj.(*SRole))
|
||||
}
|
||||
|
||||
for i := range projects {
|
||||
for j := range roles {
|
||||
if isUser {
|
||||
err = AssignmentManager.projectAddUser(ctx, userCred, projects[i], ident.(*SUser), roles[j])
|
||||
} else {
|
||||
err = AssignmentManager.projectAddGroup(ctx, userCred, projects[i], ident.(*SGroup), roles[j])
|
||||
}
|
||||
if err != nil {
|
||||
return httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (user *SUser) AllowPerformLeave(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) bool {
|
||||
return db.IsAdminAllowPerform(userCred, user, "leave")
|
||||
}
|
||||
|
||||
func (user *SUser) PerformLeave(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data jsonutils.JSONObject,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
err := leaveProjects(user, true, ctx, userCred, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func leaveProjects(ident db.IModel, isUser bool, ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) error {
|
||||
input := api.SLeaveProjectsInput{}
|
||||
err := data.Unmarshal(&input)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError("unmarshal leave porject input error: %s", err)
|
||||
}
|
||||
for i := range input.ProjectRoles {
|
||||
projObj, err := ProjectManager.FetchByIdOrName(userCred, input.ProjectRoles[i].Project)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return httperrors.NewResourceNotFoundError2(ProjectManager.Keyword(), input.ProjectRoles[i].Project)
|
||||
} else {
|
||||
return httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
roleObj, err := RoleManager.FetchByIdOrName(userCred, input.ProjectRoles[i].Role)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return httperrors.NewResourceNotFoundError2(RoleManager.Keyword(), input.ProjectRoles[i].Role)
|
||||
} else {
|
||||
return httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
if isUser {
|
||||
err = AssignmentManager.projectRemoveUser(ctx, userCred, projObj.(*SProject), ident.(*SUser), roleObj.(*SRole))
|
||||
} else {
|
||||
err = AssignmentManager.projectRemoveGroup(ctx, userCred, projObj.(*SProject), ident.(*SGroup), roleObj.(*SRole))
|
||||
}
|
||||
if err != nil {
|
||||
return httperrors.NewGeneralError(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -33,6 +33,11 @@ var (
|
||||
Groups GroupManager
|
||||
)
|
||||
|
||||
func (this *GroupManager) GetProjects(session *mcclient.ClientSession, uid string) (*ListResult, error) {
|
||||
url := fmt.Sprintf("/groups/%s/projects?admin=true", uid)
|
||||
return this._list(session, url, "projects")
|
||||
}
|
||||
|
||||
func init() {
|
||||
Groups = GroupManager{NewIdentityV3Manager("group", "groups",
|
||||
[]string{},
|
||||
|
||||
Vendored
+2
-2
@@ -775,6 +775,7 @@ yunion.io/x/pkg/util/regutils
|
||||
yunion.io/x/pkg/util/signalutils
|
||||
yunion.io/x/pkg/util/timeutils
|
||||
yunion.io/x/pkg/util/sets
|
||||
yunion.io/x/pkg/errors
|
||||
yunion.io/x/pkg/trace
|
||||
yunion.io/x/pkg/util/errors
|
||||
yunion.io/x/pkg/util/netutils
|
||||
@@ -784,7 +785,6 @@ yunion.io/x/pkg/tristate
|
||||
yunion.io/x/pkg/util/stringutils
|
||||
yunion.io/x/pkg/util/fileutils
|
||||
yunion.io/x/pkg/util/osprofile
|
||||
yunion.io/x/pkg/errors
|
||||
yunion.io/x/pkg/gotypes
|
||||
yunion.io/x/pkg/util/filterclause
|
||||
yunion.io/x/pkg/util/reflectutils
|
||||
@@ -800,7 +800,7 @@ yunion.io/x/pkg/util/runtime
|
||||
yunion.io/x/pkg/util/clock
|
||||
# yunion.io/x/s3cli v0.0.0-20190812034537-1e65a6651a3e
|
||||
yunion.io/x/s3cli
|
||||
# yunion.io/x/sqlchemy v0.0.0-20190813100902-cfa59aeabbfe
|
||||
# yunion.io/x/sqlchemy v0.0.0-20190817082003-905772542cba
|
||||
yunion.io/x/sqlchemy
|
||||
# yunion.io/x/structarg v0.0.0-20190809075558-115bed041de3
|
||||
yunion.io/x/structarg
|
||||
|
||||
+6
-1
@@ -16,6 +16,7 @@ package sqlchemy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -191,7 +192,11 @@ func (us *SUpdateSession) saveUpdate(dt interface{}) (UpdateDiffs, error) {
|
||||
return nil, err
|
||||
}
|
||||
if aCnt != 1 {
|
||||
return nil, fmt.Errorf("affected rows %d != 1", aCnt)
|
||||
if aCnt == 0 {
|
||||
return nil, sql.ErrNoRows
|
||||
} else {
|
||||
return nil, fmt.Errorf("affected rows %d != 1", aCnt)
|
||||
}
|
||||
}
|
||||
q := us.tableSpec.Query()
|
||||
for k, v := range primaries {
|
||||
|
||||
Reference in New Issue
Block a user