Skip to content

Commit 04ebe6f

Browse files
committed
feat: add nat gateway commands
1 parent c62d4ca commit 04ebe6f

File tree

6 files changed

+176
-48
lines changed

6 files changed

+176
-48
lines changed

src/ApiClient.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ public function __construct(string $baseUrl, ClientInterface $client, CliConfigu
5252
$this->cliConfiguration = $cliConfiguration;
5353
}
5454

55+
/**
56+
* Add a NAT gateway to the given network.
57+
*/
58+
public function addNatGateway(int $networkId)
59+
{
60+
$this->request('post', "/networks/{$networkId}/nat");
61+
}
62+
5563
/**
5664
* Send signal to the Ymir API to cancel the deployment.
5765
*/
@@ -586,6 +594,14 @@ public function getInvocation(int $invocationId): Collection
586594
return $this->request('get', "/invocations/{$invocationId}");
587595
}
588596

597+
/**
598+
* Get the network.
599+
*/
600+
public function getNetwork(int $networkId): Collection
601+
{
602+
return $this->request('get', "/networks/{$networkId}");
603+
}
604+
589605
/**
590606
* Get the project.
591607
*/
@@ -732,6 +748,14 @@ public function isAuthenticated(): bool
732748
}
733749
}
734750

751+
/**
752+
* Remove the NAT gateway from the given network.
753+
*/
754+
public function removeNatGateway(int $networkId)
755+
{
756+
$this->request('delete', "/networks/{$networkId}/nat");
757+
}
758+
735759
/**
736760
* Send signal to the Ymir API to start the deployment.
737761
*/

src/Command/AbstractCommand.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,29 @@ protected function determineCloudProvider(string $question, InputInterface $inpu
8888
return 1 === count($providers) ? $providers[0]['id'] : $output->choiceWithId($question, $providers);
8989
}
9090

91+
/**
92+
* Determine the network to use.
93+
*/
94+
protected function determineNetwork(string $question, InputInterface $input, ConsoleOutput $output): int
95+
{
96+
$networkIdOrName = $this->getStringArgument($input, 'network');
97+
$networks = $this->apiClient->getTeamNetworks($this->cliConfiguration->getActiveTeamId());
98+
99+
if (empty($networkIdOrName) && $input->isInteractive()) {
100+
$networkIdOrName = $output->choiceWithResourceDetails($question, $networks);
101+
}
102+
103+
$network = $networks->firstWhere('name', $networkIdOrName) ?? $networks->firstWhere('id', $networkIdOrName);
104+
105+
if (1 < $networks->where('name', $networkIdOrName)->count()) {
106+
throw new RuntimeException(sprintf('Unable to select a network because more than one network has the name "%s"', $networkIdOrName));
107+
} elseif (empty($network['id'])) {
108+
throw new RuntimeException(sprintf('Unable to find a network with "%s" as the ID or name', $networkIdOrName));
109+
}
110+
111+
return (int) $network['id'];
112+
}
113+
91114
/**
92115
* Determine the cloud provider region to use.
93116
*/

src/Command/Database/CreateDatabaseServerCommand.php

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
use Symfony\Component\Console\Input\InputArgument;
2020
use Symfony\Component\Console\Input\InputInterface;
2121
use Symfony\Component\Console\Input\InputOption;
22+
use Tightenco\Collect\Support\Arr;
23+
use Tightenco\Collect\Support\Collection;
2224
use Ymir\Cli\Command\AbstractCommand;
2325
use Ymir\Cli\Command\Network\CreateNetworkCommand;
2426
use Ymir\Cli\Console\ConsoleOutput;
@@ -49,6 +51,28 @@ protected function configure()
4951
->addOption('type', null, InputOption::VALUE_REQUIRED, 'The database server type to create on the cloud provider');
5052
}
5153

