blob: d3ab134c55c02a037281dc8855d4d470799d2468 [file] [log] [blame]
Jamie Hannaford2a130242014-10-28 11:19:46 +01001package users
Jamie Hannaford929bd002014-10-29 11:14:25 +01002
3import (
Jamie Hannaford9c7bb8e2014-10-29 11:47:34 +01004 "errors"
5
6 "github.com/racker/perigee"
Jamie Hannaford929bd002014-10-29 11:14:25 +01007 "github.com/rackspace/gophercloud"
8 "github.com/rackspace/gophercloud/pagination"
9)
10
11func List(client *gophercloud.ServiceClient) pagination.Pager {
12 createPage := func(r pagination.PageResult) pagination.Page {
13 return UserPage{pagination.SinglePageBase(r)}
14 }
15
16 return pagination.NewPager(client, rootURL(client), createPage)
17}
Jamie Hannaford9c7bb8e2014-10-29 11:47:34 +010018
19// EnabledState represents whether the user is enabled or not.
20type EnabledState *bool
21
22// Useful variables to use when creating or updating users.
23var (
24 iTrue = true
25 iFalse = false
26
27 Enabled EnabledState = &iTrue
28 Disabled EnabledState = &iFalse
29)
30
Alex Gaynore4d83a42014-10-31 10:18:10 -070031type CreateOpts struct {
Jamie Hannaford9c7bb8e2014-10-29 11:47:34 +010032 // Either a name or username is required. When provided, the value must be
33 // unique or a 409 conflict error will be returned. If you provide a name but
34 // omit a username, the latter will be set to the former; and vice versa.
35 Name, Username string
36
37 // The ID of the tenant to which you want to assign this user.
38 TenantID string
39
40 // Indicates whether this user is enabled or not.
41 Enabled EnabledState
42
43 // The email address of this user.
44 Email string
45}
46
47// CreateOptsBuilder describes struct types that can be accepted by the Create call.
48type CreateOptsBuilder interface {
49 ToUserCreateMap() (map[string]interface{}, error)
50}
51
52// ToUserCreateMap assembles a request body based on the contents of a CreateOpts.
53func (opts CreateOpts) ToUserCreateMap() (map[string]interface{}, error) {
54 m := make(map[string]interface{})
55
56 if opts.Name == "" && opts.Username == "" {
57 return m, errors.New("Either a Name or Username must be provided")
58 }
59
60 if opts.Name != "" {
61 m["name"] = opts.Name
62 }
63 if opts.Username != "" {
64 m["username"] = opts.Username
65 }
66 if opts.Enabled != nil {
67 m["enabled"] = &opts.Enabled
68 }
69 if opts.Email != "" {
70 m["email"] = opts.Email
71 }
Jamie Hannaford7e04adf2014-10-29 13:47:58 +010072 if opts.TenantID != "" {
73 m["tenant_id"] = opts.TenantID
74 }
Jamie Hannaford9c7bb8e2014-10-29 11:47:34 +010075
Jamie Hannaford7e04adf2014-10-29 13:47:58 +010076 return map[string]interface{}{"user": m}, nil
Jamie Hannaford9c7bb8e2014-10-29 11:47:34 +010077}
78
79// Create is the operation responsible for creating new users.
80func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
81 var res CreateResult
82
83 reqBody, err := opts.ToUserCreateMap()
84 if err != nil {
85 res.Err = err
86 return res
87 }
88
89 _, res.Err = perigee.Request("POST", rootURL(client), perigee.Options{
90 Results: &res.Body,
91 ReqBody: reqBody,
92 MoreHeaders: client.AuthenticatedHeaders(),
93 OkCodes: []int{200, 201},
94 })
95
96 return res
97}
Jamie Hannaford2ad98bd2014-10-29 13:26:47 +010098
Jamie Hannaford69c1fe92014-10-29 13:28:58 +010099// Get requests details on a single user, either by ID.
100func Get(client *gophercloud.ServiceClient, id string) GetResult {
Jamie Hannaford2ad98bd2014-10-29 13:26:47 +0100101 var result GetResult
102
Jamie Hannaford6e4d7952014-10-29 16:18:29 +0100103 _, result.Err = perigee.Request("GET", ResourceURL(client, id), perigee.Options{
Jamie Hannaford2ad98bd2014-10-29 13:26:47 +0100104 Results: &result.Body,
105 MoreHeaders: client.AuthenticatedHeaders(),
Jamie Hannaford8b9a8002014-10-29 14:20:24 +0100106 OkCodes: []int{200},
Jamie Hannaford2ad98bd2014-10-29 13:26:47 +0100107 })
108
109 return result
110}
Jamie Hannaford7e04adf2014-10-29 13:47:58 +0100111
112// UpdateOptsBuilder allows extentions to add additional attributes to the Update request.
113type UpdateOptsBuilder interface {
114 ToUserUpdateMap() map[string]interface{}
115}
116
Alex Gaynore4d83a42014-10-31 10:18:10 -0700117// UpdateOpts specifies the base attributes that may be updated on an existing
118// server.
119type UpdateOpts struct {
120 // Either a name or username is required. When provided, the value must be
121 // unique or a 409 conflict error will be returned. If you provide a name but
122 // omit a username, the latter will be set to the former; and vice versa.
123 Name, Username string
124
125 // The ID of the tenant to which you want to assign this user.
126 TenantID string
127
128 // Indicates whether this user is enabled or not.
129 Enabled EnabledState
130
131 // The email address of this user.
132 Email string
133}
Jamie Hannaford7e04adf2014-10-29 13:47:58 +0100134
135// ToUserUpdateMap formats an UpdateOpts structure into a request body.
136func (opts UpdateOpts) ToUserUpdateMap() map[string]interface{} {
137 m := make(map[string]interface{})
138
139 if opts.Name != "" {
140 m["name"] = opts.Name
141 }
142 if opts.Username != "" {
143 m["username"] = opts.Username
144 }
145 if opts.Enabled != nil {
146 m["enabled"] = &opts.Enabled
147 }
148 if opts.Email != "" {
149 m["email"] = opts.Email
150 }
151 if opts.TenantID != "" {
152 m["tenant_id"] = opts.TenantID
153 }
154
155 return map[string]interface{}{"user": m}
156}
157
158// Update is the operation responsible for updating exist users by their UUID.
159func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
160 var result UpdateResult
161
Jamie Hannaford6e4d7952014-10-29 16:18:29 +0100162 _, result.Err = perigee.Request("PUT", ResourceURL(client, id), perigee.Options{
Jamie Hannaford7e04adf2014-10-29 13:47:58 +0100163 Results: &result.Body,
164 ReqBody: opts.ToUserUpdateMap(),
165 MoreHeaders: client.AuthenticatedHeaders(),
Jamie Hannaford8b9a8002014-10-29 14:20:24 +0100166 OkCodes: []int{200},
167 })
168
169 return result
170}
171
172// Delete is the operation responsible for permanently deleting an API user.
173func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
174 var result DeleteResult
175
Jamie Hannaford6e4d7952014-10-29 16:18:29 +0100176 _, result.Err = perigee.Request("DELETE", ResourceURL(client, id), perigee.Options{
Jamie Hannaford8b9a8002014-10-29 14:20:24 +0100177 MoreHeaders: client.AuthenticatedHeaders(),
178 OkCodes: []int{204},
Jamie Hannaford7e04adf2014-10-29 13:47:58 +0100179 })
180
181 return result
182}
Jamie Hannaforde680e422014-10-29 14:55:57 +0100183
184func ListRoles(client *gophercloud.ServiceClient, tenantID, userID string) pagination.Pager {
185 createPage := func(r pagination.PageResult) pagination.Page {
186 return RolePage{pagination.SinglePageBase(r)}
187 }
188
189 return pagination.NewPager(client, listRolesURL(client, tenantID, userID), createPage)
190}