github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/networking/v2/ports/results.go (about) 1 package ports 2 3 import ( 4 "encoding/json" 5 "time" 6 7 "github.com/vnpaycloud-console/gophercloud/v2" 8 "github.com/vnpaycloud-console/gophercloud/v2/pagination" 9 ) 10 11 type commonResult struct { 12 gophercloud.Result 13 } 14 15 // Extract is a function that accepts a result and extracts a port resource. 16 func (r commonResult) Extract() (*Port, error) { 17 var s Port 18 err := r.ExtractInto(&s) 19 return &s, err 20 } 21 22 func (r commonResult) ExtractInto(v any) error { 23 return r.Result.ExtractIntoStructPtr(v, "port") 24 } 25 26 // CreateResult represents the result of a create operation. Call its Extract 27 // method to interpret it as a Port. 28 type CreateResult struct { 29 commonResult 30 } 31 32 // GetResult represents the result of a get operation. Call its Extract 33 // method to interpret it as a Port. 34 type GetResult struct { 35 commonResult 36 } 37 38 // UpdateResult represents the result of an update operation. Call its Extract 39 // method to interpret it as a Port. 40 type UpdateResult struct { 41 commonResult 42 } 43 44 // DeleteResult represents the result of a delete operation. Call its 45 // ExtractErr method to determine if the request succeeded or failed. 46 type DeleteResult struct { 47 gophercloud.ErrResult 48 } 49 50 // IP is a sub-struct that represents an individual IP. 51 type IP struct { 52 SubnetID string `json:"subnet_id"` 53 IPAddress string `json:"ip_address,omitempty"` 54 } 55 56 // AddressPair contains the IP Address and the MAC address. 57 type AddressPair struct { 58 IPAddress string `json:"ip_address,omitempty"` 59 MACAddress string `json:"mac_address,omitempty"` 60 } 61 62 // Port represents a Neutron port. See package documentation for a top-level 63 // description of what this is. 64 type Port struct { 65 // UUID for the port. 66 ID string `json:"id"` 67 68 // Network that this port is associated with. 69 NetworkID string `json:"network_id"` 70 71 // Human-readable name for the port. Might not be unique. 72 Name string `json:"name"` 73 74 // Describes the port. 75 Description string `json:"description"` 76 77 // Administrative state of port. If false (down), port does not forward 78 // packets. 79 AdminStateUp bool `json:"admin_state_up"` 80 81 // Indicates whether network is currently operational. Possible values include 82 // `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional 83 // values. 84 Status string `json:"status"` 85 86 // Mac address to use on this port. 87 MACAddress string `json:"mac_address"` 88 89 // Specifies IP addresses for the port thus associating the port itself with 90 // the subnets where the IP addresses are picked from 91 FixedIPs []IP `json:"fixed_ips"` 92 93 // TenantID is the project owner of the port. 94 TenantID string `json:"tenant_id"` 95 96 // ProjectID is the project owner of the port. 97 ProjectID string `json:"project_id"` 98 99 // Identifies the entity (e.g.: dhcp agent) using this port. 100 DeviceOwner string `json:"device_owner"` 101 102 // Specifies the IDs of any security groups associated with a port. 103 SecurityGroups []string `json:"security_groups"` 104 105 // Identifies the device (e.g., virtual server) using this port. 106 DeviceID string `json:"device_id"` 107 108 // Identifies the list of IP addresses the port will recognize/accept 109 AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"` 110 111 // Tags optionally set via extensions/attributestags 112 Tags []string `json:"tags"` 113 114 // PropagateUplinkStatus enables/disables propagate uplink status on the port. 115 PropagateUplinkStatus bool `json:"propagate_uplink_status"` 116 117 // RevisionNumber optionally set via extensions/standard-attr-revisions 118 RevisionNumber int `json:"revision_number"` 119 120 // Timestamp when the port was created 121 CreatedAt time.Time `json:"created_at"` 122 123 // Timestamp when the port was last updated 124 UpdatedAt time.Time `json:"updated_at"` 125 } 126 127 func (r *Port) UnmarshalJSON(b []byte) error { 128 type tmp Port 129 130 // Support for older neutron time format 131 var s1 struct { 132 tmp 133 CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"` 134 UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"` 135 } 136 137 err := json.Unmarshal(b, &s1) 138 if err == nil { 139 *r = Port(s1.tmp) 140 r.CreatedAt = time.Time(s1.CreatedAt) 141 r.UpdatedAt = time.Time(s1.UpdatedAt) 142 143 return nil 144 } 145 146 // Support for newer neutron time format 147 var s2 struct { 148 tmp 149 CreatedAt time.Time `json:"created_at"` 150 UpdatedAt time.Time `json:"updated_at"` 151 } 152 153 err = json.Unmarshal(b, &s2) 154 if err != nil { 155 return err 156 } 157 158 *r = Port(s2.tmp) 159 r.CreatedAt = time.Time(s2.CreatedAt) 160 r.UpdatedAt = time.Time(s2.UpdatedAt) 161 162 return nil 163 } 164 165 // PortPage is the page returned by a pager when traversing over a collection 166 // of network ports. 167 type PortPage struct { 168 pagination.LinkedPageBase 169 } 170 171 // NextPageURL is invoked when a paginated collection of ports has reached 172 // the end of a page and the pager seeks to traverse over a new one. In order 173 // to do this, it needs to construct the next page's URL. 174 func (r PortPage) NextPageURL() (string, error) { 175 var s struct { 176 Links []gophercloud.Link `json:"ports_links"` 177 } 178 err := r.ExtractInto(&s) 179 if err != nil { 180 return "", err 181 } 182 return gophercloud.ExtractNextURL(s.Links) 183 } 184 185 // IsEmpty checks whether a PortPage struct is empty. 186 func (r PortPage) IsEmpty() (bool, error) { 187 if r.StatusCode == 204 { 188 return true, nil 189 } 190 191 is, err := ExtractPorts(r) 192 return len(is) == 0, err 193 } 194 195 // ExtractPorts accepts a Page struct, specifically a PortPage struct, 196 // and extracts the elements into a slice of Port structs. In other words, 197 // a generic collection is mapped into a relevant slice. 198 func ExtractPorts(r pagination.Page) ([]Port, error) { 199 var s []Port 200 err := ExtractPortsInto(r, &s) 201 return s, err 202 } 203 204 func ExtractPortsInto(r pagination.Page, v any) error { 205 return r.(PortPage).Result.ExtractIntoSlicePtr(v, "ports") 206 }