block_storage.go raw
1 package govultr
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7
8 "github.com/google/go-querystring/query"
9 )
10
11 // BlockStorageService is the interface to interact with Block-Storage endpoint on the Vultr API
12 // Link : https://www.vultr.com/api/#tag/block
13 type BlockStorageService interface {
14 Create(ctx context.Context, blockReq *BlockStorageCreate) (*BlockStorage, *http.Response, error)
15 Get(ctx context.Context, blockID string) (*BlockStorage, *http.Response, error)
16 Update(ctx context.Context, blockID string, blockReq *BlockStorageUpdate) error
17 Delete(ctx context.Context, blockID string) error
18 List(ctx context.Context, options *ListOptions) ([]BlockStorage, *Meta, *http.Response, error)
19
20 Attach(ctx context.Context, blockID string, attach *BlockStorageAttach) error
21 Detach(ctx context.Context, blockID string, detach *BlockStorageDetach) error
22 }
23
24 // BlockStorageServiceHandler handles interaction with the block-storage methods for the Vultr API
25 type BlockStorageServiceHandler struct {
26 client *Client
27 }
28
29 // BlockStorage represents Vultr Block-Storage
30 type BlockStorage struct {
31 ID string `json:"id"`
32 Cost float32 `json:"cost"`
33 Status string `json:"status"`
34 SizeGB int `json:"size_gb"`
35 Region string `json:"region"`
36 DateCreated string `json:"date_created"`
37 AttachedToInstance string `json:"attached_to_instance"`
38 Label string `json:"label"`
39 MountID string `json:"mount_id"`
40 BlockType string `json:"block_type"`
41 }
42
43 // BlockStorageCreate struct is used for creating Block Storage.
44 type BlockStorageCreate struct {
45 Region string `json:"region"`
46 SizeGB int `json:"size_gb"`
47 Label string `json:"label,omitempty"`
48 BlockType string `json:"block_type,omitempty"`
49 }
50
51 // BlockStorageUpdate struct is used to update Block Storage.
52 type BlockStorageUpdate struct {
53 SizeGB int `json:"size_gb,omitempty"`
54 Label string `json:"label,omitempty"`
55 }
56
57 // BlockStorageAttach struct used to define if a attach should be restart the instance.
58 type BlockStorageAttach struct {
59 InstanceID string `json:"instance_id"`
60 Live *bool `json:"live,omitempty"`
61 }
62
63 // BlockStorageDetach struct used to define if a detach should be restart the instance.
64 type BlockStorageDetach struct {
65 Live *bool `json:"live,omitempty"`
66 }
67
68 type blockStoragesBase struct {
69 Blocks []BlockStorage `json:"blocks"`
70 Meta *Meta `json:"meta"`
71 }
72
73 type blockStorageBase struct {
74 Block *BlockStorage `json:"block"`
75 }
76
77 // Create builds out a block storage
78 func (b *BlockStorageServiceHandler) Create(ctx context.Context, blockReq *BlockStorageCreate) (*BlockStorage, *http.Response, error) {
79 uri := "/v2/blocks"
80
81 req, err := b.client.NewRequest(ctx, http.MethodPost, uri, blockReq)
82 if err != nil {
83 return nil, nil, err
84 }
85
86 block := new(blockStorageBase)
87 resp, err := b.client.DoWithContext(ctx, req, block)
88 if err != nil {
89 return nil, resp, err
90 }
91
92 return block.Block, resp, nil
93 }
94
95 // Get returns a single block storage instance based ony our blockID you provide from your Vultr Account
96 func (b *BlockStorageServiceHandler) Get(ctx context.Context, blockID string) (*BlockStorage, *http.Response, error) {
97 uri := fmt.Sprintf("/v2/blocks/%s", blockID)
98
99 req, err := b.client.NewRequest(ctx, http.MethodGet, uri, nil)
100 if err != nil {
101 return nil, nil, err
102 }
103
104 block := new(blockStorageBase)
105 resp, err := b.client.DoWithContext(ctx, req, block)
106 if err != nil {
107 return nil, resp, err
108 }
109
110 return block.Block, resp, nil
111 }
112
113 // Update a block storage subscription.
114 func (b *BlockStorageServiceHandler) Update(ctx context.Context, blockID string, blockReq *BlockStorageUpdate) error {
115 uri := fmt.Sprintf("/v2/blocks/%s", blockID)
116
117 req, err := b.client.NewRequest(ctx, http.MethodPatch, uri, blockReq)
118 if err != nil {
119 return err
120 }
121 _, err = b.client.DoWithContext(ctx, req, nil)
122 return err
123 }
124
125 // Delete a block storage subscription from your Vultr account
126 func (b *BlockStorageServiceHandler) Delete(ctx context.Context, blockID string) error {
127 uri := fmt.Sprintf("/v2/blocks/%s", blockID)
128
129 req, err := b.client.NewRequest(ctx, http.MethodDelete, uri, nil)
130 if err != nil {
131 return err
132 }
133 _, err = b.client.DoWithContext(ctx, req, nil)
134 return err
135 }
136
137 // List returns a list of all block storage instances on your Vultr Account
138 func (b *BlockStorageServiceHandler) List(ctx context.Context, options *ListOptions) ([]BlockStorage, *Meta, *http.Response, error) { //nolint:dupl,lll
139 uri := "/v2/blocks"
140
141 req, err := b.client.NewRequest(ctx, http.MethodGet, uri, nil)
142 if err != nil {
143 return nil, nil, nil, err
144 }
145
146 newValues, err := query.Values(options)
147 if err != nil {
148 return nil, nil, nil, err
149 }
150
151 req.URL.RawQuery = newValues.Encode()
152
153 blocks := new(blockStoragesBase)
154 resp, err := b.client.DoWithContext(ctx, req, blocks)
155 if err != nil {
156 return nil, nil, resp, err
157 }
158
159 return blocks.Blocks, blocks.Meta, resp, nil
160 }
161
162 // Attach will link a given block storage to a given Vultr instance
163 // If Live is set to true the block storage will be attached without reloading the instance
164 func (b *BlockStorageServiceHandler) Attach(ctx context.Context, blockID string, attach *BlockStorageAttach) error {
165 uri := fmt.Sprintf("/v2/blocks/%s/attach", blockID)
166
167 req, err := b.client.NewRequest(ctx, http.MethodPost, uri, attach)
168 if err != nil {
169 return err
170 }
171 _, err = b.client.DoWithContext(ctx, req, nil)
172 return err
173 }
174
175 // Detach will de-link a given block storage to the Vultr instance it is attached to
176 // If Live is set to true the block storage will be detached without reloading the instance
177 func (b *BlockStorageServiceHandler) Detach(ctx context.Context, blockID string, detach *BlockStorageDetach) error {
178 uri := fmt.Sprintf("/v2/blocks/%s/detach", blockID)
179
180 req, err := b.client.NewRequest(ctx, http.MethodPost, uri, detach)
181 if err != nil {
182 return err
183 }
184 _, err = b.client.DoWithContext(ctx, req, nil)
185 return err
186 }
187