blob: 896a007175b0595a703625b8c2c0ed2a37609079 [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"
Krzysztof Szukiełojć24a29ce2017-05-07 14:24:02 +02005 "gerrit.mcp.mirantis.net/debian/gophercloud.git/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.
Jon Perritt3860b512016-03-29 12:01:48 -050063func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050064 _, r.Err = c.Get(getURL(c, id), &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -050065 return
Jamie Hannaforda311f182014-09-19 11:19:10 +020066}
Jamie Hannaforda5fb7822014-09-19 15:07:02 +020067
Jon Perritt04851d32014-10-14 02:07:13 -050068// CreateOptsBuilder is the interface options structs have to satisfy in order
69// to be used in the main Create operation in this package. Since many
70// extensions decorate or modify the common logic, it is useful for them to
71// satisfy a basic interface in order for them to be used.
72type CreateOptsBuilder interface {
73 ToPortCreateMap() (map[string]interface{}, error)
74}
75
Jamie Hannaford686c4962014-09-23 10:46:20 +020076// CreateOpts represents the attributes used when creating a new port.
Jamie Hannaford965ae702014-09-22 14:58:19 +020077type CreateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050078 NetworkID string `json:"network_id" required:"true"`
79 Name string `json:"name,omitempty"`
80 AdminStateUp *bool `json:"admin_state_up,omitempty"`
81 MACAddress string `json:"mac_address,omitempty"`
82 FixedIPs interface{} `json:"fixed_ips,omitempty"`
83 DeviceID string `json:"device_id,omitempty"`
84 DeviceOwner string `json:"device_owner,omitempty"`
85 TenantID string `json:"tenant_id,omitempty"`
86 SecurityGroups []string `json:"security_groups,omitempty"`
87 AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +020088}
89
Jon Perritt04851d32014-10-14 02:07:13 -050090// ToPortCreateMap casts a CreateOpts struct to a map.
91func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050092 return gophercloud.BuildRequestBody(opts, "port")
Jon Perritt04851d32014-10-14 02:07:13 -050093}
94
Jamie Hannaford686c4962014-09-23 10:46:20 +020095// Create accepts a CreateOpts struct and creates a new network using the values
96// provided. You must remember to provide a NetworkID value.
Jon Perritt3860b512016-03-29 12:01:48 -050097func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050098 b, err := opts.ToPortCreateMap()
Jon Perritt04851d32014-10-14 02:07:13 -050099 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500100 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500101 return
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200102 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500103 _, r.Err = c.Post(createURL(c), b, &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500104 return
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200105}
106
Jon Perritt04851d32014-10-14 02:07:13 -0500107// UpdateOptsBuilder is the interface options structs have to satisfy in order
108// to be used in the main Update operation in this package. Since many
109// extensions decorate or modify the common logic, it is useful for them to
110// satisfy a basic interface in order for them to be used.
111type UpdateOptsBuilder interface {
112 ToPortUpdateMap() (map[string]interface{}, error)
113}
114
Jamie Hannaford686c4962014-09-23 10:46:20 +0200115// UpdateOpts represents the attributes used when updating an existing port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200116type UpdateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500117 Name string `json:"name,omitempty"`
118 AdminStateUp *bool `json:"admin_state_up,omitempty"`
119 FixedIPs interface{} `json:"fixed_ips,omitempty"`
120 DeviceID string `json:"device_id,omitempty"`
121 DeviceOwner string `json:"device_owner,omitempty"`
Joe Topjian6d2ec962017-02-13 21:23:55 -0700122 SecurityGroups []string `json:"security_groups"`
123 AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200124}
125
Jon Perritt04851d32014-10-14 02:07:13 -0500126// ToPortUpdateMap casts an UpdateOpts struct to a map.
127func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500128 return gophercloud.BuildRequestBody(opts, "port")
Jon Perritt04851d32014-10-14 02:07:13 -0500129}
130
Jamie Hannaford686c4962014-09-23 10:46:20 +0200131// Update accepts a UpdateOpts struct and updates an existing port using the
132// values provided.
Jon Perritt3860b512016-03-29 12:01:48 -0500133func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500134 b, err := opts.ToPortUpdateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500135 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500136 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500137 return
Jon Perritt04851d32014-10-14 02:07:13 -0500138 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500139 _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford059e1502015-03-24 16:20:32 +0100140 OkCodes: []int{200, 201},
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200141 })
jrperritt29ae6b32016-04-13 12:59:37 -0500142 return
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200143}
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200144
Jamie Hannaford686c4962014-09-23 10:46:20 +0200145// Delete accepts a unique ID and deletes the port associated with it.
Jon Perritt3860b512016-03-29 12:01:48 -0500146func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500147 _, r.Err = c.Delete(deleteURL(c, id), nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500148 return
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200149}
Jon Perritt7ab13282015-06-28 18:47:19 -0600150
jrperritt14f716b2015-06-28 19:07:52 -0600151// IDFromName is a convenience function that returns a port's ID given its name.
Jon Perritt7ab13282015-06-28 18:47:19 -0600152func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritte3cb7e42016-03-07 06:24:11 -0600153 count := 0
154 id := ""
Jon Perritte3cb7e42016-03-07 06:24:11 -0600155 pages, err := List(client, nil).AllPages()
156 if err != nil {
157 return "", err
158 }
Jon Perritt7ab13282015-06-28 18:47:19 -0600159
Jon Perritte3cb7e42016-03-07 06:24:11 -0600160 all, err := ExtractPorts(pages)
161 if err != nil {
162 return "", err
163 }
164
165 for _, s := range all {
166 if s.Name == name {
167 count++
168 id = s.ID
169 }
170 }
171
172 switch count {
Jon Perritt7ab13282015-06-28 18:47:19 -0600173 case 0:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500174 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "port"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600175 case 1:
Jon Perritte3cb7e42016-03-07 06:24:11 -0600176 return id, nil
Jon Perritt7ab13282015-06-28 18:47:19 -0600177 default:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500178 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "port"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600179 }
180}