krystal/go-katapult

View on GitHub
core/ip_address.go

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
package core

import (
    "context"
    "net/url"
    "strings"

    "github.com/krystal/go-katapult"
)

type IPAddress struct {
    ID              string   `json:"id,omitempty"`
    Address         string   `json:"address,omitempty"`
    ReverseDNS      string   `json:"reverse_dns,omitempty"`
    VIP             bool     `json:"vip,omitempty"`
    Label           string   `json:"label,omitempty"`
    AddressWithMask string   `json:"address_with_mask,omitempty"`
    Network         *Network `json:"network,omitempty"`
    AllocationID    string   `json:"allocation_id,omitempty"`
    AllocationType  string   `json:"allocation_type,omitempty"`
}

func (s *IPAddress) Ref() IPAddressRef {
    return IPAddressRef{ID: s.ID}
}

func (s *IPAddress) Version() IPVersion {
    if strings.Count(s.Address, ":") < 2 {
        return IPv4
    }

    return IPv6
}

type IPAddressRef struct {
    ID      string `json:"id,omitempty"`
    Address string `json:"address,omitempty"`
}

func (ref IPAddressRef) queryValues() *url.Values {
    v := &url.Values{}

    switch {
    case ref.ID != "":
        v.Set("ip_address[id]", ref.ID)
    case ref.Address != "":
        v.Set("ip_address[address]", ref.Address)
    }

    return v
}

type IPAddressCreateArguments struct {
    Network NetworkRef
    Version IPVersion
    VIP     *bool
    Label   string
}

type IPAddressUpdateArguments struct {
    VIP        *bool
    Label      string
    ReverseDNS string
}

type ipAddressCreateRequest struct {
    Organization OrganizationRef `json:"organization,omitempty"`
    Network      NetworkRef      `json:"network,omitempty"`
    Version      IPVersion       `json:"version,omitempty"`
    VIP          *bool           `json:"vip,omitempty"`
    Label        string          `json:"label,omitempty"`
}

type ipAddressUpdateRequest struct {
    IPAddress  IPAddressRef `json:"ip_address"`
    VIP        *bool        `json:"vip,omitempty"`
    Label      string       `json:"label,omitempty"`
    ReverseDNS string       `json:"reverse_dns,omitempty"`
}

type ipAddressesResponseBody struct {
    Pagination  *katapult.Pagination `json:"pagination,omitempty"`
    IPAddress   *IPAddress           `json:"ip_address,omitempty"`
    IPAddresses []*IPAddress         `json:"ip_addresses,omitempty"`
}

type IPAddressesClient struct {
    client   RequestMaker
    basePath *url.URL
}

func NewIPAddressesClient(rm RequestMaker) *IPAddressesClient {
    return &IPAddressesClient{
        client:   rm,
        basePath: &url.URL{Path: "/core/v1/"},
    }
}

func (s *IPAddressesClient) List(
    ctx context.Context,
    org OrganizationRef,
    opts *ListOptions,
    reqOpts ...katapult.RequestOption,
) ([]*IPAddress, *katapult.Response, error) {
    qs := queryValues(org, opts)
    u := &url.URL{
        Path:     "organizations/_/ip_addresses",
        RawQuery: qs.Encode(),
    }

    body, resp, err := s.doRequest(ctx, "GET", u, nil, reqOpts...)
    resp.Pagination = body.Pagination

    return body.IPAddresses, resp, err
}

func (s *IPAddressesClient) Get(
    ctx context.Context,
    ref IPAddressRef,
    reqOpts ...katapult.RequestOption,
) (*IPAddress, *katapult.Response, error) {
    u := &url.URL{
        Path:     "ip_addresses/_",
        RawQuery: ref.queryValues().Encode(),
    }

    body, resp, err := s.doRequest(ctx, "GET", u, nil, reqOpts...)

    return body.IPAddress, resp, err
}

func (s *IPAddressesClient) GetByID(
    ctx context.Context,
    id string,
    reqOpts ...katapult.RequestOption,
) (*IPAddress, *katapult.Response, error) {
    return s.Get(ctx, IPAddressRef{ID: id}, reqOpts...)
}

func (s *IPAddressesClient) GetByAddress(
    ctx context.Context,
    address string,
    reqOpts ...katapult.RequestOption,
) (*IPAddress, *katapult.Response, error) {
    return s.Get(ctx, IPAddressRef{Address: address}, reqOpts...)
}

func (s *IPAddressesClient) Create(
    ctx context.Context,
    org OrganizationRef,
    args *IPAddressCreateArguments,
    reqOpts ...katapult.RequestOption,
) (*IPAddress, *katapult.Response, error) {
    u := &url.URL{Path: "organizations/_/ip_addresses"}
    reqBody := &ipAddressCreateRequest{
        Organization: org,
    }

    if args != nil {
        reqBody.Network = args.Network
        reqBody.Version = args.Version
        reqBody.VIP = args.VIP
        reqBody.Label = args.Label
    }

    body, resp, err := s.doRequest(ctx, "POST", u, reqBody, reqOpts...)

    return body.IPAddress, resp, err
}

func (s *IPAddressesClient) Update(
    ctx context.Context,
    ip IPAddressRef,
    args *IPAddressUpdateArguments,
    reqOpts ...katapult.RequestOption,
) (*IPAddress, *katapult.Response, error) {
    u := &url.URL{Path: "ip_addresses/_"}
    reqBody := &ipAddressUpdateRequest{
        IPAddress: ip,
    }

    if args != nil {
        reqBody.VIP = args.VIP
        reqBody.Label = args.Label
        reqBody.ReverseDNS = args.ReverseDNS
    }

    body, resp, err := s.doRequest(ctx, "PATCH", u, reqBody, reqOpts...)

    return body.IPAddress, resp, err
}

func (s *IPAddressesClient) Delete(
    ctx context.Context,
    ip IPAddressRef,
    reqOpts ...katapult.RequestOption,
) (*katapult.Response, error) {
    qs := queryValues(ip)
    u := &url.URL{Path: "ip_addresses/_", RawQuery: qs.Encode()}

    _, resp, err := s.doRequest(ctx, "DELETE", u, nil, reqOpts...)

    return resp, err
}

func (s *IPAddressesClient) Unallocate(
    ctx context.Context,
    ip IPAddressRef,
    reqOpts ...katapult.RequestOption,
) (*katapult.Response, error) {
    qs := queryValues(ip)
    u := &url.URL{Path: "ip_addresses/_/unallocate", RawQuery: qs.Encode()}

    _, resp, err := s.doRequest(ctx, "POST", u, nil, reqOpts...)

    return resp, err
}

func (s *IPAddressesClient) doRequest(
    ctx context.Context,
    method string,
    u *url.URL,
    body interface{},
    reqOpts ...katapult.RequestOption,
) (*ipAddressesResponseBody, *katapult.Response, error) {
    u = s.basePath.ResolveReference(u)
    respBody := &ipAddressesResponseBody{}

    req := katapult.NewRequest(method, u, body, reqOpts...)
    resp, err := s.client.Do(ctx, req, respBody)
    if resp == nil {
        resp = katapult.NewResponse(nil)
    }

    return respBody, resp, handleResponseError(err)
}