github.com/gophercloud/gophercloud@v1.11.0/openstack/networking/v2/ports/results.go (about)

     1  package ports
     2  
     3  import (
     4  	"encoding/json"
     5  	"time"
     6  
     7  	"github.com/gophercloud/gophercloud"
     8  	"github.com/gophercloud/gophercloud/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 interface{}) 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  	// Extra parameters to include in the request.
   118  	ValueSpecs map[string]string `json:"value_specs"`
   119  
   120  	// RevisionNumber optionally set via extensions/standard-attr-revisions
   121  	RevisionNumber int `json:"revision_number"`
   122  
   123  	// Timestamp when the port was created
   124  	CreatedAt time.Time `json:"created_at"`
   125  
   126  	// Timestamp when the port was last updated
   127  	UpdatedAt time.Time `json:"updated_at"`
   128  }
   129  
   130  func (r *Port) UnmarshalJSON(b []byte) error {
   131  	type tmp Port
   132  
   133  	// Support for older neutron time format
   134  	var s1 struct {
   135  		tmp
   136  		CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"`
   137  		UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"`
   138  	}
   139  
   140  	err := json.Unmarshal(b, &s1)
   141  	if err == nil {
   142  		*r = Port(s1.tmp)
   143  		r.CreatedAt = time.Time(s1.CreatedAt)
   144  		r.UpdatedAt = time.Time(s1.UpdatedAt)
   145  
   146  		return nil
   147  	}
   148  
   149  	// Support for newer neutron time format
   150  	var s2 struct {
   151  		tmp
   152  		CreatedAt time.Time `json:"created_at"`
   153  		UpdatedAt time.Time `json:"updated_at"`
   154  	}
   155  
   156  	err = json.Unmarshal(b, &s2)
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	*r = Port(s2.tmp)
   162  	r.CreatedAt = time.Time(s2.CreatedAt)
   163  	r.UpdatedAt = time.Time(s2.UpdatedAt)
   164  
   165  	return nil
   166  }
   167  
   168  // PortPage is the page returned by a pager when traversing over a collection
   169  // of network ports.
   170  type PortPage struct {
   171  	pagination.LinkedPageBase
   172  }
   173  
   174  // NextPageURL is invoked when a paginated collection of ports has reached
   175  // the end of a page and the pager seeks to traverse over a new one. In order
   176  // to do this, it needs to construct the next page's URL.
   177  func (r PortPage) NextPageURL() (string, error) {
   178  	var s struct {
   179  		Links []gophercloud.Link `json:"ports_links"`
   180  	}
   181  	err := r.ExtractInto(&s)
   182  	if err != nil {
   183  		return "", err
   184  	}
   185  	return gophercloud.ExtractNextURL(s.Links)
   186  }
   187  
   188  // IsEmpty checks whether a PortPage struct is empty.
   189  func (r PortPage) IsEmpty() (bool, error) {
   190  	if r.StatusCode == 204 {
   191  		return true, nil
   192  	}
   193  
   194  	is, err := ExtractPorts(r)
   195  	return len(is) == 0, err
   196  }
   197  
   198  // ExtractPorts accepts a Page struct, specifically a PortPage struct,
   199  // and extracts the elements into a slice of Port structs. In other words,
   200  // a generic collection is mapped into a relevant slice.
   201  func ExtractPorts(r pagination.Page) ([]Port, error) {
   202  	var s []Port
   203  	err := ExtractPortsInto(r, &s)
   204  	return s, err
   205  }
   206  
   207  func ExtractPortsInto(r pagination.Page, v interface{}) error {
   208  	return r.(PortPage).Result.ExtractIntoSlicePtr(v, "ports")
   209  }