54+
/**
55+
* Determine the network to create the database on.
56+
*/
57+
protected function determineNetwork(string $question, InputInterface $input, ConsoleOutput $output): int
58+
{
59+
$networks = $this->apiClient->getTeamNetworks($this->cliConfiguration->getActiveTeamId())->whereNotIn('status', ['deleting', 'failed']);
60+
61+
if ($networks->isEmpty() && !$output->confirm('Your team doesn\'t have any provisioned networks to create the database server on. Would you like to create one first? <fg=default>(Answering "<comment>no</comment>" will cancel the command.)</>')) {
62+
throw new CommandCancelledException();
63+
}
64+
65+
if ($networks->isEmpty()) {
66+
$this->retryApi(function () use ($output) {
67+
$this->invoke($output, CreateNetworkCommand::NAME);
68+
}, 'Do you want to try creating a network again?', $output);
69+
70+
return (int) Arr::get($this->apiClient->getTeamNetworks($this->cliConfiguration->getActiveTeamId())->last(), 'id');
71+
}
72+
73+
return parent::determineNetwork($question, $input, $output);
74+
}
75+
5276
/**
5377
* {@inheritdoc}
5478
*/
@@ -60,7 +84,7 @@ protected function perform(InputInterface $input, ConsoleOutput $output)
6084
$name = $output->askSlug('What is the name of the database server');
6185
}
6286

63-
$network = $this->determineNetwork($input, $output);
87+
$network = $this->apiClient->getNetwork($this->determineNetwork('On what network should the database server be created?', $input, $output));
6488
$type = $this->determineType($network, $input, $output);
6589
$storage = $this->determineStorage($input, $output);
6690
$public = $this->determinePublic($input, $output);
@@ -75,37 +99,6 @@ protected function perform(InputInterface $input, ConsoleOutput $output)
7599
$output->infoWithDelayWarning('Database server created');
76100
}
77101

