github.com/leeclow-ops/gophercloud@v1.2.1/openstack/networking/v2/ports/requests.go (about) 1 package ports 2 3 import ( 4 "fmt" 5 "net/url" 6 "strings" 7 8 "github.com/leeclow-ops/gophercloud" 9 "github.com/leeclow-ops/gophercloud/pagination" 10 ) 11 12 // ListOptsBuilder allows extensions to add additional parameters to the 13 // List request. 14 type ListOptsBuilder interface { 15 ToPortListQuery() (string, error) 16 } 17 18 // ListOpts allows the filtering and sorting of paginated collections through 19 // the API. Filtering is achieved by passing in struct field values that map to 20 // the port attributes you want to see returned. SortKey allows you to sort 21 // by a particular port attribute. SortDir sets the direction, and is either 22 // `asc' or `desc'. Marker and Limit are used for pagination. 23 type ListOpts struct { 24 Status string `q:"status"` 25 Name string `q:"name"` 26 Description string `q:"description"` 27 AdminStateUp *bool `q:"admin_state_up"` 28 NetworkID string `q:"network_id"` 29 TenantID string `q:"tenant_id"` 30 ProjectID string `q:"project_id"` 31 DeviceOwner string `q:"device_owner"` 32 MACAddress string `q:"mac_address"` 33 ID string `q:"id"` 34 DeviceID string `q:"device_id"` 35 Limit int `q:"limit"` 36 Marker string `q:"marker"` 37 SortKey string `q:"sort_key"` 38 SortDir string `q:"sort_dir"` 39 Tags string `q:"tags"` 40 TagsAny string `q:"tags-any"` 41 NotTags string `q:"not-tags"` 42 NotTagsAny string `q:"not-tags-any"` 43 FixedIPs []FixedIPOpts 44 } 45 46 type FixedIPOpts struct { 47 IPAddress string 48 IPAddressSubstr string 49 SubnetID string 50 } 51 52 func (f FixedIPOpts) String() string { 53 var res []string 54 if f.IPAddress != "" { 55 res = append(res, fmt.Sprintf("ip_address=%s", f.IPAddress)) 56 } 57 if f.IPAddressSubstr != "" { 58 res = append(res, fmt.Sprintf("ip_address_substr=%s", f.IPAddressSubstr)) 59 } 60 if f.SubnetID != "" { 61 res = append(res, fmt.Sprintf("subnet_id=%s", f.SubnetID)) 62 } 63 return strings.Join(res, ",") 64 } 65 66 // ToPortListQuery formats a ListOpts into a query string. 67 func (opts ListOpts) ToPortListQuery() (string, error) { 68 q, err := gophercloud.BuildQueryString(opts) 69 params := q.Query() 70 for _, fixedIP := range opts.FixedIPs { 71 params.Add("fixed_ips", fixedIP.String()) 72 } 73 q = &url.URL{RawQuery: params.Encode()} 74 return q.String(), err 75 } 76 77 // List returns a Pager which allows you to iterate over a collection of 78 // ports. It accepts a ListOpts struct, which allows you to filter and sort 79 // the returned collection for greater efficiency. 80 // 81 // Default policy settings return only those ports that are owned by the tenant 82 // who submits the request, unless the request is submitted by a user with 83 // administrative rights. 84 func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { 85 url := listURL(c) 86 if opts != nil { 87 query, err := opts.ToPortListQuery() 88 if err != nil { 89 return pagination.Pager{Err: err} 90 } 91 url += query 92 } 93 return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { 94 return PortPage{pagination.LinkedPageBase{PageResult: r}} 95 }) 96 } 97 98 // Get retrieves a specific port based on its unique ID. 99 func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { 100 resp, err := c.Get(getURL(c, id), &r.Body, nil) 101 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 102 return 103 } 104 105 // CreateOptsBuilder allows extensions to add additional parameters to the 106 // Create request. 107 type CreateOptsBuilder interface { 108 ToPortCreateMap() (map[string]interface{}, error) 109 } 110 111 // CreateOpts represents the attributes used when creating a new port. 112 type CreateOpts struct { 113 NetworkID string `json:"network_id" required:"true"` 114 Name string `json:"name,omitempty"` 115 Description string `json:"description,omitempty"` 116 AdminStateUp *bool `json:"admin_state_up,omitempty"` 117 MACAddress string `json:"mac_address,omitempty"` 118 FixedIPs interface{} `json:"fixed_ips,omitempty"` 119 DeviceID string `json:"device_id,omitempty"` 120 DeviceOwner string `json:"device_owner,omitempty"` 121 TenantID string `json:"tenant_id,omitempty"` 122 ProjectID string `json:"project_id,omitempty"` 123 SecurityGroups *[]string `json:"security_groups,omitempty"` 124 AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"` 125 PropagateUplinkStatus *bool `json:"propagate_uplink_status,omitempty"` 126 ValueSpecs *map[string]string `json:"value_specs,omitempty"` 127 } 128 129 // ToPortCreateMap builds a request body from CreateOpts. 130 func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) { 131 return gophercloud.BuildRequestBody(opts, "port") 132 } 133 134 // Create accepts a CreateOpts struct and creates a new network using the values 135 // provided. You must remember to provide a NetworkID value. 136 func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 137 b, err := opts.ToPortCreateMap() 138 if err != nil { 139 r.Err = err 140 return 141 } 142 resp, err := c.Post(createURL(c), b, &r.Body, nil) 143 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 144 return 145 } 146 147 // UpdateOptsBuilder allows extensions to add additional parameters to the 148 // Update request. 149 type UpdateOptsBuilder interface { 150 ToPortUpdateMap() (map[string]interface{}, error) 151 } 152 153 // UpdateOpts represents the attributes used when updating an existing port. 154 type UpdateOpts struct { 155 Name *string `json:"name,omitempty"` 156 Description *string `json:"description,omitempty"` 157 AdminStateUp *bool `json:"admin_state_up,omitempty"` 158 FixedIPs interface{} `json:"fixed_ips,omitempty"` 159 DeviceID *string `json:"device_id,omitempty"` 160 DeviceOwner *string `json:"device_owner,omitempty"` 161 SecurityGroups *[]string `json:"security_groups,omitempty"` 162 AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"` 163 PropagateUplinkStatus *bool `json:"propagate_uplink_status,omitempty"` 164 ValueSpecs *map[string]string `json:"value_specs,omitempty"` 165 166 // RevisionNumber implements extension:standard-attr-revisions. If != "" it 167 // will set revision_number=%s. If the revision number does not match, the 168 // update will fail. 169 RevisionNumber *int `json:"-" h:"If-Match"` 170 } 171 172 // ToPortUpdateMap builds a request body from UpdateOpts. 173 func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) { 174 return gophercloud.BuildRequestBody(opts, "port") 175 } 176 177 // Update accepts a UpdateOpts struct and updates an existing port using the 178 // values provided. 179 func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { 180 b, err := opts.ToPortUpdateMap() 181 if err != nil { 182 r.Err = err 183 return 184 } 185 h, err := gophercloud.BuildHeaders(opts) 186 if err != nil { 187 r.Err = err 188 return 189 } 190 for k := range h { 191 if k == "If-Match" { 192 h[k] = fmt.Sprintf("revision_number=%s", h[k]) 193 } 194 } 195 resp, err := c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ 196 MoreHeaders: h, 197 OkCodes: []int{200, 201}, 198 }) 199 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 200 return 201 } 202 203 // Delete accepts a unique ID and deletes the port associated with it. 204 func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { 205 resp, err := c.Delete(deleteURL(c, id), nil) 206 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 207 return 208 }