Completed
Push — master ( d97254...a7d64c )
by Timur
02:21
created

ForgeServers::createServer()   D

Complexity

Conditions 10
Paths 384

Size

Total Lines 74
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 74
rs 4.0449
c 0
b 0
f 0
cc 10
eloc 47
nc 384
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Laravel\Forge\Laravel\Commands;
4
5
use Laravel\Forge\Forge;
6
use Illuminate\Support\Str;
7
use Illuminate\Console\Command;
8
use GuzzleHttp\Exception\RequestException;
9
use Laravel\Forge\Servers\Providers\Provider;
10
11
class ForgeServers extends Command
12
{
13
    /**
14
     * The name and signature of the console command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'forge:servers';
19
20
    /**
21
     * The console command description.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Manage Forge Servers';
26
27
    /**
28
     * Execute the console command.
29
     *
30
     * @return mixed
31
     */
32
    public function handle(Forge $forge)
33
    {
34
        $action = $this->choice('What do you want to do?', [
35
            'list' => 'List Servers',
36
            'create' => 'Create New Server',
37
            'delete' => 'Delete Server',
38
        ]);
39
40
        switch ($action) {
41
            case 'list':
42
                return $this->handleListAction($forge);
43
            case 'create':
44
                return $this->handleCreateAction($forge);
45
            case 'delete':
46
                return $this->handleDeleteAction($forge);
47
        }
48
    }
49
50
    /**
51
     * Asks user to choose a server.
52
     *
53
     * @param \Laravel\Forge\Forge $forge
54
     * @param string               $message = 'Choose Server'
55
     *
56
     * @return \Laravel\Forge\Server
57
     */
58
    protected function chooseServer(Forge $forge, string $message = 'Choose Server')
59
    {
60
        $choices = [];
61
62
        foreach ($forge as $server) {
63
            $choices[$server->name()] = $server->id();
64
        }
65
66
        $serverName = $this->choice($message, $choices);
67
68
        return $forge[$serverName];
69
    }
70
71
    /**
72
     * "List Servers" handler.
73
     *
74
     * @param \Laravel\Forge\Forge $forge
75
     *
76
     * @return mixed
77
     */
78
    protected function handleListAction(Forge $forge)
79
    {
80
        $headers = ['ID', 'Name', 'Size', 'Region', 'Ready?', 'PHP Version'];
81
        $rows = [];
82
83
        foreach ($forge as $server) {
84
            $rows[] = [
85
                $server->id(),
86
                $server->name(),
87
                $server->size(),
88
                $server->region(),
89
                $server->isReady() ? 'Yes' : 'No',
90
                $server->phpVersion(),
91
            ];
92
        }
93
94
        $this->info('Here are your servers:');
95
        $this->table($headers, $rows);
96
    }
97
98
    /**
99
     * "Create New Server" handler.
100
     *
101
     * @param \Laravel\Forge\Forge $forge
102
     *
103
     * @return mixed
104
     */
105
    protected function handleCreateAction(Forge $forge)
106
    {
107
        $provider = $this->choice('Choose provider', [
108
            'ocean2' => 'DigitalOcean',
109
            'linode' => 'Linode',
110
            'aws' => 'AWS',
111
            'custom' => 'Custom VPS',
112
        ]);
113
114
        $name = $this->ask('Choose name for your new server');
115
116
        switch ($provider) {
117
            case 'ocean2':
118
                return $this->createServer($forge->create()->droplet($name));
119
            case 'linode':
120
                return $this->createServer($forge->create()->linode($name));
121
            case 'aws':
122
                return $this->createServer($forge->create()->aws($name));
123
            case 'custom':
124
                return $this->createServer($forge->create()->custom($name));
125
        }
126
    }
127
128
    /**
129
     * Create server at specific provider.
130
     *
131
     * @param \Laravel\Forge\Servers\Providers\Provider $provider
132
     *
133
     * @return mixed
134
     */
135
    protected function createServer(Provider $provider)
136
    {
137
        if ($provider->provider() !== 'custom') {
138
            $size = $this->choice('Choose server size', array_keys($provider->sizes()));
139
            $provider->withMemoryOf($size);
140
141
            $regions = $provider->regions();
142
143
            $region = $this->choice('Choose server region', $regions);
144
145
            if ($provider->provider() === 'linode') {
146
                $flippedRegions = array_flip($regions);
147
                $region = $flippedRegions[$region];
148
            }
149
150
            $provider->at($region);
151
        }
152
153
        $phpVersion = $this->choice('Choose PHP version', $provider->phpVersions());
154
        $provider->runningPhp($phpVersion);
155
156
        $databaseName = 'forge';
157
158
        if ($this->confirm('Do you want to set new database name?')) {
159
            $databaseName = $this->ask('Choose database name');
160
        } else {
161
            $this->comment('OK, using default database name ("forge").');
162
        }
163
164
        if ($this->confirm('Do you want to install MariaDb instead of MySQL?')) {
165
            $provider->withMariaDb($databaseName);
166
            $this->comment('OK, MariaDb server will be installed');
167
        } else {
168
            $provider->withMysql($databaseName);
169
            $this->comment('OK, MySQL server will be installed.');
170
        }
171
172
        if ($this->confirm('Do you want to provision this server as load balancer?', false)) {
173
            $provider->asLoadBalancer();
174
            $this->comment('OK, server will be provisioned as load balancer.');
175
        }
176
177
        if ($provider->provider() === 'custom') {
178
            $publicIp = $this->ask('Please, provide public IP address for this VPS');
179
            $privateIp = $this->ask('Please, provide private IP address for this VPS');
180
181
            $provision->usingPublicIp($publicIp)->usingPrivateIp($privateIp);
0 ignored issues
show
Bug introduced by
The variable $provision does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
182
        }
183
184
        $hasCredentials = $provider->hasPayload('credential_id');
185
        $credentialMessage = 'Seems that you\'re using predefined credential. Do you want to change credential for this server?';
186
        $updateCredential = $hasCredentials === false || $this->confirm($credentialMessage, false);
187
188
        if ($updateCredential) {
189
            $credentialId = $this->ask('Enter credential ID');
190
            $provider->usingCredential($credentialId);
191
        } else {
192
            $this->comment('OK, default credential will be used.');
193
        }
194
195
        try {
196
            $server = $provider->save();
197
        } catch (RequestException $e) {
198
            $response = $e->getResponse();
199
200
            $this->error('Request ended with error.');
201
            $this->error('HTTP Status Code: '.$response->getStatusCode());
202
203
            return $this->error((string) $response->getBody());
204
        }
205
206
        $this->info('Great! Your new server "'.$server->name().'" was created!');
207
        $this->info('Please allow up to 10-15 minutes to finish server provision.');
208
    }
209
210
    /**
211
     * "Delete Server" handler.
212
     *
213
     * @param \Laravel\Forge\Forge $forge
214
     *
215
     * @return mixed
216
     */
217
    protected function handleDeleteAction(Forge $forge)
218
    {
219
        $server = $this->chooseServer($forge);
220
221
        $this->error('THIS IS DESTRUCTIVE OPERATION! YOUR SERVER WILL BE DELETED AND THIS ACTION IS UNDONE!');
222
        $this->error('You\'re going to delete '.Str::upper($server->name()).' server.');
223
224
        if (!$this->confirm('Are you totally sure you want to delete this server?', false)) {
225
            return $this->info('Ok, your server left untoched.');
226
        }
227
228
        $this->error('We require one more confirmation that you\'re totally sure about deleting '.$server->name().' server.');
229
        $confirmation = $this->ask('Enter server name to continue');
230
231
        if ($server->name() !== $confirmation) {
232
            return $this->error('You\'ve entered wrong name, operation aborted.');
233
        }
234
235
        $this->info('Ok, server '.$server->name().' will be deleted now.');
236
237
        $server->delete();
238
239
        $this->info('Server '.$server->name().' was sucessfully deleted.');
240
    }
241
}
242