users.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  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. "yunion.io/x/jsonutils"
  17. "yunion.io/x/onecloud/cmd/climc/shell"
  18. api "yunion.io/x/onecloud/pkg/apis/identity"
  19. "yunion.io/x/onecloud/pkg/mcclient"
  20. "yunion.io/x/onecloud/pkg/mcclient/modulebase"
  21. modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
  22. "yunion.io/x/onecloud/pkg/mcclient/options"
  23. identity_options "yunion.io/x/onecloud/pkg/mcclient/options/identity"
  24. )
  25. func init() {
  26. cmd := shell.NewResourceCmd(&modules.UsersV3)
  27. cmd.List(&identity_options.UserListOptions{})
  28. cmd.Perform("user-metadata", &options.ResourceMetadataOptions{})
  29. cmd.Perform("set-user-metadata", &options.ResourceMetadataOptions{})
  30. cmd.Perform("class-metadata", &options.ResourceMetadataOptions{})
  31. cmd.Perform("set-class-metadata", &options.ResourceMetadataOptions{})
  32. cmd.Perform("metadata", &options.ResourceMetadataOptions{})
  33. cmd.Perform("enable", &identity_options.UserDetailOptions{})
  34. cmd.Perform("disable", &identity_options.UserDetailOptions{})
  35. /*type UserListOptions struct {
  36. options.BaseListOptions
  37. Name string `help:"Filter by name"`
  38. OrderByDomain string `help:"order by domain name" choices:"asc|desc"`
  39. Role string `help:"Filter by role"`
  40. RoleAssignmentDomainId string `help:"filter role assignment domain"`
  41. RoleAssignmentProjectId string `help:"filter role assignment project"`
  42. IdpId string `help:"filter by idp_id"`
  43. IdpEntityId string `help:"filter by idp_entity_id"`
  44. }
  45. R(&UserListOptions{}, "user-list", "List users", func(s *mcclient.ClientSession, args *UserListOptions) error {
  46. params, err := options.ListStructToParams(args)
  47. if err != nil {
  48. return err
  49. }
  50. result, err := modules.UsersV3.List(s, params)
  51. if err != nil {
  52. return err
  53. }
  54. if len(args.ExportFile) > 0 {
  55. exportList(result, args.ExportFile, args.ExportKeys, args.ExportTexts, modules.UsersV3.GetColumns(s))
  56. } else {
  57. printList(result, modules.UsersV3.GetColumns(s))
  58. }
  59. return nil
  60. })*/
  61. type UserDetailOptions struct {
  62. ID string `help:"ID of user"`
  63. Domain string `help:"Domain"`
  64. System bool `help:"show system user"`
  65. }
  66. R(&UserDetailOptions{}, "user-show", "Show details of user", func(s *mcclient.ClientSession, args *UserDetailOptions) error {
  67. query := jsonutils.NewDict()
  68. if len(args.Domain) > 0 {
  69. domainId, err := modules.Domains.GetId(s, args.Domain, nil)
  70. if err != nil {
  71. return err
  72. }
  73. query.Add(jsonutils.NewString(domainId), "domain_id")
  74. }
  75. if args.System {
  76. query.Add(jsonutils.JSONTrue, "system")
  77. }
  78. user, e := modules.UsersV3.Get(s, args.ID, query)
  79. if e != nil {
  80. return e
  81. }
  82. printObject(user)
  83. return nil
  84. })
  85. R(&UserDetailOptions{}, "user-delete", "Delete user", func(s *mcclient.ClientSession, args *UserDetailOptions) error {
  86. query := jsonutils.NewDict()
  87. if len(args.Domain) > 0 {
  88. domainId, err := modules.Domains.GetId(s, args.Domain, nil)
  89. if err != nil {
  90. return err
  91. }
  92. query.Add(jsonutils.NewString(domainId), "domain_id")
  93. }
  94. uid, e := modules.UsersV3.GetId(s, args.ID, query)
  95. if e != nil {
  96. return e
  97. }
  98. _, e = modules.UsersV3.Delete(s, uid, nil)
  99. if e != nil {
  100. return e
  101. }
  102. return nil
  103. })
  104. R(&UserDetailOptions{}, "user-project-list", "List projects of user", func(s *mcclient.ClientSession, args *UserDetailOptions) error {
  105. query := jsonutils.NewDict()
  106. if len(args.Domain) > 0 {
  107. domainId, err := modules.Domains.GetId(s, args.Domain, nil)
  108. if err != nil {
  109. return err
  110. }
  111. query.Add(jsonutils.NewString(domainId), "domain_id")
  112. }
  113. uid, err := modules.UsersV3.GetId(s, args.ID, query)
  114. if err != nil {
  115. return err
  116. }
  117. projects, e := modules.UsersV3.GetProjects(s, uid)
  118. if e != nil {
  119. return e
  120. }
  121. printList(projects, modules.Projects.GetColumns(s))
  122. return nil
  123. })
  124. R(&UserDetailOptions{}, "user-group-list", "List groups of user", func(s *mcclient.ClientSession, args *UserDetailOptions) error {
  125. query := jsonutils.NewDict()
  126. if len(args.Domain) > 0 {
  127. domainId, err := modules.Domains.GetId(s, args.Domain, nil)
  128. if err != nil {
  129. return err
  130. }
  131. query.Add(jsonutils.NewString(domainId), "domain_id")
  132. }
  133. uid, err := modules.UsersV3.GetId(s, args.ID, query)
  134. if err != nil {
  135. return err
  136. }
  137. groups, e := modules.UsersV3.GetGroups(s, uid)
  138. if e != nil {
  139. return e
  140. }
  141. printList(groups, modules.Groups.GetColumns(s))
  142. return nil
  143. })
  144. type UserTenantRoleOptions struct {
  145. ID string `help:"ID of user"`
  146. Tenant string `help:"ID of tenant"`
  147. }
  148. R(&UserTenantRoleOptions{}, "user-role-list", "List roles of user", func(s *mcclient.ClientSession, args *UserTenantRoleOptions) error {
  149. params := jsonutils.NewDict()
  150. params.Add(jsonutils.NewString(args.ID), "id")
  151. if len(args.Tenant) > 0 {
  152. params.Add(jsonutils.NewString(args.Tenant), "tenantId")
  153. }
  154. result, err := modules.Users.GetTenantRoleList(s, params)
  155. if err != nil {
  156. return err
  157. }
  158. printList(modulebase.JSON2ListResult(result), nil)
  159. return nil
  160. })
  161. type UserCreateOptions struct {
  162. NAME string `help:"Name of the new user"`
  163. Domain string `help:"Domain"`
  164. Desc string `help:"Description"`
  165. Password *string `help:"Password"`
  166. Displayname string `help:"Displayname"`
  167. Email string `help:"Email"`
  168. Mobile string `help:"Mobile"`
  169. Enabled bool `help:"Enabled"`
  170. Disabled bool `help:"Disabled"`
  171. SkipPasswordComplexityCheck bool `help:"do password complexity check, default is false"`
  172. // DefaultProject string `help:"Default project"`
  173. SystemAccount bool `help:"is a system account?"`
  174. NoWebConsole bool `help:"allow web console access"`
  175. EnableMfa bool `help:"enable TOTP mfa"`
  176. IdpId string `help:"Id of identity provider to link with"`
  177. IdpEntityId string `help:"Entity id of identity provider to link with"`
  178. Lang string `help:"user default language"`
  179. Expire string `help:"user expired at"`
  180. }
  181. R(&UserCreateOptions{}, "user-create", "Create a user", func(s *mcclient.ClientSession, args *UserCreateOptions) error {
  182. params := jsonutils.NewDict()
  183. params.Add(jsonutils.NewString(args.NAME), "name")
  184. if len(args.Domain) > 0 {
  185. domainId, err := modules.Domains.GetId(s, args.Domain, nil)
  186. if err != nil {
  187. return err
  188. }
  189. params.Add(jsonutils.NewString(domainId), "domain_id")
  190. }
  191. if args.Password != nil {
  192. params.Add(jsonutils.NewString(*args.Password), "password")
  193. if args.SkipPasswordComplexityCheck {
  194. params.Add(jsonutils.JSONTrue, "skip_password_complexity_check")
  195. }
  196. }
  197. if len(args.Displayname) > 0 {
  198. params.Add(jsonutils.NewString(args.Displayname), "displayname")
  199. }
  200. if len(args.Desc) > 0 {
  201. params.Add(jsonutils.NewString(args.Desc), "description")
  202. }
  203. if len(args.Email) > 0 {
  204. params.Add(jsonutils.NewString(args.Email), "email")
  205. }
  206. if len(args.Mobile) > 0 {
  207. params.Add(jsonutils.NewString(args.Mobile), "mobile")
  208. }
  209. if args.Enabled && !args.Disabled {
  210. params.Add(jsonutils.JSONTrue, "enabled")
  211. } else if !args.Enabled && args.Disabled {
  212. params.Add(jsonutils.JSONFalse, "enabled")
  213. }
  214. if args.SystemAccount {
  215. params.Add(jsonutils.JSONTrue, "is_system_account")
  216. }
  217. if args.NoWebConsole {
  218. params.Add(jsonutils.JSONFalse, "allow_web_console")
  219. }
  220. if args.EnableMfa {
  221. params.Add(jsonutils.JSONTrue, "enable_mfa")
  222. }
  223. if len(args.IdpId) > 0 {
  224. params.Add(jsonutils.NewString(args.IdpId), "idp_id")
  225. params.Add(jsonutils.NewString(args.IdpEntityId), "idp_entity_id")
  226. }
  227. if len(args.Lang) > 0 {
  228. params.Add(jsonutils.NewString(args.Lang), "lang")
  229. }
  230. if len(args.Expire) > 0 {
  231. params.Add(jsonutils.NewString(args.Expire), "expired_at")
  232. }
  233. /*if len(args.DefaultProject) > 0 {
  234. projId, err := modules.Projects.GetId(s, args.DefaultProject, nil)
  235. if err != nil {
  236. return err
  237. }
  238. params.Add(jsonutils.NewString(projId), "default_project_id")
  239. }*/
  240. user, err := modules.UsersV3.Create(s, params)
  241. if err != nil {
  242. return err
  243. }
  244. printObject(user)
  245. return nil
  246. })
  247. type UserUpdateOptions struct {
  248. ID string `help:"ID or name of the user"`
  249. Domain string `help:"Domain"`
  250. Name string `help:"New name of the user"`
  251. Password *string `help:"New password"`
  252. Desc string `help:"Description"`
  253. Displayname string `help:"Displayname"`
  254. Email string `help:"Email"`
  255. Mobile string `help:"Mobile"`
  256. Enabled bool `help:"Enabled"`
  257. Disabled bool `help:"Disabled"`
  258. SystemAccount bool `help:"Turn on is_system_account"`
  259. NotSystemAccount bool `help:"Turn off is_system_account"`
  260. AllowWebConsole bool `help:"Turn on allow_web_console"`
  261. DisallowWebConsole bool `help:"Turn off allow_web_console"`
  262. EnableMfa bool `help:"turn on enable_mfa"`
  263. DisableMfa bool `help:"turn off enable_mfa"`
  264. // DefaultProject string `help:"Default project"`
  265. // Option []string `help:"User options"`
  266. SkipPasswordComplexityCheck bool `help:"skip_password_complexity_check"`
  267. Lang string `help:"update user language"`
  268. Expire string `help:"user expired at"`
  269. ClearExpire bool `help:"clear user expired at"`
  270. }
  271. R(&UserUpdateOptions{}, "user-update", "Update a user", func(s *mcclient.ClientSession, args *UserUpdateOptions) error {
  272. query := jsonutils.NewDict()
  273. if len(args.Domain) > 0 {
  274. domainId, err := modules.Domains.GetId(s, args.Domain, nil)
  275. if err != nil {
  276. return err
  277. }
  278. query.Add(jsonutils.NewString(domainId), "domain_id")
  279. }
  280. uid, err := modules.UsersV3.GetId(s, args.ID, query)
  281. if err != nil {
  282. return err
  283. }
  284. params := jsonutils.NewDict()
  285. if len(args.Name) > 0 {
  286. params.Add(jsonutils.NewString(args.Name), "name")
  287. }
  288. if args.Password != nil {
  289. params.Add(jsonutils.NewString(*args.Password), "password")
  290. if args.SkipPasswordComplexityCheck {
  291. params.Add(jsonutils.JSONTrue, "skip_password_complexity_check")
  292. }
  293. }
  294. if len(args.Displayname) > 0 {
  295. params.Add(jsonutils.NewString(args.Displayname), "displayname")
  296. }
  297. if len(args.Desc) > 0 {
  298. params.Add(jsonutils.NewString(args.Desc), "description")
  299. }
  300. if len(args.Email) > 0 {
  301. params.Add(jsonutils.NewString(args.Email), "email")
  302. }
  303. if len(args.Mobile) > 0 {
  304. params.Add(jsonutils.NewString(args.Mobile), "mobile")
  305. }
  306. if args.Enabled && !args.Disabled {
  307. params.Add(jsonutils.JSONTrue, "enabled")
  308. } else if !args.Enabled && args.Disabled {
  309. params.Add(jsonutils.JSONFalse, "enabled")
  310. }
  311. if args.SystemAccount {
  312. params.Add(jsonutils.JSONTrue, "is_system_account")
  313. } else if args.NotSystemAccount {
  314. params.Add(jsonutils.JSONFalse, "is_system_account")
  315. }
  316. if args.AllowWebConsole {
  317. params.Add(jsonutils.JSONTrue, "allow_web_console")
  318. } else if args.DisallowWebConsole {
  319. params.Add(jsonutils.JSONFalse, "allow_web_console")
  320. }
  321. if args.EnableMfa {
  322. params.Add(jsonutils.JSONTrue, "enable_mfa")
  323. } else if args.DisableMfa {
  324. params.Add(jsonutils.JSONFalse, "enable_mfa")
  325. }
  326. if len(args.Lang) > 0 {
  327. params.Add(jsonutils.NewString(args.Lang), "lang")
  328. }
  329. if args.ClearExpire {
  330. params.Add(jsonutils.JSONTrue, "clear_expire")
  331. } else if len(args.Expire) > 0 {
  332. params.Add(jsonutils.NewString(args.Expire), "expired_at")
  333. }
  334. // if len(args.DefaultProject) > 0 {
  335. // projId, err := modules.Projects.GetId(s, args.DefaultProject, nil)
  336. // if err != nil {
  337. // return err
  338. // }
  339. // params.Add(jsonutils.NewString(projId), "default_project_id")
  340. // }
  341. //
  342. // if len(args.Option) > 0 {
  343. // uoptions := jsonutils.NewDict()
  344. // for _, opt := range args.Option {
  345. // pos := strings.IndexByte(opt, ':')
  346. // key := opt[:pos]
  347. // val := opt[pos+1:]
  348. // uoptions.Add(jsonutils.NewString(val), key)
  349. // }
  350. // params.Add(uoptions, "_resource_options")
  351. // }
  352. //
  353. user, err := modules.UsersV3.Patch(s, uid, params)
  354. if err != nil {
  355. return err
  356. }
  357. printObject(user)
  358. return nil
  359. })
  360. type UserGroupOptions struct {
  361. USER string `help:"User ID or Name"`
  362. GROUP string `help:"group ID or Name"`
  363. Domain string `help:"Domain"`
  364. }
  365. R(&UserGroupOptions{}, "user-join-group", "Add a user to a group", func(s *mcclient.ClientSession, args *UserGroupOptions) error {
  366. uid, gid, err := getUserGroupId(s, args.USER, args.GROUP, args.Domain)
  367. if err != nil {
  368. return err
  369. }
  370. _, err = modules.UsersV3.PutInContext(s, uid, nil, &modules.Groups, gid)
  371. if err != nil {
  372. return err
  373. }
  374. return nil
  375. })
  376. R(&UserGroupOptions{}, "user-in-group", "Check whether a user belongs a group", func(s *mcclient.ClientSession, args *UserGroupOptions) error {
  377. uid, gid, err := getUserGroupId(s, args.USER, args.GROUP, args.Domain)
  378. if err != nil {
  379. return err
  380. }
  381. _, err = modules.UsersV3.HeadInContext(s, uid, nil, &modules.Groups, gid)
  382. if err != nil {
  383. return err
  384. }
  385. return nil
  386. })
  387. R(&UserGroupOptions{}, "user-leave-group", "Remove a user from a group", func(s *mcclient.ClientSession, args *UserGroupOptions) error {
  388. uid, gid, err := getUserGroupId(s, args.USER, args.GROUP, args.Domain)
  389. if err != nil {
  390. return err
  391. }
  392. _, err = modules.UsersV3.DeleteInContext(s, uid, nil, &modules.Groups, gid)
  393. if err != nil {
  394. return err
  395. }
  396. return nil
  397. })
  398. type UserGroupsOptions struct {
  399. USER string `help:"User ID or Name"`
  400. Gids []string `help:"group ID or Name"`
  401. Action string `default:"join" choices:"join|leave"`
  402. Enabled bool
  403. }
  404. R(&UserGroupsOptions{}, "user-join-groups", "Add a user to groups", func(s *mcclient.ClientSession, args *UserGroupsOptions) error {
  405. _, err := modules.UsersV3.DoJoinGroups(s, args.USER, jsonutils.Marshal(args))
  406. if err != nil {
  407. return err
  408. }
  409. return nil
  410. })
  411. type UserJoinProjectOptions struct {
  412. User string `help:"User Id or name" optional:"false" positional:"true"`
  413. Project []string `help:"Projects to join" nargs:"+"`
  414. Role []string `help:"User join project with roles" nargs:"+"`
  415. Enabled bool
  416. }
  417. R(&UserJoinProjectOptions{}, "user-join-project", "User join projects with roles", func(s *mcclient.ClientSession, args *UserJoinProjectOptions) error {
  418. input := api.SJoinProjectsInput{}
  419. input.Projects = args.Project
  420. input.Roles = args.Role
  421. input.Enabled = args.Enabled
  422. result, err := modules.UsersV3.PerformAction(s, args.User, "join", jsonutils.Marshal(input))
  423. if err != nil {
  424. return err
  425. }
  426. printObject(result)
  427. return nil
  428. })
  429. type UserLeaveProjectsOptions struct {
  430. User string `help:"user id or name" optional:"false" positional:"true"`
  431. Project string `help:"project id or name" optional:"false" positional:"true"`
  432. Role []string `help:"roles to remove" nargs:"+"`
  433. }
  434. R(&UserLeaveProjectsOptions{}, "user-leave-project", "Leave a user from projects", func(s *mcclient.ClientSession, args *UserLeaveProjectsOptions) error {
  435. input := api.SLeaveProjectsInput{}
  436. input.ProjectRoles = make([]api.SProjectRole, len(args.Role))
  437. for i := range args.Role {
  438. input.ProjectRoles[i].Project = args.Project
  439. input.ProjectRoles[i].Role = args.Role[i]
  440. }
  441. result, err := modules.UsersV3.PerformAction(s, args.User, "leave", jsonutils.Marshal(input))
  442. if err != nil {
  443. return err
  444. }
  445. printObject(result)
  446. return nil
  447. })
  448. type UserLinkIdpOptions struct {
  449. USER string `help:"ID or name of user to operate" json:"-"`
  450. IdpId string `help:"Id of identity provider to link with" required:"true" json:"idp_id"`
  451. IdpEntityId string `help:"Id of entity in identity provider to link with" required:"true" json:"idp_entity_id"`
  452. }
  453. R(&UserLinkIdpOptions{}, "user-link-idp", "Link user with an entity in the speicified identity provider", func(s *mcclient.ClientSession, args *UserLinkIdpOptions) error {
  454. result, err := modules.UsersV3.PerformAction(s, args.USER, "link-idp", jsonutils.Marshal(args))
  455. if err != nil {
  456. return err
  457. }
  458. printObject(result)
  459. return nil
  460. })
  461. R(&UserLinkIdpOptions{}, "user-unlink-idp", "Unlink user from an entity in the speicified identity provider", func(s *mcclient.ClientSession, args *UserLinkIdpOptions) error {
  462. result, err := modules.UsersV3.PerformAction(s, args.USER, "unlink-idp", jsonutils.Marshal(args))
  463. if err != nil {
  464. return err
  465. }
  466. printObject(result)
  467. return nil
  468. })
  469. type UserResetCredentialOptions struct {
  470. USER string `json:"-" help:"ID or name of user to operate"`
  471. TYPE string `json:"type" help:"Crednetial type of reset" choices:"totp|recovery|aksk|enc_key"`
  472. }
  473. R(&UserResetCredentialOptions{}, "user-reset-credentials", "Reset user credential", func(s *mcclient.ClientSession, args *UserResetCredentialOptions) error {
  474. result, err := modules.UsersV3.PerformAction(s, args.USER, "reset-credentials", jsonutils.Marshal(args))
  475. if err != nil {
  476. return err
  477. }
  478. printObject(result)
  479. return nil
  480. })
  481. }