Passed
Push — master ( 0676a7...01ab94 )
by Artem
11:54
created

LinodeClient::delete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
c 0
b 0
f 0
rs 10
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
// ---------------------------------------------------------------------
4
//
5
//  Copyright (C) 2018-2024 Artem Rodygin
6
//
7
//  You should have received a copy of the MIT License along with
8
//  this file. If not, see <https://opensource.org/licenses/MIT>.
9
//
10
// ---------------------------------------------------------------------
11
12
namespace Linode;
13
14
use GuzzleHttp\Client;
15
use GuzzleHttp\ClientInterface;
16
use GuzzleHttp\Exception\ClientException;
17
use GuzzleHttp\Exception\GuzzleException;
18
use GuzzleHttp\Psr7\Response;
19
use Linode\Exception\LinodeException;
20
use Psr\Http\Message\ResponseInterface;
21
22
/**
23
 * Linode API client.
24
 *
25
 * @property Account\Account                                       $account
26
 * @property Domains\DomainRepositoryInterface                     $domains
27
 * @property Images\ImageRepositoryInterface                       $images
28
 * @property LinodeInstances\KernelRepositoryInterface             $kernels
29
 * @property LinodeInstances\LinodeRepositoryInterface             $linodes
30
 * @property LinodeTypes\LinodeTypeRepositoryInterface             $linodeTypes
31
 * @property Longview\LongviewClientRepositoryInterface            $longviewClients
32
 * @property Longview\LongviewSubscriptionRepositoryInterface      $longviewSubscriptions
33
 * @property Managed\ManagedContactRepositoryInterface             $managedContacts
34
 * @property Managed\ManagedCredentialRepositoryInterface          $managedCredentials
35
 * @property Managed\ManagedIssueRepositoryInterface               $managedIssues
36
 * @property Managed\ManagedLinodeSettingsRepositoryInterface      $managedLinodeSettings
37
 * @property Managed\ManagedServiceRepositoryInterface             $managedServices
38
 * @property Networking\IPAddressRepositoryInterface               $ipAddresses
39
 * @property Networking\IPv6PoolRepositoryInterface                $ipv6Pools
40
 * @property Networking\IPv6RangeRepositoryInterface               $ipv6Ranges
41
 * @property NodeBalancers\NodeBalancerRepositoryInterface         $nodeBalancers
42
 * @property ObjectStorage\ObjectStorageClusterRepositoryInterface $objectStorageClusters
43
 * @property ObjectStorage\ObjectStorageKeyRepositoryInterface     $objectStorageKeys
44
 * @property Profile\Profile                                       $profile
45
 * @property Regions\RegionRepositoryInterface                     $regions
46
 * @property StackScripts\StackScriptRepositoryInterface           $stackScripts
47
 * @property Support\SupportTicketRepositoryInterface              $supportTickets
48
 * @property Tags\TagRepositoryInterface                           $tags
49
 * @property Volumes\VolumeRepositoryInterface                     $volumes
50
 */
