195 lines
6.4 KiB
Go
195 lines
6.4 KiB
Go
package packngo
|
||
|
||
import (
|
||
"fmt"
|
||
)
|
||
|
||
const ipBasePath = "/ips"
|
||
|
||
// DeviceIPService handles assignment of addresses from reserved blocks to instances in a project.
|
||
type DeviceIPService interface {
|
||
Assign(deviceID string, assignRequest *AddressStruct) (*IPAddressAssignment, *Response, error)
|
||
Unassign(assignmentID string) (*Response, error)
|
||
Get(assignmentID string) (*IPAddressAssignment, *Response, error)
|
||
}
|
||
|
||
// ProjectIPService handles reservation of IP address blocks for a project.
|
||
type ProjectIPService interface {
|
||
Get(reservationID string) (*IPAddressReservation, *Response, error)
|
||
List(projectID string) ([]IPAddressReservation, *Response, error)
|
||
Request(projectID string, ipReservationReq *IPReservationRequest) (*IPAddressReservation, *Response, error)
|
||
Remove(ipReservationID string) (*Response, error)
|
||
AvailableAddresses(ipReservationID string, r *AvailableRequest) ([]string, *Response, error)
|
||
}
|
||
|
||
type ipAddressCommon struct {
|
||
ID string `json:"id"`
|
||
Address string `json:"address"`
|
||
Gateway string `json:"gateway"`
|
||
Network string `json:"network"`
|
||
AddressFamily int `json:"address_family"`
|
||
Netmask string `json:"netmask"`
|
||
Public bool `json:"public"`
|
||
CIDR int `json:"cidr"`
|
||
Created string `json:"created_at,omitempty"`
|
||
Updated string `json:"updated_at,omitempty"`
|
||
Href string `json:"href"`
|
||
Management bool `json:"management"`
|
||
Manageable bool `json:"manageable"`
|
||
Project Href `json:"project"`
|
||
}
|
||
|
||
// IPAddressReservation is created when user sends IP reservation request for a project (considering it's within quota).
|
||
type IPAddressReservation struct {
|
||
ipAddressCommon
|
||
Assignments []Href `json:"assignments"`
|
||
Facility Facility `json:"facility,omitempty"`
|
||
Available string `json:"available"`
|
||
Addon bool `json:"addon"`
|
||
Bill bool `json:"bill"`
|
||
}
|
||
|
||
// AvailableResponse is a type for listing of available addresses from a reserved block.
|
||
type AvailableResponse struct {
|
||
Available []string `json:"available"`
|
||
}
|
||
|
||
// AvailableRequest is a type for listing available addresses from a reserved block.
|
||
type AvailableRequest struct {
|
||
CIDR int `json:"cidr"`
|
||
}
|
||
|
||
// IPAddressAssignment is created when an IP address from reservation block is assigned to a device.
|
||
type IPAddressAssignment struct {
|
||
ipAddressCommon
|
||
AssignedTo Href `json:"assigned_to"`
|
||
}
|
||
|
||
// IPReservationRequest represents the body of a reservation request.
|
||
type IPReservationRequest struct {
|
||
Type string `json:"type"`
|
||
Quantity int `json:"quantity"`
|
||
Comments string `json:"comments"`
|
||
Facility string `json:"facility"`
|
||
}
|
||
|
||
// AddressStruct is a helper type for request/response with dict like {"address": ... }
|
||
type AddressStruct struct {
|
||
Address string `json:"address"`
|
||
}
|
||
|
||
func deleteFromIP(client *Client, resourceID string) (*Response, error) {
|
||
path := fmt.Sprintf("%s/%s", ipBasePath, resourceID)
|
||
|
||
return client.DoRequest("DELETE", path, nil, nil)
|
||
}
|
||
|
||
func (i IPAddressReservation) String() string {
|
||
return Stringify(i)
|
||
}
|
||
|
||
func (i IPAddressAssignment) String() string {
|
||
return Stringify(i)
|
||
}
|
||
|
||
// DeviceIPServiceOp is interface for IP-address assignment methods.
|
||
type DeviceIPServiceOp struct {
|
||
client *Client
|
||
}
|
||
|
||
// Unassign unassigns an IP address from the device to which it is currently assigned.
|
||
// This will remove the relationship between an IP and the device and will make the IP
|
||
// address available to be assigned to another device.
|
||
func (i *DeviceIPServiceOp) Unassign(assignmentID string) (*Response, error) {
|
||
return deleteFromIP(i.client, assignmentID)
|
||
}
|
||
|
||
// Assign assigns an IP address to a device.
|
||
// The IP address must be in one of the IP ranges assigned to the device’s project.
|
||
func (i *DeviceIPServiceOp) Assign(deviceID string, assignRequest *AddressStruct) (*IPAddressAssignment, *Response, error) {
|
||
path := fmt.Sprintf("%s/%s%s", deviceBasePath, deviceID, ipBasePath)
|
||
ipa := new(IPAddressAssignment)
|
||
|
||
resp, err := i.client.DoRequest("POST", path, assignRequest, ipa)
|
||
if err != nil {
|
||
return nil, resp, err
|
||
}
|
||
|
||
return ipa, resp, err
|
||
}
|
||
|
||
// Get returns assignment by ID.
|
||
func (i *DeviceIPServiceOp) Get(assignmentID string) (*IPAddressAssignment, *Response, error) {
|
||
path := fmt.Sprintf("%s/%s", ipBasePath, assignmentID)
|
||
ipa := new(IPAddressAssignment)
|
||
|
||
resp, err := i.client.DoRequest("GET", path, nil, ipa)
|
||
if err != nil {
|
||
return nil, resp, err
|
||
}
|
||
|
||
return ipa, resp, err
|
||
}
|
||
|
||
// ProjectIPServiceOp is interface for IP assignment methods.
|
||
type ProjectIPServiceOp struct {
|
||
client *Client
|
||
}
|
||
|
||
// Get returns reservation by ID.
|
||
func (i *ProjectIPServiceOp) Get(reservationID string) (*IPAddressReservation, *Response, error) {
|
||
path := fmt.Sprintf("%s/%s", ipBasePath, reservationID)
|
||
ipr := new(IPAddressReservation)
|
||
|
||
resp, err := i.client.DoRequest("GET", path, nil, ipr)
|
||
if err != nil {
|
||
return nil, resp, err
|
||
}
|
||
|
||
return ipr, resp, err
|
||
}
|
||
|
||
// List provides a list of IP resevations for a single project.
|
||
func (i *ProjectIPServiceOp) List(projectID string) ([]IPAddressReservation, *Response, error) {
|
||
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
|
||
reservations := new(struct {
|
||
Reservations []IPAddressReservation `json:"ip_addresses"`
|
||
})
|
||
|
||
resp, err := i.client.DoRequest("GET", path, nil, reservations)
|
||
if err != nil {
|
||
return nil, resp, err
|
||
}
|
||
return reservations.Reservations, resp, nil
|
||
}
|
||
|
||
// Request requests more IP space for a project in order to have additional IP addresses to assign to devices.
|
||
func (i *ProjectIPServiceOp) Request(projectID string, ipReservationReq *IPReservationRequest) (*IPAddressReservation, *Response, error) {
|
||
path := fmt.Sprintf("%s/%s%s", projectBasePath, projectID, ipBasePath)
|
||
ipr := new(IPAddressReservation)
|
||
|
||
resp, err := i.client.DoRequest("POST", path, ipReservationReq, ipr)
|
||
if err != nil {
|
||
return nil, resp, err
|
||
}
|
||
return ipr, resp, err
|
||
}
|
||
|
||
// Remove removes an IP reservation from the project.
|
||
func (i *ProjectIPServiceOp) Remove(ipReservationID string) (*Response, error) {
|
||
return deleteFromIP(i.client, ipReservationID)
|
||
}
|
||
|
||
// AvailableAddresses lists addresses available from a reserved block
|
||
func (i *ProjectIPServiceOp) AvailableAddresses(ipReservationID string, r *AvailableRequest) ([]string, *Response, error) {
|
||
path := fmt.Sprintf("%s/%s/available?cidr=%d", ipBasePath, ipReservationID, r.CIDR)
|
||
ar := new(AvailableResponse)
|
||
|
||
resp, err := i.client.DoRequest("GET", path, r, ar)
|
||
if err != nil {
|
||
return nil, resp, err
|
||
}
|
||
return ar.Available, resp, nil
|
||
|
||
}
|