github.com/gophercloud/gophercloud@v1.11.0/openstack/identity/v3/policies/requests.go (about) 1 package policies 2 3 import ( 4 "net/url" 5 "strings" 6 7 "github.com/gophercloud/gophercloud" 8 "github.com/gophercloud/gophercloud/pagination" 9 ) 10 11 const policyTypeMaxLength = 255 12 13 // ListOptsBuilder allows extensions to add additional parameters to 14 // the List request 15 type ListOptsBuilder interface { 16 ToPolicyListQuery() (string, error) 17 } 18 19 // ListOpts provides options to filter the List results. 20 type ListOpts struct { 21 // Type filters the response by MIME media type 22 // of the serialized policy blob. 23 Type string `q:"type"` 24 25 // Filters filters the response by custom filters such as 26 // 'type__contains=foo' 27 Filters map[string]string `q:"-"` 28 } 29 30 // ToPolicyListQuery formats a ListOpts into a query string. 31 func (opts ListOpts) ToPolicyListQuery() (string, error) { 32 q, err := gophercloud.BuildQueryString(opts) 33 if err != nil { 34 return "", err 35 } 36 37 params := q.Query() 38 for k, v := range opts.Filters { 39 i := strings.Index(k, "__") 40 if i > 0 && i < len(k)-2 { 41 params.Add(k, v) 42 } else { 43 return "", InvalidListFilter{FilterName: k} 44 } 45 } 46 47 q = &url.URL{RawQuery: params.Encode()} 48 return q.String(), err 49 } 50 51 // List enumerates the policies to which the current token has access. 52 func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { 53 url := listURL(client) 54 if opts != nil { 55 query, err := opts.ToPolicyListQuery() 56 if err != nil { 57 return pagination.Pager{Err: err} 58 } 59 url += query 60 } 61 62 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 63 return PolicyPage{pagination.LinkedPageBase{PageResult: r}} 64 }) 65 } 66 67 // CreateOptsBuilder allows extensions to add additional parameters to 68 // the Create request. 69 type CreateOptsBuilder interface { 70 ToPolicyCreateMap() (map[string]interface{}, error) 71 } 72 73 // CreateOpts provides options used to create a policy. 74 type CreateOpts struct { 75 // Type is the MIME media type of the serialized policy blob. 76 Type string `json:"type" required:"true"` 77 78 // Blob is the policy rule as a serialized blob. 79 Blob []byte `json:"-" required:"true"` 80 81 // Extra is free-form extra key/value pairs to describe the policy. 82 Extra map[string]interface{} `json:"-"` 83 } 84 85 // ToPolicyCreateMap formats a CreateOpts into a create request. 86 func (opts CreateOpts) ToPolicyCreateMap() (map[string]interface{}, error) { 87 if len(opts.Type) > policyTypeMaxLength { 88 return nil, StringFieldLengthExceedsLimit{ 89 Field: "type", 90 Limit: policyTypeMaxLength, 91 } 92 } 93 94 b, err := gophercloud.BuildRequestBody(opts, "policy") 95 if err != nil { 96 return nil, err 97 } 98 99 if v, ok := b["policy"].(map[string]interface{}); ok { 100 v["blob"] = string(opts.Blob) 101 102 if opts.Extra != nil { 103 for key, value := range opts.Extra { 104 v[key] = value 105 } 106 } 107 } 108 109 return b, nil 110 } 111 112 // Create creates a new Policy. 113 func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 114 b, err := opts.ToPolicyCreateMap() 115 if err != nil { 116 r.Err = err 117 return 118 } 119 resp, err := client.Post(createURL(client), &b, &r.Body, &gophercloud.RequestOpts{ 120 OkCodes: []int{201}, 121 }) 122 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 123 return 124 } 125 126 // Get retrieves details on a single policy, by ID. 127 func Get(client *gophercloud.ServiceClient, policyID string) (r GetResult) { 128 resp, err := client.Get(getURL(client, policyID), &r.Body, nil) 129 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 130 return 131 } 132 133 // UpdateOptsBuilder allows extensions to add additional parameters to 134 // the Update request. 135 type UpdateOptsBuilder interface { 136 ToPolicyUpdateMap() (map[string]interface{}, error) 137 } 138 139 // UpdateOpts provides options for updating a policy. 140 type UpdateOpts struct { 141 // Type is the MIME media type of the serialized policy blob. 142 Type string `json:"type,omitempty"` 143 144 // Blob is the policy rule as a serialized blob. 145 Blob []byte `json:"-"` 146 147 // Extra is free-form extra key/value pairs to describe the policy. 148 Extra map[string]interface{} `json:"-"` 149 } 150 151 // ToPolicyUpdateMap formats a UpdateOpts into an update request. 152 func (opts UpdateOpts) ToPolicyUpdateMap() (map[string]interface{}, error) { 153 if len(opts.Type) > policyTypeMaxLength { 154 return nil, StringFieldLengthExceedsLimit{ 155 Field: "type", 156 Limit: policyTypeMaxLength, 157 } 158 } 159 160 b, err := gophercloud.BuildRequestBody(opts, "policy") 161 if err != nil { 162 return nil, err 163 } 164 165 if v, ok := b["policy"].(map[string]interface{}); ok { 166 if len(opts.Blob) != 0 { 167 v["blob"] = string(opts.Blob) 168 } 169 170 if opts.Extra != nil { 171 for key, value := range opts.Extra { 172 v[key] = value 173 } 174 } 175 } 176 177 return b, nil 178 } 179 180 // Update updates an existing Role. 181 func Update(client *gophercloud.ServiceClient, policyID string, opts UpdateOptsBuilder) (r UpdateResult) { 182 b, err := opts.ToPolicyUpdateMap() 183 if err != nil { 184 r.Err = err 185 return 186 } 187 resp, err := client.Patch(updateURL(client, policyID), &b, &r.Body, &gophercloud.RequestOpts{ 188 OkCodes: []int{200}, 189 }) 190 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 191 return 192 } 193 194 // Delete deletes a policy. 195 func Delete(client *gophercloud.ServiceClient, policyID string) (r DeleteResult) { 196 resp, err := client.Delete(deleteURL(client, policyID), nil) 197 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 198 return 199 }