51
class LinodeClient
52
{
53
    // Request methods.
54
    public const REQUEST_GET    = 'GET';
55
    public const REQUEST_POST   = 'POST';
56
    public const REQUEST_PUT    = 'PUT';
57
    public const REQUEST_DELETE = 'DELETE';
58
59
    // Response success codes.
60
    public const SUCCESS_OK         = 200;
61
    public const SUCCESS_NO_CONTENT = 204;
62
63
    // Response error codes.
64
    public const ERROR_BAD_REQUEST           = 400;
65
    public const ERROR_UNAUTHORIZED          = 401;
66
    public const ERROR_FORBIDDEN             = 403;
67
    public const ERROR_NOT_FOUND             = 404;
68
    public const ERROR_TOO_MANY_REQUESTS     = 429;
69
    public const ERROR_INTERNAL_SERVER_ERROR = 500;
70
71
    // Base URI to Linode API.
72
    protected const BASE_API_URI = 'https://api.linode.com/v4';
73
74
    /** @var ClientInterface HTTP client. */
75
    protected ClientInterface $client;
76
77
    /**
78
     * @param null|string $access_token API access token (PAT or retrieved via OAuth).
79
     */
80 1
    public function __construct(protected ?string $access_token = null)
81
    {
82 1
        $this->client = new Client();
83
    }
84
85
    /**
86
     * Returns specified repository.
87
     *
88
     * @param string $name Repository name.
89
     *
90
     * @throws LinodeException
91
     */
92 1
    public function __get(string $name): null|Account\Account|Profile\Profile|RepositoryInterface
93
    {
94 1
        return match ($name) {
95 1
            'account'               => new Account\Account($this),
96 1
            'domains'               => new Domains\Repository\DomainRepository($this),
97 1
            'images'                => new Images\Repository\ImageRepository($this),
98 1
            'kernels'               => new LinodeInstances\Repository\KernelRepository($this),
99 1
            'linodes'               => new LinodeInstances\Repository\LinodeRepository($this),
100 1
            'linodeTypes'           => new LinodeTypes\Repository\LinodeTypeRepository($this),
101 1
            'longviewClients'       => new Longview\Repository\LongviewClientRepository($this),
102 1
            'longviewSubscriptions' => new Longview\Repository\LongviewSubscriptionRepository($this),
103 1
            'managedContacts'       => new Managed\Repository\ManagedContactRepository($this),
104 1
            'managedCredentials'    => new Managed\Repository\ManagedCredentialRepository($this),
105 1
            'managedIssues'         => new Managed\Repository\ManagedIssueRepository($this),
106 1
            'managedLinodeSettings' => new Managed\Repository\ManagedLinodeSettingsRepository($this),
107 1
            'managedServices'       => new Managed\Repository\ManagedServiceRepository($this),
108 1
            'ipAddresses'           => new Networking\Repository\IPAddressRepository($this),
109 1
            'ipv6Pools'             => new Networking\Repository\IPv6PoolRepository($this),
110 1
            'ipv6Ranges'            => new Networking\Repository\IPv6RangeRepository($this),
111 1
            'nodeBalancers'         => new NodeBalancers\Repository\NodeBalancerRepository($this),
112 1
            'objectStorageClusters' => new ObjectStorage\Repository\ObjectStorageClusterRepository($this),
113 1
            'objectStorageKeys'     => new ObjectStorage\Repository\ObjectStorageKeyRepository($this),
114 1
            'profile'               => new Profile\Profile($this),
115 1
            'regions'               => new Regions\Repository\RegionRepository($this),
116 1
            'stackScripts'          => new StackScripts\Repository\StackScriptRepository($this),
117 1
            'supportTickets'        => new Support\Repository\SupportTicketRepository($this),
118 1
            'tags'                  => new Tags\Repository\TagRepository($this),
119 1
            'volumes'               => new Volumes\Repository\VolumeRepository($this),
120 1
            default                 => null,
121 1
        };
122
    }
123
124
    /**
125
     * Performs a GET request to specified API endpoint.
126
     *
127
     * @param string $uri     Relative URI to the API endpoint.
128
     * @param array  $body    Request body.
129
     * @param array  $filters Pagination options.
130
     *
131
     * @throws LinodeException
132
     */
133 2
    public function get(string $uri, array $body = [], array $filters = []): ResponseInterface
134
    {
135 2
        $options = [];
136
137 2
        if (0 !== count($filters)) {
138 2
            $options['headers']['X-Filter'] = json_encode($filters);
139
        }
140
141 2
        if (0 !== count($body)) {
142 2
            $options['query'] = $body;
143
        }
144
145 2
        return $this->api(self::REQUEST_GET, $uri, $options);
146
    }
147
148
    /**
149
     * Performs a POST request to specified API endpoint.
150
     *
151
     * @param string $uri     Relative URI to the API endpoint.
152
     * @param array  $body    Request body.
153
     * @param array  $options Custom request options.
154
     *
155
     * @throws LinodeException
156
     */
157 1
    public function post(string $uri, array $body = [], array $options = []): ResponseInterface
158
    {
159 1
        if (0 !== count($body) && 0 === count($options)) {
160 1
            $options['json'] = array_filter($body, static fn ($value) => null !== $value);
161
        }
162
163 1
        return $this->api(self::REQUEST_POST, $uri, $options);
164
    }
165
166
    /**
167
     * Performs a PUT request to specified API endpoint.
168
     *
169
     * @param string $uri     Relative URI to the API endpoint.
170
     * @param array  $body    Request body.
171
     * @param array  $options Custom request options.
172
     *
173
     * @throws LinodeException
174
     */
175 1
    public function put(string $uri, array $body = [], array $options = []): ResponseInterface
176
    {
177 1
        if (0 !== count($body) && 0 === count($options)) {
178 1
            $options['json'] = array_filter($body, static fn ($value) => null !== $value);
179
        }
180
181 1
        return $this->api(self::REQUEST_PUT, $uri, $options);
182
    }
183
184
    /**
185
     * Performs a DELETE request to specified API endpoint.
186
     *
187
     * @param string $uri Relative URI to the API endpoint.
188
     *
189
     * @throws LinodeException
190
     */
191 1
    public function delete(string $uri): ResponseInterface
192
    {
193 1
        return $this->api(self::REQUEST_DELETE, $uri);
194
    }
195
196
    /**
197
     * Performs a request to specified API endpoint.
198
     *
199
     * @param string $method  Request method.
200
     * @param string $uri     Relative URI to request bodyAPI endpoint.
201
     * @param array  $options Request options.
202
     *
203
     * @throws LinodeException
204
     */
205 2
    protected function api(string $method, string $uri, array $options = []): ResponseInterface
206
    {
207
        try {
208 2
            if (null !== $this->access_token) {
209 2
                $options['headers']['Authorization'] = 'Bearer ' . $this->access_token;
210
            }
211
212 2
            return $this->client->request($method, self::BASE_API_URI . $uri, $options);
213 2
        } catch (ClientException $exception) {
214 1
            throw new LinodeException($exception->getResponse());
215 1
        } catch (GuzzleException) {
216 1
            throw new LinodeException(new Response(500));
217
        }
218
    }
219
}
220