1313
1414namespace Ymir \Cli \Command \Database ;
1515
16- use Illuminate \Support \Collection ;
1716use Symfony \Component \Console \Exception \InvalidArgumentException ;
1817use Symfony \Component \Console \Exception \RuntimeException ;
1918use Symfony \Component \Console \Helper \TableSeparator ;
2221use Symfony \Component \Console \Input \InputOption ;
2322use Ymir \Cli \Command \AbstractCommand ;
2423use Ymir \Cli \Console \OutputInterface ;
24+ use Ymir \Cli \Exception \CommandCancelledException ;
2525
2626class CreateDatabaseServerCommand extends AbstractCommand
2727{
@@ -44,6 +44,7 @@ protected function configure()
4444 ->addOption ('network ' , null , InputOption::VALUE_REQUIRED , 'The ID or name of the network on which the database will be created ' )
4545 ->addOption ('private ' , null , InputOption::VALUE_NONE , 'The created database server won \'t be publicly accessible ' )
4646 ->addOption ('public ' , null , InputOption::VALUE_NONE , 'The created database server will be publicly accessible ' )
47+ ->addOption ('serverless ' , null , InputOption::VALUE_NONE , 'Create an Aurora serverless database cluster (overrides all other options) ' )
4748 ->addOption ('storage ' , null , InputOption::VALUE_REQUIRED , 'The maximum amount of storage (in GB) allocated to the database server ' )
4849 ->addOption ('type ' , null , InputOption::VALUE_REQUIRED , 'The database server type to create on the cloud provider ' );
4950 }
@@ -60,12 +61,19 @@ protected function perform(InputInterface $input, OutputInterface $output)
6061 }
6162
6263 $ network = $ this ->apiClient ->getNetwork ($ this ->determineOrCreateNetwork ('On what network should the database server be created? ' , $ input , $ output ));
63- $ type = $ this ->determineType ($ network , $ input , $ output );
64- $ storage = $ this ->determineStorage ($ input , $ output );
65- $ public = $ this ->determinePublic ($ input , $ output );
6664
67- if (!$ public && !$ network ->get ('has_nat_gateway ' ) && !$ output ->confirm ('A private database server will require Ymir to add a NAT gateway to your network (~$32/month). Would you like to proceed? (Answering "no" will make the database server publicly accessible.) ' )) {
65+ if (!isset ($ network ['provider ' ]['id ' ])) {
66+ throw new RuntimeException ('The Ymir API failed to return information on the cloud provider ' );
67+ }
68+
69+ $ type = $ this ->determineType ($ input , $ output , (int ) $ network ['provider ' ]['id ' ]);
70+ $ storage = 'aurora-mysql ' !== $ type ? $ this ->determineStorage ($ input , $ output ) : null ;
71+ $ public = 'aurora-mysql ' !== $ type && $ this ->determinePublic ($ input , $ output );
72+
73+ if (!$ public && !$ network ->get ('has_nat_gateway ' ) && !$ output ->confirm ('A private database server requires that Ymir add a NAT gateway (~$32/month) to your network. Would you like to proceed? <fg=default>(Answering "<comment>no</comment>" will make the database server publicly accessible.)</> ' )) {
6874 $ public = true ;
75+ } elseif ('aurora-mysql ' !== $ type && !$ network ->get ('has_nat_gateway ' ) && !$ output ->confirm ('An Aurora serverless database cluster requires that Ymir add a NAT gateway (~$32/month) to your network. Would you like to proceed? <fg=default>(Answering "<comment>no</comment>" will cancel the command.)</> ' )) {
76+ throw new CommandCancelledException ();
6977 }
7078
7179 $ database = $ this ->apiClient ->createDatabaseServer ($ name , (int ) $ network ['id ' ], $ type , $ storage , $ public );
@@ -75,7 +83,7 @@ protected function perform(InputInterface $input, OutputInterface $output)
7583
7684 $ output ->horizontalTable (
7785 ['Database Sever ' , new TableSeparator (), 'Username ' , 'Password ' , new TableSeparator (), 'Type ' , 'Public ' , 'Storage (in GB) ' ],
78- [[$ database ['name ' ], new TableSeparator (), $ database ['username ' ], $ database ['password ' ], new TableSeparator (), $ database ['type ' ], $ output ->formatBoolean ($ database ['publicly_accessible ' ]), $ database ['storage ' ]]]
86+ [[$ database ['name ' ], new TableSeparator (), $ database ['username ' ], $ database ['password ' ], new TableSeparator (), $ database ['type ' ], $ output ->formatBoolean ($ database ['publicly_accessible ' ]), $ database ['storage ' ] ?? ' N/A ' ]]
7987 );
8088
8189 $ output ->infoWithDelayWarning ('Database server created ' );
@@ -118,16 +126,14 @@ private function determineStorage(InputInterface $input, OutputInterface $output
118126 /**
119127 * Determine the database server type to create.
120128 */
121- private function determineType (Collection $ network , InputInterface $ input , OutputInterface $ output ): string
129+ private function determineType (InputInterface $ input , OutputInterface $ output, int $ providerId ): string
122130 {
123- if (!isset ($ network ['provider ' ]['id ' ])) {
124- throw new RuntimeException ('The Ymir API failed to return information on the cloud provider ' );
125- }
126-
127- $ type = $ this ->getStringOption ($ input , 'type ' );
128- $ types = $ this ->apiClient ->getDatabaseServerTypes ((int ) $ network ['provider ' ]['id ' ]);
131+ $ type = !$ this ->getBooleanOption ($ input , 'serverless ' ) ? $ this ->getStringOption ($ input , 'type ' ) : 'aurora-mysql ' ;
132+ $ types = $ this ->apiClient ->getDatabaseServerTypes ($ providerId );
129133
130- if (null !== $ type && !$ types ->has ($ type )) {
134+ if ($ types ->isEmpty ()) {
135+ throw new RuntimeException ('The Ymir API failed to return database server types ' );
136+ } elseif (null !== $ type && !$ types ->has ($ type )) {
131137 throw new InvalidArgumentException (sprintf ('The type "%s" isn \'t a valid database type ' , $ type ));
132138 } elseif (null === $ type ) {
133139 $ type = (string ) $ output ->choice ('What should the database server type be? ' , $ types );
0 commit comments