blob: 7533fc494bed75dd43baa8c581da0ed6bbd57ded [file] [log] [blame]
Jamie Hannafordaf4570f2015-02-12 13:33:25 +01001package users
2
3import (
Jamie Hannaford9793d942015-02-18 15:13:20 +01004 "errors"
5
Jamie Hannafordaf4570f2015-02-12 13:33:25 +01006 "github.com/rackspace/gophercloud"
7 db "github.com/rackspace/gophercloud/openstack/db/v1/databases"
8 "github.com/rackspace/gophercloud/pagination"
9)
10
Jamie Hannaford9793d942015-02-18 15:13:20 +010011// CreateOptsBuilder is the top-level interface for creating JSON maps.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010012type CreateOptsBuilder interface {
13 ToUserCreateMap() (map[string]interface{}, error)
14}
15
16// CreateOpts is the struct responsible for configuring a new user; often in the
17// context of an instance.
18type CreateOpts struct {
Jamie Hannaford9793d942015-02-18 15:13:20 +010019 // [REQUIRED] Specifies a name for the user. Valid names can be composed
20 // of the following characters: letters (either case); numbers; these
21 // characters '@', '?', '#', ' ' but NEVER beginning a name string; '_' is
22 // permitted anywhere. Prohibited characters that are forbidden include:
23 // single quotes, double quotes, back quotes, semicolons, commas, backslashes,
24 // and forward slashes. Spaces at the front or end of a user name are also
25 // not permitted.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010026 Name string
27
Jamie Hannaford9793d942015-02-18 15:13:20 +010028 // [REQUIRED] Specifies a password for the user.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010029 Password string
30
Jamie Hannaford9793d942015-02-18 15:13:20 +010031 // [OPTIONAL] An array of databases that this user will connect to. The
32 // "name" field is the only requirement for each option.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010033 Databases db.BatchCreateOpts
34
Jamie Hannaford9793d942015-02-18 15:13:20 +010035 // [OPTIONAL] Specifies the host from which a user is allowed to connect to
36 // the database. Possible values are a string containing an IPv4 address or
37 // "%" to allow connecting from any host. Optional; the default is "%".
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010038 Host string
39}
40
Jamie Hannaford9793d942015-02-18 15:13:20 +010041// ToMap is a convenience function for creating sub-maps for individual users.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010042func (opts CreateOpts) ToMap() (map[string]interface{}, error) {
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010043
Jamie Hannaford9793d942015-02-18 15:13:20 +010044 if opts.Name == "root" {
45 return nil, errors.New("root is a reserved user name and cannot be used")
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010046 }
Jamie Hannaford9793d942015-02-18 15:13:20 +010047 if opts.Name == "" {
48 return nil, errors.New("Name is a required field")
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010049 }
Jamie Hannaford9793d942015-02-18 15:13:20 +010050 if opts.Password == "" {
51 return nil, errors.New("Password is a required field")
52 }
53
54 user := map[string]interface{}{
55 "name": opts.Name,
56 "password": opts.Password,
57 }
58
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010059 if opts.Host != "" {
60 user["host"] = opts.Host
61 }
62
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010063 dbs := make([]map[string]string, len(opts.Databases))
64 for i, db := range opts.Databases {
65 dbs[i] = map[string]string{"name": db.Name}
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010066 }
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010067
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010068 if len(dbs) > 0 {
69 user["databases"] = dbs
70 }
71
72 return user, nil
73}
74
Jamie Hannaford9793d942015-02-18 15:13:20 +010075// BatchCreateOpts allows multiple users to be created at once.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010076type BatchCreateOpts []CreateOpts
77
Jamie Hannaford9793d942015-02-18 15:13:20 +010078// ToUserCreateMap will generate a JSON map.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010079func (opts BatchCreateOpts) ToUserCreateMap() (map[string]interface{}, error) {
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010080 users := make([]map[string]interface{}, len(opts))
81 for i, opt := range opts {
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010082 user, err := opt.ToMap()
83 if err != nil {
84 return nil, err
85 }
Jamie Hannaford257c8dc2015-02-25 14:40:22 +010086 users[i] = user
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010087 }
88 return map[string]interface{}{"users": users}, nil
89}
90
Jamie Hannaford9793d942015-02-18 15:13:20 +010091// Create asynchronously provisions a new user for the specified database
92// instance based on the configuration defined in CreateOpts. If databases are
93// assigned for a particular user, the user will be granted all privileges
94// for those specified databases. "root" is a reserved name and cannot be used.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +010095func Create(client *gophercloud.ServiceClient, instanceID string, opts CreateOptsBuilder) CreateResult {
96 var res CreateResult
97
98 reqBody, err := opts.ToUserCreateMap()
99 if err != nil {
100 res.Err = err
101 return res
102 }
103
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100104 _, res.Err = client.Request("POST", baseURL(client, instanceID), gophercloud.RequestOpts{
105 JSONBody: &reqBody,
106 OkCodes: []int{202},
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100107 })
108
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100109 return res
110}
111
Jamie Hannaford9793d942015-02-18 15:13:20 +0100112// List will list all the users associated with a specified database instance,
113// along with their associated databases. This operation will not return any
114// system users or administrators for a database.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100115func List(client *gophercloud.ServiceClient, instanceID string) pagination.Pager {
116 createPageFn := func(r pagination.PageResult) pagination.Page {
117 return UserPage{pagination.LinkedPageBase{PageResult: r}}
118 }
119
120 return pagination.NewPager(client, baseURL(client, instanceID), createPageFn)
121}
122
Jamie Hannaford9793d942015-02-18 15:13:20 +0100123// Delete will permanently delete a user from a specified database instance.
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100124func Delete(client *gophercloud.ServiceClient, instanceID, userName string) DeleteResult {
125 var res DeleteResult
126
Jamie Hannaforda50d1352015-02-18 11:38:38 +0100127 _, res.Err = client.Request("DELETE", userURL(client, instanceID, userName), gophercloud.RequestOpts{
128 OkCodes: []int{202},
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100129 })
130
Jamie Hannafordaf4570f2015-02-12 13:33:25 +0100131 return res
132}