diff --git a/app/Commands/Servers/RebootCommand.php b/app/Commands/Servers/RebootCommand.php new file mode 100644 index 0000000..dd44f27 --- /dev/null +++ b/app/Commands/Servers/RebootCommand.php @@ -0,0 +1,78 @@ +option('all')) { + $this->rebootAll(); + return self::SUCCESS; + } + + $serverId = $this->argument('server_id'); + + if (empty($serverId)) { + $serverId = $this->askToSelectServer('Which server would you like to reboot'); + } + + $server = $this->spinupwp->getServer((int) $serverId); + + if ((bool) $this->option('force') || $this->confirm("Are you sure you want to reboot \"{$server->name}\"?", true)) { + $this->rebootServers([$server]); + } + + return self::SUCCESS; + } + + protected function rebootAll(): void + { + if ((bool) $this->option('force') || $this->confirm('Are you sure you want to reboot all servers?', true)) { + $this->rebootServers($this->spinupwp->listServers()->toArray()); + } + } + + protected function rebootServers(array $servers): void + { + if (empty($servers)) { + return; + } + + $events = []; + + foreach ($servers as $server) { + try { + $eventId = $server->reboot(); + $events[] = ["{$eventId}", $server->name]; + } catch (\Exception $e) { + if (count($servers) === 1) { + $this->error("{$server->name} could not be rebooted."); + return; + } + } + } + + if (empty($events)) { + $this->error('No servers could be rebooted.'); + return; + } + + $this->successfulStep((count($events) === 1 ? 'Server' : 'Servers') . ' queued for reboot.'); + + $this->stepTable([ + 'Event ID', + 'Server', + ], $events); + } +} diff --git a/tests/Feature/Commands/ServersRebootCommandTest.php b/tests/Feature/Commands/ServersRebootCommandTest.php new file mode 100644 index 0000000..aad4029 --- /dev/null +++ b/tests/Feature/Commands/ServersRebootCommandTest.php @@ -0,0 +1,45 @@ +clientMock->shouldReceive('request')->with('GET', 'servers/1', [])->andReturn( + new Response(200, [], json_encode(['data' => ['id' => 1, 'name' => 'hellfish-media']])) + ); + + $this->clientMock->shouldReceive('request')->with('POST', 'servers/1/reboot', [])->andReturn( + new Response(200, [], json_encode(['event_id' => '100'])) + ); +}); + +afterEach(function () { + deleteTestConfigFile(); +}); + +test('reboot a server', function () { + $this->artisan('servers:reboot 1') + ->expectsConfirmation('Are you sure you want to reboot "hellfish-media"?', 'yes') + ->expectsOutput('==> Server queued for reboot.'); +}); + +test('reboot a server with force option', function () { + $this->artisan('servers:reboot 1 --force') + ->expectsOutput('==> Server queued for reboot.'); +}); + +test('reboot all servers', function () { + $this->clientMock->shouldReceive('request')->once()->with('GET', 'servers?page=1&limit=100', [])->andReturn( + new Response(200, [], listResponseJson([ + ['id' => 1, 'name' => 'hellfish-media'], + ['id' => 2, 'name' => 'staging.hellfish-media'], + ])) + ); + $this->clientMock->shouldReceive('request')->with('POST', 'servers/2/reboot', [])->andReturn( + new Response(200, [], json_encode(['event_id' => '101'])) + ); + $this->artisan('servers:reboot --all') + ->expectsConfirmation('Are you sure you want to reboot all servers?', 'yes') + ->expectsOutput('==> Servers queued for reboot.'); +});