github.com/gophercloud/gophercloud@v1.11.0/openstack/identity/v3/projects/requests.go (about) 1 package projects 2 3 import ( 4 "net/url" 5 "strings" 6 7 "github.com/gophercloud/gophercloud" 8 "github.com/gophercloud/gophercloud/pagination" 9 ) 10 11 // ListOptsBuilder allows extensions to add additional parameters to 12 // the List request 13 type ListOptsBuilder interface { 14 ToProjectListQuery() (string, error) 15 } 16 17 // ListOpts enables filtering of a list request. 18 type ListOpts struct { 19 // DomainID filters the response by a domain ID. 20 DomainID string `q:"domain_id"` 21 22 // Enabled filters the response by enabled projects. 23 Enabled *bool `q:"enabled"` 24 25 // IsDomain filters the response by projects that are domains. 26 // Setting this to true is effectively listing domains. 27 IsDomain *bool `q:"is_domain"` 28 29 // Name filters the response by project name. 30 Name string `q:"name"` 31 32 // ParentID filters the response by projects of a given parent project. 33 ParentID string `q:"parent_id"` 34 35 // Tags filters on specific project tags. All tags must be present for the project. 36 Tags string `q:"tags"` 37 38 // TagsAny filters on specific project tags. At least one of the tags must be present for the project. 39 TagsAny string `q:"tags-any"` 40 41 // NotTags filters on specific project tags. All tags must be absent for the project. 42 NotTags string `q:"not-tags"` 43 44 // NotTagsAny filters on specific project tags. At least one of the tags must be absent for the project. 45 NotTagsAny string `q:"not-tags-any"` 46 47 // Filters filters the response by custom filters such as 48 // 'name__contains=foo' 49 Filters map[string]string `q:"-"` 50 } 51 52 // ToProjectListQuery formats a ListOpts into a query string. 53 func (opts ListOpts) ToProjectListQuery() (string, error) { 54 q, err := gophercloud.BuildQueryString(opts) 55 if err != nil { 56 return "", err 57 } 58 59 params := q.Query() 60 for k, v := range opts.Filters { 61 i := strings.Index(k, "__") 62 if i > 0 && i < len(k)-2 { 63 params.Add(k, v) 64 } else { 65 return "", InvalidListFilter{FilterName: k} 66 } 67 } 68 69 q = &url.URL{RawQuery: params.Encode()} 70 return q.String(), err 71 } 72 73 // List enumerates the Projects to which the current token has access. 74 func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { 75 url := listURL(client) 76 if opts != nil { 77 query, err := opts.ToProjectListQuery() 78 if err != nil { 79 return pagination.Pager{Err: err} 80 } 81 url += query 82 } 83 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 84 return ProjectPage{pagination.LinkedPageBase{PageResult: r}} 85 }) 86 } 87 88 // ListAvailable enumerates the Projects which are available to a specific user. 89 func ListAvailable(client *gophercloud.ServiceClient) pagination.Pager { 90 url := listAvailableURL(client) 91 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 92 return ProjectPage{pagination.LinkedPageBase{PageResult: r}} 93 }) 94 } 95 96 // Get retrieves details on a single project, by ID. 97 func Get(client *gophercloud.ServiceClient, id string) (r GetResult) { 98 resp, err := client.Get(getURL(client, id), &r.Body, nil) 99 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 100 return 101 } 102 103 // CreateOptsBuilder allows extensions to add additional parameters to 104 // the Create request. 105 type CreateOptsBuilder interface { 106 ToProjectCreateMap() (map[string]interface{}, error) 107 } 108 109 // CreateOpts represents parameters used to create a project. 110 type CreateOpts struct { 111 // DomainID is the ID this project will belong under. 112 DomainID string `json:"domain_id,omitempty"` 113 114 // Enabled sets the project status to enabled or disabled. 115 Enabled *bool `json:"enabled,omitempty"` 116 117 // IsDomain indicates if this project is a domain. 118 IsDomain *bool `json:"is_domain,omitempty"` 119 120 // Name is the name of the project. 121 Name string `json:"name" required:"true"` 122 123 // ParentID specifies the parent project of this new project. 124 ParentID string `json:"parent_id,omitempty"` 125 126 // Description is the description of the project. 127 Description string `json:"description,omitempty"` 128 129 // Tags is a list of tags to associate with the project. 130 Tags []string `json:"tags,omitempty"` 131 132 // Extra is free-form extra key/value pairs to describe the project. 133 Extra map[string]interface{} `json:"-"` 134 135 // Options are defined options in the API to enable certain features. 136 Options map[Option]interface{} `json:"options,omitempty"` 137 } 138 139 // ToProjectCreateMap formats a CreateOpts into a create request. 140 func (opts CreateOpts) ToProjectCreateMap() (map[string]interface{}, error) { 141 b, err := gophercloud.BuildRequestBody(opts, "project") 142 143 if err != nil { 144 return nil, err 145 } 146 147 if opts.Extra != nil { 148 if v, ok := b["project"].(map[string]interface{}); ok { 149 for key, value := range opts.Extra { 150 v[key] = value 151 } 152 } 153 } 154 155 return b, nil 156 } 157 158 // Create creates a new Project. 159 func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 160 b, err := opts.ToProjectCreateMap() 161 if err != nil { 162 r.Err = err 163 return 164 } 165 resp, err := client.Post(createURL(client), &b, &r.Body, nil) 166 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 167 return 168 } 169 170 // Delete deletes a project. 171 func Delete(client *gophercloud.ServiceClient, projectID string) (r DeleteResult) { 172 resp, err := client.Delete(deleteURL(client, projectID), nil) 173 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 174 return 175 } 176 177 // UpdateOptsBuilder allows extensions to add additional parameters to 178 // the Update request. 179 type UpdateOptsBuilder interface { 180 ToProjectUpdateMap() (map[string]interface{}, error) 181 } 182 183 // UpdateOpts represents parameters to update a project. 184 type UpdateOpts struct { 185 // DomainID is the ID this project will belong under. 186 DomainID string `json:"domain_id,omitempty"` 187 188 // Enabled sets the project status to enabled or disabled. 189 Enabled *bool `json:"enabled,omitempty"` 190 191 // IsDomain indicates if this project is a domain. 192 IsDomain *bool `json:"is_domain,omitempty"` 193 194 // Name is the name of the project. 195 Name string `json:"name,omitempty"` 196 197 // ParentID specifies the parent project of this new project. 198 ParentID string `json:"parent_id,omitempty"` 199 200 // Description is the description of the project. 201 Description *string `json:"description,omitempty"` 202 203 // Tags is a list of tags to associate with the project. 204 Tags *[]string `json:"tags,omitempty"` 205 206 // Extra is free-form extra key/value pairs to describe the project. 207 Extra map[string]interface{} `json:"-"` 208 209 // Options are defined options in the API to enable certain features. 210 Options map[Option]interface{} `json:"options,omitempty"` 211 } 212 213 // ToUpdateCreateMap formats a UpdateOpts into an update request. 214 func (opts UpdateOpts) ToProjectUpdateMap() (map[string]interface{}, error) { 215 b, err := gophercloud.BuildRequestBody(opts, "project") 216 217 if err != nil { 218 return nil, err 219 } 220 221 if opts.Extra != nil { 222 if v, ok := b["project"].(map[string]interface{}); ok { 223 for key, value := range opts.Extra { 224 v[key] = value 225 } 226 } 227 } 228 229 return b, nil 230 } 231 232 // Update modifies the attributes of a project. 233 func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { 234 b, err := opts.ToProjectUpdateMap() 235 if err != nil { 236 r.Err = err 237 return 238 } 239 resp, err := client.Patch(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ 240 OkCodes: []int{200}, 241 }) 242 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 243 return 244 }