mod_projects.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package identity
  15. import (
  16. "fmt"
  17. "golang.org/x/sync/errgroup"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/onecloud/pkg/httperrors"
  20. "yunion.io/x/onecloud/pkg/mcclient"
  21. "yunion.io/x/onecloud/pkg/mcclient/modulebase"
  22. "yunion.io/x/onecloud/pkg/mcclient/modules"
  23. )
  24. type ProjectManagerV3 struct {
  25. modulebase.ResourceManager
  26. }
  27. var (
  28. Projects ProjectManagerV3
  29. )
  30. func (this *ProjectManagerV3) _join(s *mcclient.ClientSession, pid, uid, rid, resource string) error {
  31. if resource == "users" {
  32. _, err := RolesV3.PutInContexts(s, rid, nil, []modulebase.ManagerContext{
  33. {InstanceManager: &Projects, InstanceId: pid},
  34. {InstanceManager: &UsersV3, InstanceId: uid},
  35. })
  36. if err != nil {
  37. return err
  38. }
  39. } else if resource == "groups" {
  40. _, err := RolesV3.PutInContexts(s, rid, nil, []modulebase.ManagerContext{
  41. {InstanceManager: &Projects, InstanceId: pid},
  42. {InstanceManager: &Groups, InstanceId: uid},
  43. })
  44. if err != nil {
  45. return err
  46. }
  47. }
  48. return nil
  49. }
  50. func (this *ProjectManagerV3) _leave(s *mcclient.ClientSession, pid string, resource string, uid string, rid string) error {
  51. var err error
  52. if resource == "users" {
  53. _, err = RolesV3.DeleteInContexts(s, rid, nil, []modulebase.ManagerContext{
  54. {InstanceManager: &Projects, InstanceId: pid},
  55. {InstanceManager: &UsersV3, InstanceId: uid},
  56. })
  57. } else if resource == "groups" {
  58. _, err = RolesV3.DeleteInContexts(s, rid, nil, []modulebase.ManagerContext{
  59. {InstanceManager: &Projects, InstanceId: pid},
  60. {InstanceManager: &Groups, InstanceId: uid},
  61. })
  62. }
  63. if err != nil {
  64. return err
  65. }
  66. return nil
  67. }
  68. func (this *ProjectManagerV3) DoLeaveProject(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  69. // params format:
  70. // {
  71. // "uid": "CCCGwOsrpp6h", // may be userid, may be group id
  72. // "resource": "" default users, else: groups
  73. // "pids": [{"rid": "arstarst", "pid": "ooienst"}, {}...]
  74. // }
  75. ret := jsonutils.NewDict()
  76. uid, e := params.GetString("uid")
  77. if e != nil {
  78. return nil, httperrors.NewInputParameterError("missing uid")
  79. }
  80. pids, e := params.GetArray("pids")
  81. if e != nil {
  82. return nil, httperrors.NewInputParameterError("missing pids")
  83. }
  84. resource, _ := params.GetString("resource")
  85. if len(resource) == 0 {
  86. resource = "users"
  87. }
  88. for _, pid := range pids {
  89. _pid, e := pid.GetString("pid")
  90. if e != nil {
  91. return nil, httperrors.NewInputParameterError("missing pid in pids")
  92. }
  93. _rid, e := pid.GetString("rid")
  94. if e != nil {
  95. return nil, httperrors.NewInputParameterError("missing rid in pids")
  96. }
  97. err := this._leave(s, _pid, resource, uid, _rid)
  98. if err != nil {
  99. return nil, err
  100. }
  101. }
  102. return ret, nil
  103. }
  104. // Add one user to Many Projects
  105. func (this *ProjectManagerV3) DoJoinProject(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  106. // params format:
  107. // {
  108. // "uid": "CCCGwOsrpp6h",
  109. // "rid": "aDeKQx1PmcTd",
  110. // "pids": ["L6ssbAJUG3rC", "pu8lkunxP4z8"]
  111. // "resource": "users" or "groups"
  112. // }
  113. ret := jsonutils.NewDict()
  114. uid, e := params.GetString("uid")
  115. if e != nil {
  116. return nil, httperrors.NewInputParameterError("missing uid")
  117. }
  118. ridsA, e := params.Get("rid")
  119. if e != nil {
  120. return nil, httperrors.NewInputParameterError("missing rid")
  121. }
  122. rids := ridsA.(*jsonutils.JSONArray).GetStringArray()
  123. pidsA, e := params.Get("pids")
  124. if e != nil {
  125. return nil, httperrors.NewInputParameterError("missing pids")
  126. }
  127. pids := pidsA.(*jsonutils.JSONArray).GetStringArray()
  128. resource, _ := params.GetString("resource")
  129. if len(resource) == 0 {
  130. resource = "users"
  131. }
  132. for _, rid := range rids {
  133. for _, pid := range pids {
  134. err := this._join(s, pid, uid, rid, resource)
  135. if err != nil {
  136. return nil, err
  137. }
  138. }
  139. }
  140. return ret, nil
  141. }
  142. // Add Many user[uids] to project(pid) with role(rid)
  143. func (this *ProjectManagerV3) DoProjectBatchJoin(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  144. // params format:
  145. // {
  146. // "uids": ["CCCGwOsrpp6h", "aroisetna"],
  147. // "rid": "aDeKQx1PmcTd", // role id
  148. // "pid": "L6ssbAJUG3rC"
  149. // }
  150. ret := jsonutils.NewDict()
  151. _ids, e := params.GetArray("ids")
  152. if e != nil {
  153. return ret, e
  154. }
  155. // ids := make([]string, 0)
  156. // for _, u := range _ids {
  157. // name, _ := u.GetString()
  158. // ids = append(ids, name)
  159. // }
  160. resource, e := params.GetString("resource")
  161. if e != nil {
  162. return ret, e
  163. }
  164. if resource != "users" && resource != "groups" {
  165. return ret, fmt.Errorf("不支持的 resource type")
  166. }
  167. _rids, e := params.GetArray("rid")
  168. if e != nil {
  169. return ret, e
  170. }
  171. pid, e := params.GetString("pid")
  172. if e != nil {
  173. return ret, e
  174. }
  175. for i := range _rids {
  176. rid, _ := _rids[i].GetString()
  177. for _, u := range _ids {
  178. id, _ := u.GetString()
  179. if resource == "users" {
  180. _, err := RolesV3.PutInContexts(
  181. s,
  182. rid,
  183. nil,
  184. []modulebase.ManagerContext{
  185. {InstanceManager: &Projects, InstanceId: pid},
  186. {InstanceManager: &UsersV3, InstanceId: id},
  187. })
  188. if err != nil {
  189. return nil, err
  190. }
  191. } else {
  192. _, err := RolesV3.PutInContexts(
  193. s,
  194. rid,
  195. nil,
  196. []modulebase.ManagerContext{
  197. {InstanceManager: &Projects, InstanceId: pid},
  198. {InstanceManager: &Groups, InstanceId: id},
  199. })
  200. if err != nil {
  201. return nil, err
  202. }
  203. }
  204. }
  205. }
  206. return ret, nil
  207. }
  208. // Remove Many user[uids] to project(pid) with role(rid)
  209. func (this *ProjectManagerV3) DoProjectBatchDeleteUserGroup(s *mcclient.ClientSession, pid string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  210. // params format:
  211. // {
  212. // id: project id;
  213. // params: {items: [
  214. // id:, role_id:, res_type:
  215. // ]}
  216. // }
  217. ret := jsonutils.NewDict()
  218. items, e := params.GetArray("items")
  219. if e != nil {
  220. return ret, e
  221. }
  222. for _, item := range items {
  223. id, _ := item.GetString("id")
  224. role_id, _ := item.GetString("role_id")
  225. res_type, _ := item.GetString("res_type")
  226. if res_type == "user" {
  227. _, err := RolesV3.DeleteInContexts(s, role_id, nil, []modulebase.ManagerContext{
  228. {InstanceManager: &Projects, InstanceId: pid},
  229. {InstanceManager: &UsersV3, InstanceId: id},
  230. })
  231. if err != nil {
  232. return nil, err
  233. }
  234. } else if res_type == "group" {
  235. _, err := RolesV3.DeleteInContexts(s, role_id, nil, []modulebase.ManagerContext{
  236. {InstanceManager: &Projects, InstanceId: pid},
  237. {InstanceManager: &Groups, InstanceId: id},
  238. })
  239. if err != nil {
  240. return nil, err
  241. }
  242. }
  243. }
  244. return ret, nil
  245. }
  246. func (this *ProjectManagerV3) AddTags(session *mcclient.ClientSession, id string, tags []string) error {
  247. path := fmt.Sprintf("/projects/%s/tags", id)
  248. body := jsonutils.NewDict()
  249. body.Add(jsonutils.NewStringArray(tags), "tags")
  250. _, err := modulebase.Put(this.ResourceManager, session, path, body, "")
  251. if err != nil {
  252. return err
  253. }
  254. return nil
  255. }
  256. func (this *ProjectManagerV3) FetchId(s *mcclient.ClientSession, project string, domain string) (string, error) {
  257. query := jsonutils.NewDict()
  258. if len(domain) > 0 {
  259. domainId, err := Domains.GetId(s, domain, nil)
  260. if err != nil {
  261. return "", err
  262. }
  263. query.Add(jsonutils.NewString(domainId), "domain_id")
  264. }
  265. return this.GetId(s, project, query)
  266. }
  267. func (this *ProjectManagerV3) JoinProject(s *mcclient.ClientSession, rid, pid, uid string) error {
  268. _, err := RolesV3.PutInContexts(s, rid, nil, []modulebase.ManagerContext{
  269. {InstanceManager: &Projects, InstanceId: pid},
  270. {InstanceManager: &UsersV3, InstanceId: uid},
  271. })
  272. if err != nil {
  273. return err
  274. }
  275. return nil
  276. }
  277. // create project and attach users & roles
  278. func (this *ProjectManagerV3) DoCreateProject(s *mcclient.ClientSession, p jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  279. /*
  280. params format:
  281. {
  282. user : ["TestA", "TestB"],
  283. role : ["RoleA", "RoleB"],
  284. }
  285. */
  286. params := p.(*jsonutils.JSONDict)
  287. _user, _ := params.Get("user")
  288. _role, _ := params.Get("role")
  289. params.Remove("user")
  290. params.Remove("role")
  291. // create project
  292. response, err := Projects.Create(s, params)
  293. if err != nil {
  294. return nil, err
  295. }
  296. pid, err := response.GetString("id")
  297. if err != nil {
  298. return nil, httperrors.NewResourceNotFoundError("project is not found")
  299. }
  300. // assgin users to project
  301. users := []string{}
  302. roles := []string{}
  303. if _user != nil {
  304. if _u, ok := _user.(*jsonutils.JSONArray); ok {
  305. users = _u.GetStringArray()
  306. }
  307. }
  308. if _role != nil {
  309. if _r, ok := _role.(*jsonutils.JSONArray); ok {
  310. roles = _r.GetStringArray()
  311. }
  312. }
  313. if len(users) > 0 && len(roles) > 0 {
  314. var projectG errgroup.Group
  315. for i := range users {
  316. uid := users[i]
  317. for j := range roles {
  318. rid := roles[j]
  319. projectG.Go(func() error {
  320. return this.JoinProject(s, rid, pid, uid)
  321. })
  322. }
  323. }
  324. if err := projectG.Wait(); err != nil {
  325. return nil, err
  326. }
  327. }
  328. return response, nil
  329. }
  330. func init() {
  331. Projects = ProjectManagerV3{modules.NewIdentityV3Manager("project", "projects",
  332. []string{},
  333. []string{"ID", "Name", "Domain_Id", "Project_Domain", "Parent_Id", "Enabled", "Description", "Created_At", "Displayname"})}
  334. modules.Register(&Projects)
  335. }