blob: 6815c1c666b5dc9329c6574ac5e247069d78dcb9 [file] [log] [blame]
Jamie Hannafordaf4570f2015-02-12 13:33:25 +01001package users
2
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "github.com/gophercloud/gophercloud"
5 db "github.com/gophercloud/gophercloud/openstack/db/v1/databases"
6 "github.com/gophercloud/gophercloud/pagination"
Jamie Hannafordaf4570f2015-02-12 13:33:25 +01007)
8
Jamie Hannaford9793d942015-02-18 15:13:20 +01009// CreateOptsBuilder is the top-level interface for creating JSON maps.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010010type CreateOptsBuilder interface {
11 ToUserCreateMap() (map[string]interface{}, error)
12}
13
14// CreateOpts is the struct responsible for configuring a new user; often in the
15// context of an instance.
16type CreateOpts struct {
Jamie Hannaford9793d942015-02-18 15:13:20 +010017 // [REQUIRED] Specifies a name for the user. Valid names can be composed
18 // of the following characters: letters (either case); numbers; these
19 // characters '@', '?', '#', ' ' but NEVER beginning a name string; '_' is
20 // permitted anywhere. Prohibited characters that are forbidden include:
21 // single quotes, double quotes, back quotes, semicolons, commas, backslashes,
22 // and forward slashes. Spaces at the front or end of a user name are also
23 // not permitted.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010024 Name string
25
Jamie Hannaford9793d942015-02-18 15:13:20 +010026 // [REQUIRED] Specifies a password for the user.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010027 Password string
28
Jamie Hannaford9793d942015-02-18 15:13:20 +010029 // [OPTIONAL] An array of databases that this user will connect to. The
30 // "name" field is the only requirement for each option.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010031 Databases db.BatchCreateOpts
32
Jamie Hannaford9793d942015-02-18 15:13:20 +010033 // [OPTIONAL] Specifies the host from which a user is allowed to connect to
34 // the database. Possible values are a string containing an IPv4 address or
35 // "%" to allow connecting from any host. Optional; the default is "%".
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010036 Host string
37}
38
Jamie Hannaford9793d942015-02-18 15:13:20 +010039// ToMap is a convenience function for creating sub-maps for individual users.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010040func (opts CreateOpts) ToMap() (map[string]interface{}, error) {
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010041
Jamie Hannaford9793d942015-02-18 15:13:20 +010042 if opts.Name == "root" {
Jon Perritt763e5922016-03-07 03:21:18 -060043 err := gophercloud.ErrInvalidInput{}
44 err.Function = "users.ToUserCreateMap"
45 err.Argument = "users.CreateOpts.Name"
46 err.Value = "root"
47 err.Info = "root is a reserved user name and cannot be used"
48 return nil, err
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010049 }
Jamie Hannaford9793d942015-02-18 15:13:20 +010050 if opts.Name == "" {
Jon Perritt763e5922016-03-07 03:21:18 -060051 err := gophercloud.ErrMissingInput{}
52 err.Function = "users.ToUserCreateMap"
53 err.Argument = "users.CreateOpts.Name"
54 return nil, err
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010055 }
Jamie Hannaford9793d942015-02-18 15:13:20 +010056 if opts.Password == "" {
Jon Perritt763e5922016-03-07 03:21:18 -060057 err := gophercloud.ErrMissingInput{}
58 err.Function = "users.ToUserCreateMap"
59 err.Argument = "users.CreateOpts.Password"
60 return nil, err
Jamie Hannaford9793d942015-02-18 15:13:20 +010061 }
62
63 user := map[string]interface{}{
64 "name": opts.Name,
65 "password": opts.Password,
66 }
67
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010068 if opts.Host != "" {
69 user["host"] = opts.Host
70 }
71
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010072 dbs := make([]map[string]string, len(opts.Databases))
73 for i, db := range opts.Databases {
74 dbs[i] = map[string]string{"name": db.Name}
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010075 }
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010076
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010077 if len(dbs) > 0 {
78 user["databases"] = dbs
79 }
80
81 return user, nil
82}
83
Jamie Hannaford9793d942015-02-18 15:13:20 +010084// BatchCreateOpts allows multiple users to be created at once.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010085type BatchCreateOpts []CreateOpts
86
Jamie Hannaford9793d942015-02-18 15:13:20 +010087// ToUserCreateMap will generate a JSON map.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010088func (opts BatchCreateOpts) ToUserCreateMap() (map[string]interface{}, error) {
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010089 users := make([]map[string]interface{}, len(opts))
90 for i, opt := range opts {
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010091 user, err := opt.ToMap()
92 if err != nil {
93 return nil, err
94 }
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010095 users[i] = user
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010096 }
97 return map[string]interface{}{"users": users}, nil
98}
99
Jamie Hannaford9793d942015-02-18 15:13:20 +0100100// Create asynchronously provisions a new user for the specified database
101// instance based on the configuration defined in CreateOpts. If databases are
102// assigned for a particular user, the user will be granted all privileges
103// for those specified databases. "root" is a reserved name and cannot be used.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100104func Create(client *gophercloud.ServiceClient, instanceID string, opts CreateOptsBuilder) CreateResult {
105 var res CreateResult
106
107 reqBody, err := opts.ToUserCreateMap()
108 if err != nil {
109 res.Err = err
110 return res
111 }
112
Jon Perritta33da232016-03-02 04:43:08 -0600113 _, res.Err = client.Request("POST", baseURL(client, instanceID), &gophercloud.RequestOpts{
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100114 JSONBody: &reqBody,
115 OkCodes: []int{202},
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100116 })
117
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100118 return res
119}
120
Jamie Hannaford9793d942015-02-18 15:13:20 +0100121// List will list all the users associated with a specified database instance,
122// along with their associated databases. This operation will not return any
123// system users or administrators for a database.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100124func List(client *gophercloud.ServiceClient, instanceID string) pagination.Pager {
125 createPageFn := func(r pagination.PageResult) pagination.Page {
126 return UserPage{pagination.LinkedPageBase{PageResult: r}}
127 }
128
129 return pagination.NewPager(client, baseURL(client, instanceID), createPageFn)
130}
131
Jamie Hannaford9793d942015-02-18 15:13:20 +0100132// Delete will permanently delete a user from a specified database instance.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100133func Delete(client *gophercloud.ServiceClient, instanceID, userName string) DeleteResult {
134 var res DeleteResult
135
Jon Perritta33da232016-03-02 04:43:08 -0600136 _, res.Err = client.Request("DELETE", userURL(client, instanceID, userName), &gophercloud.RequestOpts{
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100137 OkCodes: []int{202},
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100138 })
139
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100140 return res
141}