Completed
Pull Request — master (#20)
by
unknown
04:51
created

Provider   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 385
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 3
dl 0
loc 385
rs 9.2
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A initProvider() 0 4 1
A provider() 0 4 1
A regions() 0 4 1
A sizes() 0 4 1
A phpVersions() 0 4 1
A validate() 0 4 1
A regionAvailable() 0 4 1
A memoryAvailable() 0 4 1
A resourceAvailable() 0 4 1
A hasPayload() 0 4 1
A usingCredential() 0 6 1
A identifiedAs() 0 6 1
A withMemoryOf() 0 10 2
A at() 0 10 2
A runningPhp() 0 12 2
A withMariaDb() 0 7 1
A withMysql() 0 7 1
A runRecipe() 0 6 1
A asLoadBalancer() 0 4 1
A asNodeBalancer() 0 4 1
A connectedTo() 0 6 1
A usingPublicIp() 0 6 1
A usingPrivateIp() 0 6 1
A save() 0 16 2
A sortPayload() 0 8 1
A togglePayload() 0 10 4
1
<?php
2
3
namespace Laravel\Forge\Servers\Providers;
4
5
use Laravel\Forge\Server;
6
use InvalidArgumentException;
7
use Laravel\Forge\ApiProvider;
8
9
abstract class Provider
10
{
11
    /**
12
     * @var \Laravel\Forge\ApiProvider
13
     */
14
    protected $api;
15
16
    /**
17
     * @var array
18
     */
19
    protected $payload = [];
20
21
    /**
22
     * Create new server provider instance.
23
     *
24
     * @param \Laravel\Forge\ApiProvider $api
25
     */
26
    public function __construct(ApiProvider $api)
27
    {
28
        $this->api = $api;
29
        $this->initProvider();
30
    }
31
32
    /**
33
     * Initializes server provider.
34
     */
35
    protected function initProvider()
36
    {
37
        $this->payload['provider'] = $this->provider();
38
    }
39
40
    /**
41
     * Server provider name.
42
     *
43
     * @return string
44
     */
45
    public function provider()
46
    {
47
        return 'abstract';
48
    }
49
50
    /**
51
     * Server provider regions list.
52
     *
53
     * @return array
54
     */
55
    public function regions()
56
    {
57
        return [];
58
    }
59
60
    /**
61
     * Server provider server sizes.
62
     *
63
     * @return array
64
     */
65
    public function sizes()
66
    {
67
        return [];
68
    }
69
70
    /**
71
     * Available PHP versions.
72
     *
73
     * @return array
74
     */
75
    public function phpVersions()
76
    {
77
        return [56, 70, 71];
78
    }
79
80
    /**
81
     * Validates payload before sending to Forge API.
82
     *
83
     * @return bool|array
84
     */
85
    public function validate()
86
    {
87
        return true;
88
    }
89
90
    /**
91
     * Determines if given region is available at current provider.
92
     *
93
     * @param string $region
94
     *
95
     * @return bool
96
     */
97
    public function regionAvailable(string $region)
98
    {
99
        return $this->resourceAvailable($this->regions(), $region);
100
    }
101
102
    /**
103
     * Determines if given memory size is available at current provider.
104
     *
105
     * @param string|int $memory
106
     *
107
     * @return bool
108
     */
109
    public function memoryAvailable($memory)
110
    {
111
        return $this->resourceAvailable($this->sizes(), $memory);
112
    }
113
114
    /**
115
     * Determines if given resource exists in resources list.
116
     *
117
     * @param array $resources
118
     * @param mixed $resource
119
     *
120
     * @return bool
121
     */
122
    protected function resourceAvailable(array $resources, $resource)
123
    {
124
        return isset($resources[$resource]);
125
    }
126
127
    /**
128
     * Determines if given key exists in current payload.
129
     *
130
     * @param string $key
131
     *
132
     * @return bool
133
     */
134
    public function hasPayload(string $key): bool
135
    {
136
        return !empty($this->payload[$key]);
137
    }
138
139
    /**
140
     * Set credential ID to create server with.
141
     *
142
     * @param int $credentialId
143
     *
144
     * @return static
145
     */
146
    public function usingCredential(int $credentialId)
147
    {
148
        $this->payload['credential_id'] = $credentialId;
149
150
        return $this;
151
    }
152
153
    /**
154
     * Set new server name.
155
     *
156
     * @param string $name
157
     *
158
     * @return static
159
     */
160
    public function identifiedAs(string $name)
161
    {
162
        $this->payload['name'] = $name;
163
164
        return $this;
165
    }
166
167
    /**
168
     * Set memory / server size.
169
     *
170
     * @param int|string $memory
171
     *
172
     * @return static
173
     */
174
    public function withMemoryOf($memory)
175
    {
176
        if (!$this->memoryAvailable($memory)) {
177
            throw new InvalidArgumentException('Given memory value is not supported by '.$this->provider().' provider.');
178
        }
179
180
        $this->payload['size'] = $memory;
181
182
        return $this;
183
    }
184
185
    /**
186
     * Set server region.
187
     *
188
     * @param string $region
189
     *
190
     * @return static
191
     */
192
    public function at(string $region)
193
    {
194
        if (!$this->regionAvailable($region)) {
195
            throw new InvalidArgumentException('Given region is not supported by '.$this->provider().' provider.');
196
        }
197
198
        $this->payload['region'] = $region;
199
200
        return $this;
201
    }
202
203
    /**
204
     * Set PHP version.
205
     *
206
     * @param int|string $version
207
     *
208
     * @return static
209
     */
210
    public function runningPhp($version)
211
    {
212
        $phpVersion = intval(str_replace(['php', '.'], '', $version));
213
214
        if (!in_array($phpVersion, $this->phpVersions())) {
215
            throw new InvalidArgumentException('PHP version "php'.$phpVersion.'" is not supported.');
216
        }
217
218
        $this->payload['php_version'] = 'php'.$phpVersion;
219
220
        return $this;
221
    }
222
223
    /**
224
     * Indicates that server should be provisioned with MariaDB instead of MySQL.
225
     *
226
     * @param string $database = 'forge'
227
     *
228
     * @return static
229
     */
230
    public function withMariaDb(string $database = 'forge')
231
    {
232
        $this->payload['maria'] = 1;
233
        $this->payload['database'] = $database;
234
235
        return $this;
236
    }
237
238
    /**
239
     * Indicates that server should be provisioned with MySQL.
240
     *
241
     * @param string $database = 'forge'
242
     *
243
     * @return static
244
     */
245
    public function withMysql(string $database = 'forge')
246
    {
247
        $this->payload['maria'] = 0;
248
        $this->payload['database'] = $database;
249
250
        return $this;
251
    }
252
253
    /**
254
     * Tells that the server should be created with recipe id to be run
255
     *
256
     * @param integer $recipeId
257
     *
258
     * @return static
259
    */
260
    public function runRecipe($recipeId)
261
    {
262
        $this->payload['recipe_id'] = $recipeId;
263
264
        return $this;
265
    }
266
267
    /**
268
     * Indicates that server should be provisioned as load balancer.
269
     *
270
     * @param bool $install = true
271
     *
272
     * @deprecated since 1.3.1
273
     * @see Provider::asNodeBalancer()
274
     *
275
     * @return static
276
     */
277
    public function asLoadBalancer(bool $install = true)
278
    {
279
        return $this->asNodeBalancer($install);
280
    }
281
282
    /**
283
     * Indicates that server should be provisioned as load balancer.
284
     *
285
     * @param bool $install = true
286
     *
287
     * @return static
288
     */
289
    public function asNodeBalancer(bool $install = true)
290
    {
291
        return $this->togglePayload('node_balancer', $install);
292
    }
293
294
    /**
295
     * Servers ID that the new server should be connected to.
296
     *
297
     * @param array $servers
298
     *
299
     * @return static
300
     */
301
    public function connectedTo(array $servers)
302
    {
303
        $this->payload['network'] = $servers;
304
305
        return $this;
306
    }
307
308
    /**
309
     * Public IP address.
310
     *
311
     * @param string $ip
312
     *
313
     * @return static
314
     */
315
    public function usingPublicIp(string $ip)
316
    {
317
        $this->payload['ip_address'] = $ip;
318
319
        return $this;
320
    }
321
322
    /**
323
     * Private IP address.
324
     *
325
     * @param string $ip
326
     *
327
     * @return static
328
     */
329
    public function usingPrivateIp(string $ip)
330
    {
331
        $this->payload['private_ip_address'] = $ip;
332
333
        return $this;
334
    }
335
336
    /**
337
     * Create new server.
338
     *
339
     * @throws \GuzzleHttp\Exception\RequestException
340
     * @throws \InvalidArgumentException
341
     *
342
     * @return \Laravel\Forge\Server
343
     */
344
    public function save()
345
    {
346
        $validationResult = $this->validate();
347
348
        if ($validationResult !== true) {
349
            throw new InvalidArgumentException(
350
                'Some required parameters are missing: '.implode(', ', $validationResult)
351
            );
352
        }
353
354
        $response = $this->api->getClient()->request('POST', 'servers', [
355
            'json' => $this->sortPayload(),
356
        ]);
357
358
        return Server::createFromResponse($response, $this->api);
359
    }
360
361
    /**
362
     * Sort payload data by key name.
363
     *
364
     * @return array
365
     */
366
    protected function sortPayload(): array
367
    {
368
        $payload = $this->payload;
369
370
        ksort($payload);
371
372
        return $payload;
373
    }
374
375
    /**
376
     * Toggle boolean payload key.
377
     *
378
     * @param string $key
379
     * @param bool   $install
380
     *
381
     * @return static
382
     */
383
    protected function togglePayload(string $key, bool $install)
384
    {
385
        if ($install === false && isset($this->payload[$key])) {
386
            unset($this->payload[$key]);
387
        } elseif ($install === true) {
388
            $this->payload[$key] = 1;
389
        }
390
391
        return $this;
392
    }
393
}
394