blob: ab5d6927bdf7d15497db2d544fcd2604b47a002b [file] [log] [blame]
Jamie Hannaford548d3402014-09-18 15:50:08 +02001package ports
2
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "github.com/gophercloud/gophercloud"
5 "github.com/gophercloud/gophercloud/pagination"
Jamie Hannaford548d3402014-09-18 15:50:08 +02006)
7
Jon Perritt04851d32014-10-14 02:07:13 -05008// ListOptsBuilder allows extensions to add additional parameters to the
9// List request.
10type ListOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -050011 ToPortListQuery() (string, error)
Jon Perritt04851d32014-10-14 02:07:13 -050012}
13
Jamie Hannaford686c4962014-09-23 10:46:20 +020014// ListOpts allows the filtering and sorting of paginated collections through
15// the API. Filtering is achieved by passing in struct field values that map to
16// the port attributes you want to see returned. SortKey allows you to sort
17// by a particular port attribute. SortDir sets the direction, and is either
18// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford548d3402014-09-18 15:50:08 +020019type ListOpts struct {
Jamie Hannaford92523e32014-10-02 11:08:36 +020020 Status string `q:"status"`
21 Name string `q:"name"`
22 AdminStateUp *bool `q:"admin_state_up"`
23 NetworkID string `q:"network_id"`
24 TenantID string `q:"tenant_id"`
25 DeviceOwner string `q:"device_owner"`
26 MACAddress string `q:"mac_address"`
27 ID string `q:"id"`
28 DeviceID string `q:"device_id"`
29 Limit int `q:"limit"`
30 Marker string `q:"marker"`
31 SortKey string `q:"sort_key"`
32 SortDir string `q:"sort_dir"`
Jamie Hannaford548d3402014-09-18 15:50:08 +020033}
34
Jon Perritt26780d52014-10-14 11:35:58 -050035// ToPortListQuery formats a ListOpts into a query string.
36func (opts ListOpts) ToPortListQuery() (string, error) {
Jon Perritt04851d32014-10-14 02:07:13 -050037 q, err := gophercloud.BuildQueryString(opts)
Jon Perritte1c6ceb2016-03-14 12:09:36 -050038 return q.String(), err
Jon Perritt04851d32014-10-14 02:07:13 -050039}
40
Jamie Hannaford686c4962014-09-23 10:46:20 +020041// List returns a Pager which allows you to iterate over a collection of
42// ports. It accepts a ListOpts struct, which allows you to filter and sort
43// the returned collection for greater efficiency.
44//
45// Default policy settings return only those ports that are owned by the tenant
Alex Gaynora6d5f9f2014-10-27 10:52:32 -070046// who submits the request, unless the request is submitted by a user with
Jamie Hannaford686c4962014-09-23 10:46:20 +020047// administrative rights.
Jon Perritt04851d32014-10-14 02:07:13 -050048func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
49 url := listURL(c)
50 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -050051 query, err := opts.ToPortListQuery()
Jon Perritt04851d32014-10-14 02:07:13 -050052 if err != nil {
53 return pagination.Pager{Err: err}
54 }
55 url += query
Jamie Hannaford548d3402014-09-18 15:50:08 +020056 }
Ash Wilsonb8b16f82014-10-20 10:19:49 -040057 return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
58 return PortPage{pagination.LinkedPageBase{PageResult: r}}
Jamie Hannaford548d3402014-09-18 15:50:08 +020059 })
60}
Jamie Hannaforda311f182014-09-19 11:19:10 +020061
Jamie Hannaford686c4962014-09-23 10:46:20 +020062// Get retrieves a specific port based on its unique ID.
Jamie Hannafordd9036422014-09-23 17:50:24 +020063func Get(c *gophercloud.ServiceClient, id string) GetResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050064 var r GetResult
65 _, r.Err = c.Get(getURL(c, id), &r.Body, nil)
66 return r
Jamie Hannaforda311f182014-09-19 11:19:10 +020067}
Jamie Hannaforda5fb7822014-09-19 15:07:02 +020068
Jon Perritt04851d32014-10-14 02:07:13 -050069// CreateOptsBuilder is the interface options structs have to satisfy in order
70// to be used in the main Create operation in this package. Since many
71// extensions decorate or modify the common logic, it is useful for them to
72// satisfy a basic interface in order for them to be used.
73type CreateOptsBuilder interface {
74 ToPortCreateMap() (map[string]interface{}, error)
75}
76
Jamie Hannaford686c4962014-09-23 10:46:20 +020077// CreateOpts represents the attributes used when creating a new port.
Jamie Hannaford965ae702014-09-22 14:58:19 +020078type CreateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050079 NetworkID string `json:"network_id" required:"true"`
80 Name string `json:"name,omitempty"`
81 AdminStateUp *bool `json:"admin_state_up,omitempty"`
82 MACAddress string `json:"mac_address,omitempty"`
83 FixedIPs interface{} `json:"fixed_ips,omitempty"`
84 DeviceID string `json:"device_id,omitempty"`
85 DeviceOwner string `json:"device_owner,omitempty"`
86 TenantID string `json:"tenant_id,omitempty"`
87 SecurityGroups []string `json:"security_groups,omitempty"`
88 AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +020089}
90
Jon Perritt04851d32014-10-14 02:07:13 -050091// ToPortCreateMap casts a CreateOpts struct to a map.
92func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050093 return gophercloud.BuildRequestBody(opts, "port")
Jon Perritt04851d32014-10-14 02:07:13 -050094}
95
Jamie Hannaford686c4962014-09-23 10:46:20 +020096// Create accepts a CreateOpts struct and creates a new network using the values
97// provided. You must remember to provide a NetworkID value.
Jon Perritt04851d32014-10-14 02:07:13 -050098func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050099 var r CreateResult
100 b, err := opts.ToPortCreateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500101 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500102 r.Err = err
103 return r
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200104 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500105 _, r.Err = c.Post(createURL(c), b, &r.Body, nil)
106 return r
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200107}
108
Jon Perritt04851d32014-10-14 02:07:13 -0500109// UpdateOptsBuilder is the interface options structs have to satisfy in order
110// to be used in the main Update operation in this package. Since many
111// extensions decorate or modify the common logic, it is useful for them to
112// satisfy a basic interface in order for them to be used.
113type UpdateOptsBuilder interface {
114 ToPortUpdateMap() (map[string]interface{}, error)
115}
116
Jamie Hannaford686c4962014-09-23 10:46:20 +0200117// UpdateOpts represents the attributes used when updating an existing port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200118type UpdateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500119 Name string `json:"name,omitempty"`
120 AdminStateUp *bool `json:"admin_state_up,omitempty"`
121 FixedIPs interface{} `json:"fixed_ips,omitempty"`
122 DeviceID string `json:"device_id,omitempty"`
123 DeviceOwner string `json:"device_owner,omitempty"`
124 SecurityGroups []string `json:"security_groups,omitempty"`
125 AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200126}
127
Jon Perritt04851d32014-10-14 02:07:13 -0500128// ToPortUpdateMap casts an UpdateOpts struct to a map.
129func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500130 return gophercloud.BuildRequestBody(opts, "port")
Jon Perritt04851d32014-10-14 02:07:13 -0500131}
132
Jamie Hannaford686c4962014-09-23 10:46:20 +0200133// Update accepts a UpdateOpts struct and updates an existing port using the
134// values provided.
Jon Perritt04851d32014-10-14 02:07:13 -0500135func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500136 var r UpdateResult
137 b, err := opts.ToPortUpdateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500138 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500139 r.Err = err
140 return r
Jon Perritt04851d32014-10-14 02:07:13 -0500141 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500142 _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford059e1502015-03-24 16:20:32 +0100143 OkCodes: []int{200, 201},
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200144 })
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500145 return r
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200146}
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200147
Jamie Hannaford686c4962014-09-23 10:46:20 +0200148// Delete accepts a unique ID and deletes the port associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200149func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500150 var r DeleteResult
151 _, r.Err = c.Delete(deleteURL(c, id), nil)
152 return r
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200153}
Jon Perritt7ab13282015-06-28 18:47:19 -0600154
jrperritt14f716b2015-06-28 19:07:52 -0600155// IDFromName is a convenience function that returns a port's ID given its name.
Jon Perritt7ab13282015-06-28 18:47:19 -0600156func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritte3cb7e42016-03-07 06:24:11 -0600157 count := 0
158 id := ""
Jon Perritte3cb7e42016-03-07 06:24:11 -0600159 pages, err := List(client, nil).AllPages()
160 if err != nil {
161 return "", err
162 }
Jon Perritt7ab13282015-06-28 18:47:19 -0600163
Jon Perritte3cb7e42016-03-07 06:24:11 -0600164 all, err := ExtractPorts(pages)
165 if err != nil {
166 return "", err
167 }
168
169 for _, s := range all {
170 if s.Name == name {
171 count++
172 id = s.ID
173 }
174 }
175
176 switch count {
Jon Perritt7ab13282015-06-28 18:47:19 -0600177 case 0:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500178 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "port"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600179 case 1:
Jon Perritte3cb7e42016-03-07 06:24:11 -0600180 return id, nil
Jon Perritt7ab13282015-06-28 18:47:19 -0600181 default:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500182 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "port"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600183 }
184}