From 6305d72035c2235c0fd745c0e9575310da9957cf Mon Sep 17 00:00:00 2001 From: Michael Riley Date: Thu, 3 Oct 2024 09:03:12 -0400 Subject: [PATCH] Add support for sub-accounts (#329) * Add support for sub-account route actions * Add sub-account service handler to client * Fix a type and clarify extra ID field --- govultr.go | 2 ++ subaccount.go | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 subaccount.go diff --git a/govultr.go b/govultr.go index 23fc1f6..d7f75a4 100644 --- a/govultr.go +++ b/govultr.go @@ -68,6 +68,7 @@ type Client struct { Snapshot SnapshotService SSHKey SSHKeyService StartupScript StartupScriptService + SubAccount SubAccountService User UserService VPC VPCService VPC2 VPC2Service @@ -141,6 +142,7 @@ func NewClient(httpClient *http.Client) *Client { client.Snapshot = &SnapshotServiceHandler{client} client.SSHKey = &SSHKeyServiceHandler{client} client.StartupScript = &StartupScriptServiceHandler{client} + client.SubAccount = &SubAccountServiceHandler{client} client.User = &UserServiceHandler{client} client.VPC = &VPCServiceHandler{client} client.VPC2 = &VPC2ServiceHandler{client} diff --git a/subaccount.go b/subaccount.go new file mode 100644 index 0000000..0901b84 --- /dev/null +++ b/subaccount.go @@ -0,0 +1,75 @@ +package govultr + +import ( + "context" + "net/http" +) + +// SubAccountService is the interface to interact with sub-accounts endpoint on the Vultr API +// Link : https://www.vultr.com/api/#tag/subaccount +type SubAccountService interface { + List(ctx context.Context, options *ListOptions) ([]SubAccount, *Meta, *http.Response, error) + Create(ctx context.Context, saReq *SubAccountReq) (*SubAccount, *http.Response, error) +} + +// SubAccountServiceHandler handles interaction with the account methods for the Vultr API +type SubAccountServiceHandler struct { + client *Client +} + +type subAccountsBase struct { + SubAccounts []SubAccount `json:"subaccounts"` + Meta *Meta `json:"meta"` +} + +// SubAccount represents a Vultr sub-account +type SubAccount struct { + ID string `json:"id"` + Email string `json:"email"` + Name string `json:"subaccount_name"` + OtherID string `json:"subaccount_id"` + Activated bool `json:"activated"` + Balance int `json:"balance"` + PendingCharges int `json:"pending_charges"` +} + +// SubAccountReq is the sub-account struct for create calls +type SubAccountReq struct { + Email string `json:"email"` + Name string `json:"subaccount_name,omitempty"` + OtherID string `json:"subaccount_id,omitempty"` +} + +// List all sub-accounts +func (s *SubAccountServiceHandler) List(ctx context.Context, options *ListOptions) ([]SubAccount, *Meta, *http.Response, error) { + uri := "/v2/subaccounts" + req, err := s.client.NewRequest(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, nil, nil, err + } + + sas := new(subAccountsBase) + resp, err := s.client.DoWithContext(ctx, req, sas) + if err != nil { + return nil, nil, resp, err + } + + return sas.SubAccounts, sas.Meta, resp, nil +} + +// Create a sub-account +func (s *SubAccountServiceHandler) Create(ctx context.Context, saReq *SubAccountReq) (*SubAccount, *http.Response, error) { + uri := "/v2/subaccounts" + req, err := s.client.NewRequest(ctx, http.MethodPost, uri, saReq) + if err != nil { + return nil, nil, err + } + + sa := new(SubAccount) + resp, err := s.client.DoWithContext(ctx, req, sa) + if err != nil { + return nil, resp, err + } + + return sa, resp, nil +}