78-
/**
79-
* Determine the network to create the database on.
80-
*/
81-
private function determineNetwork(InputInterface $input, ConsoleOutput $output): array
82-
{
83-
$networkIdOrName = $this->getStringOption($input, 'network', true);
84-
$networks = $this->apiClient->getTeamNetworks($this->cliConfiguration->getActiveTeamId())->whereNotIn('status', ['deleting', 'failed']);
85-
86-
if ($networks->isEmpty() && !$output->confirm('Your team doesn\'t have any provisioned networks to create the database server on. Would you like to create one first? <fg=default>(Answering "<comment>no</comment>" will cancel the command.)</>')) {
87-
throw new CommandCancelledException();
88-
}
89-
90-
if ($networks->isEmpty()) {
91-
$this->retryApi(function () use ($output) {
92-
$this->invoke($output, CreateNetworkCommand::NAME);
93-
}, 'Do you want to try creating a network again?', $output);
94-
95-
return $this->apiClient->getTeamNetworks($this->cliConfiguration->getActiveTeamId())->last();
96-
} elseif (!$networks->isEmpty() && empty($networkIdOrName)) {
97-
$networkIdOrName = $output->choiceWithResourceDetails('On what network should the database server be created?', $networks);
98-
}
99-
100-
$network = $networks->firstWhere('id', $networkIdOrName) ?? $networks->firstWhere('name', $networkIdOrName);
101-
102-
if (!is_array($network)) {
103-
throw new RuntimeException(sprintf('Unable to find a network with "%s" as the ID or name', $networkIdOrName));
104-
}
105-
106-
return $network;
107-
}
108-
109102
/**
110103
* Determine whether the database should be publicly accessible or not.
111104
*/
@@ -142,7 +135,7 @@ private function determineStorage(InputInterface $input, ConsoleOutput $output):
142135
/**
143136
* Determine the database server type to create.
144137
*/
145-
private function determineType(array $network, InputInterface $input, ConsoleOutput $output): string
138+
private function determineType(Collection $network, InputInterface $input, ConsoleOutput $output): string
146139
{
147140
if (!isset($network['provider']['id'])) {
148141
throw new RuntimeException('The Ymir API failed to return information on the cloud provider');
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Ymir command-line tool.
7+
*
8+
* (c) Carl Alexander <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Ymir\Cli\Command\Network;
15+
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Input\InputInterface;
18+
use Ymir\Cli\Command\AbstractCommand;
19+
use Ymir\Cli\Console\ConsoleOutput;
20+
21+
class AddNatGatewayCommand extends AbstractCommand
22+
{
23+
/**
24+
* The name of the command.
25+
*
26+
* @var string
27+
*/
28+
public const NAME = 'network:nat:add';
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
protected function configure()
34+
{
35+
$this
36+
->setName(self::NAME)
37+
->setDescription('Add a NAT gateway to the network\'s private subnet')
38+
->addArgument('network', InputArgument::OPTIONAL, 'The ID or name of the network to add a NAT gateway to');
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
protected function perform(InputInterface $input, ConsoleOutput $output)
45+
{
46+
$this->apiClient->addNatGateway($this->determineNetwork('Which network would like to add a NAT gateway to', $input, $output));
47+
48+
$output->infoWithDelayWarning('NAT gateway added');
49+
}
50+
}

src/Command/Network/DeleteNetworkCommand.php

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
namespace Ymir\Cli\Command\Network;
1515

16-
use Symfony\Component\Console\Exception\RuntimeException;
1716
use Symfony\Component\Console\Input\InputArgument;
1817
use Symfony\Component\Console\Input\InputInterface;
1918
use Ymir\Cli\Command\AbstractCommand;
@@ -44,24 +43,13 @@ protected function configure()
4443
*/
4544
protected function perform(InputInterface $input, ConsoleOutput $output)
4645
{
47-
$networkIdOrName = $this->getStringArgument($input, 'network');
48-
$networks = $this->apiClient->getTeamNetworks($this->cliConfiguration->getActiveTeamId());
46+
$network = $this->determineNetwork('Which network would you like to delete', $input, $output);
4947

50-
if (empty($networkIdOrName) && $input->isInteractive()) {
51-
$networkIdOrName = $output->choiceWithResourceDetails('Which network like to delete', $networks);
52-
}
53-
54-
$network = $networks->firstWhere('name', $networkIdOrName) ?? $networks->firstWhere('id', $networkIdOrName);
55-
56-
if (1 < $networks->where('name', $networkIdOrName)->count()) {
57-
throw new RuntimeException(sprintf('Unable to select a network because more than one network has the name "%s"', $networkIdOrName));
58-
} elseif (empty($network['id'])) {
59-
throw new RuntimeException(sprintf('Unable to find a network with "%s" as the ID or name', $networkIdOrName));
60-
} elseif (!$output->confirm('Are you sure you want to delete this network?', false)) {
48+
if (!$output->confirm('Are you sure you want to delete this network?', false)) {
6149
return;
6250
}
6351

64-
$this->apiClient->deleteNetwork((int) $network['id']);
52+
$this->apiClient->deleteNetwork($network);
6553

6654
$output->infoWithDelayWarning('Network deleted');
6755
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Ymir command-line tool.
7+
*
8+
* (c) Carl Alexander <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Ymir\Cli\Command\Network;
15+
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Input\InputInterface;
18+
use Ymir\Cli\Command\AbstractCommand;
19+
use Ymir\Cli\Console\ConsoleOutput;
20+
21+
class RemoveNatGatewayCommand extends AbstractCommand
22+
{
23+
/**
24+
* The name of the command.
25+
*
26+
* @var string
27+
*/
28+
public const NAME = 'network:nat:remove';
29+
30+
/**
31+
* {@inheritdoc}
32+
*/
33+
protected function configure()
34+
{
35+
$this
36+
->setName(self::NAME)
37+
->setDescription('Remove the NAT gateway from the network\'s private subnet')
38+
->addArgument('network', InputArgument::OPTIONAL, 'The ID or name of the network to remove the NAT gateway from');
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
protected function perform(InputInterface $input, ConsoleOutput $output)
45+
{
46+
$this->apiClient->removeNatGateway($this->determineNetwork('Which network would like to add a NAT gateway to', $input, $output));
47+
48+
$output->infoWithDelayWarning('NAT gateway removed');
49+
}
50+
}

0 commit comments

Comments
 (0)