1package linodego 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7) 8 9// InstanceIPAddressResponse contains the IPv4 and IPv6 details for an Instance 10type InstanceIPAddressResponse struct { 11 IPv4 *InstanceIPv4Response `json:"ipv4"` 12 IPv6 *InstanceIPv6Response `json:"ipv6"` 13} 14 15// InstanceIPv4Response contains the details of all IPv4 addresses associated with an Instance 16type InstanceIPv4Response struct { 17 Public []*InstanceIP `json:"public"` 18 Private []*InstanceIP `json:"private"` 19 Shared []*InstanceIP `json:"shared"` 20 Reserved []*InstanceIP `json:"reserved"` 21} 22 23// InstanceIP represents an Instance IP with additional DNS and networking details 24type InstanceIP struct { 25 Address string `json:"address"` 26 Gateway string `json:"gateway"` 27 SubnetMask string `json:"subnet_mask"` 28 Prefix int `json:"prefix"` 29 Type InstanceIPType `json:"type"` 30 Public bool `json:"public"` 31 RDNS string `json:"rdns"` 32 LinodeID int `json:"linode_id"` 33 Region string `json:"region"` 34} 35 36// InstanceIPv6Response contains the IPv6 addresses and ranges for an Instance 37type InstanceIPv6Response struct { 38 LinkLocal *InstanceIP `json:"link_local"` 39 SLAAC *InstanceIP `json:"slaac"` 40 Global []*IPv6Range `json:"global"` 41} 42 43// IPv6Range represents a range of IPv6 addresses routed to a single Linode in a given Region 44type IPv6Range struct { 45 Range string `json:"range"` 46 Region string `json:"region"` 47 Prefix int `json:"prefix"` 48} 49 50// InstanceIPType constants start with IPType and include Linode Instance IP Types 51type InstanceIPType string 52 53// InstanceIPType constants represent the IP types an Instance IP may be 54const ( 55 IPTypeIPv4 InstanceIPType = "ipv4" 56 IPTypeIPv6 InstanceIPType = "ipv6" 57 IPTypeIPv6Pool InstanceIPType = "ipv6/pool" 58 IPTypeIPv6Range InstanceIPType = "ipv6/range" 59) 60 61// GetInstanceIPAddresses gets the IPAddresses for a Linode instance 62func (c *Client) GetInstanceIPAddresses(ctx context.Context, linodeID int) (*InstanceIPAddressResponse, error) { 63 e, err := c.InstanceIPs.endpointWithParams(linodeID) 64 if err != nil { 65 return nil, err 66 } 67 68 r, err := coupleAPIErrors(c.R(ctx).SetResult(&InstanceIPAddressResponse{}).Get(e)) 69 if err != nil { 70 return nil, err 71 } 72 return r.Result().(*InstanceIPAddressResponse), nil 73} 74 75// GetInstanceIPAddress gets the IPAddress for a Linode instance matching a supplied IP address 76func (c *Client) GetInstanceIPAddress(ctx context.Context, linodeID int, ipaddress string) (*InstanceIP, error) { 77 e, err := c.InstanceIPs.endpointWithParams(linodeID) 78 if err != nil { 79 return nil, err 80 } 81 e = fmt.Sprintf("%s/%s", e, ipaddress) 82 r, err := coupleAPIErrors(c.R(ctx).SetResult(&InstanceIP{}).Get(e)) 83 if err != nil { 84 return nil, err 85 } 86 return r.Result().(*InstanceIP), nil 87} 88 89// AddInstanceIPAddress adds a public or private IP to a Linode instance 90func (c *Client) AddInstanceIPAddress(ctx context.Context, linodeID int, public bool) (*InstanceIP, error) { 91 var body string 92 e, err := c.InstanceIPs.endpointWithParams(linodeID) 93 if err != nil { 94 return nil, err 95 } 96 97 req := c.R(ctx).SetResult(&InstanceIP{}) 98 99 instanceipRequest := struct { 100 Type string `json:"type"` 101 Public bool `json:"public"` 102 }{"ipv4", public} 103 104 if bodyData, err := json.Marshal(instanceipRequest); err == nil { 105 body = string(bodyData) 106 } else { 107 return nil, NewError(err) 108 } 109 110 r, err := coupleAPIErrors(req. 111 SetHeader("Content-Type", "application/json"). 112 SetBody(body). 113 Post(e)) 114 if err != nil { 115 return nil, err 116 } 117 118 return r.Result().(*InstanceIP), nil 119} 120 121// UpdateInstanceIPAddress updates the IPAddress with the specified instance id and IP address 122func (c *Client) UpdateInstanceIPAddress(ctx context.Context, linodeID int, ipAddress string, updateOpts IPAddressUpdateOptions) (*InstanceIP, error) { 123 var body string 124 e, err := c.InstanceIPs.endpointWithParams(linodeID) 125 if err != nil { 126 return nil, err 127 } 128 e = fmt.Sprintf("%s/%s", e, ipAddress) 129 130 req := c.R(ctx).SetResult(&InstanceIP{}) 131 132 if bodyData, err := json.Marshal(updateOpts); err == nil { 133 body = string(bodyData) 134 } else { 135 return nil, NewError(err) 136 } 137 138 r, err := coupleAPIErrors(req. 139 SetBody(body). 140 Put(e)) 141 if err != nil { 142 return nil, err 143 } 144 return r.Result().(*InstanceIP), nil 145} 146 147func (c *Client) DeleteInstanceIPAddress(ctx context.Context, linodeID int, ipAddress string) error { 148 e, err := c.InstanceIPs.endpointWithParams(linodeID) 149 if err != nil { 150 return err 151 } 152 153 e = fmt.Sprintf("%s/%s", e, ipAddress) 154 _, err = coupleAPIErrors(c.R(ctx).Delete(e)) 155 return err 156} 157