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  }