Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
64 / 64
100.00% covered (success)
100.00%
21 / 21
CRAP
100.00% covered (success)
100.00%
1 / 1
BareMetalService
100.00% covered (success)
100.00%
64 / 64
100.00% covered (success)
100.00%
21 / 21
35
100.00% covered (success)
100.00%
1 / 1
 getBareMetals
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBareMetal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deleteBareMetal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createBareMetal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updateBareMetal
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 getIPv4Addresses
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIPv6Addresses
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAddressInfo
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 startBareMetal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 startBareMetals
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 rebootBareMetal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 rebootBareMetals
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 reinstallBareMetal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 haltBareMetal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 haltBareMetals
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 singleServerAction
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 multipleServersAction
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getBandwidth
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 getUserData
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getAvailableUpgrades
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
 getVNCUrl
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Vultr\VultrPhp\Services\BareMetal;
6
7use Vultr\VultrPhp\Services\Applications\Application;
8use Vultr\VultrPhp\Services\OperatingSystems\OperatingSystem;
9use Vultr\VultrPhp\Services\VultrService;
10use Vultr\VultrPhp\Util\ListOptions;
11use Vultr\VultrPhp\Util\ModelInterface;
12use Vultr\VultrPhp\Util\VultrUtil;
13use Vultr\VultrPhp\VultrClientException;
14
15/**
16 * Baremetal service handler, for bare-metals endpoints.
17 *
18 * @see https://www.vultr.com/api/#tag/baremetal
19 */
20class BareMetalService extends VultrService
21{
22    /**
23     * List all Bare Metal instances in your account.
24     * @see https://www.vultr.com/api/#operation/list-baremetals
25     * @param $options - ListOptions|null - Interact via reference.
26     * @throws BareMetalException
27     * @return BareMetal[]
28     */
29    public function getBareMetals(?ListOptions &$options = null) : array
30    {
31        return $this->getListObjects('bare-metals', new BareMetal(), $options);
32    }
33
34    /**
35     * Get information for a Bare Metal instance.
36     * @see https://www.vultr.com/api/#operation/get-baremetal
37     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
38     * @throws BareMetalException
39     * @return BareMetal
40     */
41    public function getBareMetal(string $id) : BareMetal
42    {
43        return $this->getObject('bare-metals/'.$id, new BareMetal());
44    }
45
46    /**
47     * Delete a Bare Metal instance.
48     * @see https://www.vultr.com/api/#operation/delete-baremetal
49     * @throws BareMetalException
50     * @return void
51     */
52    public function deleteBareMetal(string $id) : void
53    {
54        $this->deleteObject('bare-metals/'.$id, new BareMetal());
55    }
56
57    /**
58     * Create a new Bare Metal instance based on BareMetalCreate
59     * @see BareMetalCreate
60     * @see https://www.vultr.com/api/#operation/create-baremetal
61     * @param $payload - BareMetalCreate
62     * @throws BareMetalException
63     * @return BareMetal
64     */
65    public function createBareMetal(BareMetalCreate $payload) : BareMetal
66    {
67        return $this->createObject('bare-metals', new BareMetal(), $payload->getPayloadParams());
68    }
69
70    /**
71     * Update a Bare Metal instance. All attributes are optional in BareMetalUpdate. If not set the attributes will not be sent to the API.
72     * @see https://www.vultr.com/api/#operation/update-baremetal
73     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
74     * @param $payload - BareMetalUpdate
75     * @throws BareMetalException
76     * @return BareMetal
77     */
78    public function updateBareMetal(string $id, BareMetalUpdate $payload) : BareMetal
79    {
80        $client = $this->getClientHandler();
81
82        try
83        {
84            $response = $client->patch('bare-metals/'.$id, $payload->getPayloadParams());
85        }
86        catch (VultrClientException $e)
87        {
88            throw new BareMetalException('Failed to update baremetal server: '.$e->getMessage(), $e->getHTTPCode(), $e);
89        }
90
91        $model = new BareMetal();
92
93        return VultrUtil::convertJSONToObject((string)$response->getBody(), $model, $model->getResponseName());
94    }
95
96    /**
97     * Get all IPv4 information for the Bare Metal instance.
98     * @see https://www.vultr.com/api/#operation/get-ipv4-baremetal
99     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
100     * @throws BareMetalException
101     * @throws VultrException
102     * @return BareMetalIPv4Info[]
103     */
104    public function getIPv4Addresses(string $id) : array
105    {
106        return $this->getAddressInfo(new BareMetalIPv4Info(), 'bare-metals/'.$id.'/ipv4', $id);
107    }
108
109    /**
110     * Get all IPv6 information for the Bare Metal instance.
111     * @see https://www.vultr.com/api/#operation/get-ipv6-baremetal
112     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
113     * @throws BareMetalException
114     * @throws VultrException
115     * @return BareMetalIPv6Info[]
116     */
117    public function getIPv6Addresses(string $id) : array
118    {
119        return $this->getAddressInfo(new BareMetalIPv6Info(), 'bare-metals/'.$id.'/ipv6', $id);
120    }
121
122    private function getAddressInfo(ModelInterface $model, string $uri, string $id) : array
123    {
124        $client = $this->getClientHandler();
125
126        try
127        {
128            $response = $client->get($uri);
129        }
130        catch (VultrClientException $e)
131        {
132            throw new BareMetalException('Failed to get baremetal address information: '.$e->getMessage(), $e->getHTTPCode(), $e);
133        }
134
135        $objects = [];
136        $decode = VultrUtil::decodeJSON((string)$response->getBody());
137        $response_name = $model->getResponseListName();
138        foreach ($decode->$response_name as $info)
139        {
140            $object = VultrUtil::mapObject($info, $model);
141            $objects[] = $object;
142        }
143        return $objects;
144    }
145
146    /**
147     * @see https://www.vultr.com/api/#operation/start-baremetal
148     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
149     * @throws BareMetalException
150     * @return void
151     */
152    public function startBareMetal(string $id) : void
153    {
154        $this->singleServerAction('start', $id);
155    }
156
157    /**
158     * Start the Bare Metal instance.
159     * @see https://www.vultr.com/api/#operation/start-bare-metals
160     * @param $ids - array - Example: [cb676a46-66fd-4dfb-b839-443f2e6c0b60, cb676a46-66fd-4dfb-b839-443f2e6c0b65]
161     * @throws BareMetalException
162     * @return void
163     */
164    public function startBareMetals(array $ids) : void
165    {
166        $this->multipleServersAction('start', $ids);
167    }
168
169    /**
170     * Reboot the Bare Metal instance.
171     * @see https://www.vultr.com/api/#operation/reboot-baremetal
172     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
173     * @throws BareMetalException
174     * @return void
175     */
176    public function rebootBareMetal(string $id) : void
177    {
178        $this->singleServerAction('reboot', $id);
179    }
180
181    /**
182     * Reboot multiple Bare Metal instances with 1 api call.
183     * @see https://www.vultr.com/api/#operation/reboot-bare-metals
184     * @param $ids - array - Example: [cb676a46-66fd-4dfb-b839-443f2e6c0b60, cb676a46-66fd-4dfb-b839-443f2e6c0b65]
185     * @throws BareMetalException
186     * @return void
187     */
188    public function rebootBareMetals(array $ids) : void
189    {
190        $this->multipleServersAction('reboot', $ids);
191    }
192
193    /**
194     * Reinstall the Bare Metal instance. This action usually takes a few seconds to complete.
195     * @see https://www.vultr.com/api/#operation/reinstall-baremetal
196     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
197     * @throws BareMetalException
198     * @return BareMetal
199     */
200    public function reinstallBareMetal(string $id) : BareMetal
201    {
202        return $this->createObject('bare-metals/'.$id.'/reinstall', new BareMetal(), []);
203    }
204
205    /**
206     * Halt the Bare Metal instance. The machine will remain off till started again.
207     * @see https://www.vultr.com/api/#operation/halt-baremetal
208     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
209     * @throws BareMetalException
210     * @return void
211     */
212    public function haltBareMetal(string $id) : void
213    {
214        $this->singleServerAction('halt', $id);
215    }
216
217    /**
218     * Halt multiple Bare Metal instances. The machines will remain off till started again.
219     * @see https://www.vultr.com/api/#operation/halt-baremetals
220     * @param $ids - array - Example: [cb676a46-66fd-4dfb-b839-443f2e6c0b60, cb676a46-66fd-4dfb-b839-443f2e6c0b65]
221     * @throws BareMetalException
222     * @return void
223     */
224    public function haltBareMetals(array $ids) : void
225    {
226        $this->multipleServersAction('halt', $ids);
227    }
228
229    private function singleServerAction(string $action, string $id) : void
230    {
231        try
232        {
233            $this->getClientHandler()->post('bare-metals/'.$id.'/'.$action);
234        }
235        catch (VultrClientException $e)
236        {
237            throw new BareMetalException('Failed to '.$action.' baremetal server: '.$e->getMessage(), $e->getHTTPCode(), $e);
238        }
239    }
240
241    private function multipleServersAction(string $action, array $ids) : void
242    {
243        try
244        {
245            $this->getClientHandler()->post('bare-metals/'.$action, ['baremetal_ids' => $ids]);
246        }
247        catch (VultrClientException $e)
248        {
249            throw new BareMetalException('Failed to '.$action.' baremetal servers: '.$e->getMessage(), $e->getHTTPCode(), $e);
250        }
251    }
252
253    /**
254     * Get bandwidth information for the Bare Metal instance
255     *
256     * The structure of the array will follow this format.
257     * ['2022-11-05' => ['incoming_bytes' => 234523452352, 'outgoing_bytes' => 132432423]]
258     *
259     * @see https://www.vultr.com/api/#operation/get-bandwidth-baremetal
260     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
261     * @throws BareMetalException
262     * @throws VultrException
263     * @return array
264     */
265    public function getBandwidth(string $id) : array
266    {
267        try
268        {
269            $response = $this->getClientHandler()->get('bare-metals/'.$id.'/bandwidth');
270        }
271        catch (VultrClientException $e)
272        {
273            throw new BareMetalException('Failed to get bandwidth for baremetal server: '.$e->getMessage(), $e->getHTTPCode(), $e);
274        }
275
276        $decode = VultrUtil::decodeJSON((string)$response->getBody(), true);
277
278        $output = [];
279        // Just a standardization, in the event the api ever changes its attributes. We can just change it here maintain backwards compat.
280        foreach ($decode['bandwidth'] as $date => $attr)
281        {
282            $output[$date] = [];
283            foreach (['incoming_bytes', 'outgoing_bytes'] as $attribute)
284            {
285                $output[$date][$attribute] = $attr[$attribute];
286            }
287        }
288
289        return $output;
290    }
291
292    /**
293     * Get the user-supplied, which is decoded for you from base64 that the api returns.
294     *
295     * @see https://www.vultr.com/api/#operation/get-bare-metal-userdata
296     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
297     * @throws BareMetalException
298     * @throws VultrException
299     * @return string
300     */
301    public function getUserData(string $id) : string
302    {
303        try
304        {
305            $response = $this->getClientHandler()->get('bare-metals/'.$id.'/user-data');
306        }
307        catch (VultrClientException $e)
308        {
309            throw new BareMetalException('Failed to get user data: '.$e->getMessage(), $e->getHTTPCode(), $e);
310        }
311
312        return base64_decode(VultrUtil::decodeJSON((string)$response->getBody(), true)['user_data']['data']);
313    }
314
315    /**
316     * Get available upgrades for a Bare Metal instance.
317     *
318     * @see https://www.vultr.com/api/#operation/get-bare-metals-upgrades
319     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
320     * @param $type - string - filter based on upgrade types.
321     * @throws BareMetalException
322     * @return OperatingSystem|Application[]
323     */
324    public function getAvailableUpgrades(string $id, string $type = 'all') : array
325    {
326        try
327        {
328            $response = $this->getClientHandler()->get('bare-metals/'.$id.'/upgrades', ['type' => $type]);
329        }
330        catch (VultrClientException $e)
331        {
332            throw new BareMetalException('Failed to get available upgrades: '.$e->getMessage(), $e->getHTTPCode(), $e);
333        }
334
335        $output = [];
336        $application = new Application();
337        $os = new OperatingSystem();
338        foreach (VultrUtil::decodeJSON((string)$response->getBody())->upgrades as $type => $upgrades)
339        {
340            foreach ($upgrades as $upgrade)
341            {
342                $output[] = VultrUtil::mapObject($upgrade, $type === 'os' ? clone $os : clone $application);
343            }
344        }
345
346        return $output;
347    }
348
349    /**
350     * Get the VNC URL for a Bare Metal instance. Which can be used to access the console of the machine.
351     *
352     * @see https://www.vultr.com/api/#operation/get-bare-metal-vnc
353     * @param $id - string - Example: cb676a46-66fd-4dfb-b839-443f2e6c0b60
354     * @throws BareMetalException
355     * @throws VultrException
356     * @return string
357     */
358    public function getVNCUrl(string $id) : string
359    {
360        try
361        {
362            $response = $this->getClientHandler()->get('bare-metals/'.$id.'/vnc');
363        }
364        catch (VultrClientException $e)
365        {
366            throw new BareMetalException('Failed to get vnc url: '.$e->getMessage(), $e->getHTTPCode(), $e);
367        }
368
369        return VultrUtil::decodeJSON((string)$response->getBody(), true)['vnc']['url'];
370    }
371}