Skip to content

Commit

Permalink
Merge pull request #46 from laravel/feat/improve-ssh-configure-command
Browse files Browse the repository at this point in the history
Improves `ssh:configure` command
  • Loading branch information
taylorotwell authored Nov 10, 2021
2 parents 855b150 + e5a2ad7 commit 51dd724
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
8 changes: 6 additions & 2 deletions app/Commands/SshConfigureCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public function handle()

$key = $this->getKey();

$this->ensureKeyExists($this->getKeyName($key), $key);
$privateKey = $this->ensureKeyExists($this->getKeyName($key), $key);

$this->callSilently('ssh:test', ['--key' => $privateKey]);

$this->successfulStep('SSH key based secure authentication configured successfully');
}
Expand All @@ -48,7 +50,7 @@ public function handle()
*
* @param string $name
* @param string|null $key
* @return void
* @return string
*/
protected function ensureKeyExists($name, $key = null)
{
Expand All @@ -65,6 +67,8 @@ protected function ensureKeyExists($name, $key = null)
$this->step('Adding Key <comment>['.$localName.']</comment>'.' With The Name <comment>['.$name.']</comment> To Server <comment>['.$server->name.']</comment>');

$this->forge->createSSHKey($server->id, ['key' => $key, 'name' => $name], true);

return $this->keys->keysPath().'/'.basename($localName, '.pub');
}

/**
Expand Down
9 changes: 8 additions & 1 deletion app/Commands/SshTestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class SshTestCommand extends Command
* @var string
*/
protected $signature = 'ssh:test
{server? : The server name}';
{server? : The server name}
{--key= : The path to the private key}';

/**
* The description of the command.
Expand All @@ -34,6 +35,12 @@ public function handle()

$this->step('Establishing secure connection');

if ($this->option('key')) {
$this->remote->resolvePrivateKeyUsing(function () {
return $this->option('key');
});
}

$this->remote->ensureSshIsConfigured();

$this->successfulStep('SSH key based secure authentication is configured');
Expand Down
27 changes: 26 additions & 1 deletion app/Repositories/RemoteRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

class RemoteRepository
{
/**
* The private key resolver.
*
* @var callable|null
*/
protected $privateKeyResolver = null;

/**
* The sockets path.
*
Expand Down Expand Up @@ -129,7 +136,18 @@ public function exec($command)
}

/**
* Sets the current server.
* Sets the current private key resolver.
*
* @param callable $resolver
* @return void
*/
public function resolvePrivateKeyUsing($resolver)
{
$this->privateKeyResolver = $resolver;
}

/**
* Sets the current server resolver.
*
* @param callable $resolver
* @return void
Expand Down Expand Up @@ -195,6 +213,13 @@ protected function ssh($command = null)
return "-o $option=$value";
})->values()->implode(' ');

if ($this->privateKeyResolver) {
$options .= sprintf(
' -o "IdentitiesOnly=yes" -i "%s"',
call_user_func($this->privateKeyResolver)
);
}

return trim(sprintf(
'ssh %s -t forge@%s %s',
$options,
Expand Down
6 changes: 6 additions & 0 deletions tests/Feature/SshConfigureCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
'key' => 'MY KEY Content',
], true)->once();

$this->remote->shouldReceive('resolvePrivateKeyUsing')->once();
$this->remote->shouldReceive('ensureSshIsConfigured')->once();

$this->artisan('ssh:configure')
->expectsQuestion('<fg=yellow>‣</> <options=bold>Which Server Would You Like To Configure The SSH Key Based Secure Authentication</>', 1)
->expectsQuestion('<fg=yellow>‣</> <options=bold>Which Key Would You Like To Use</>', 0)
Expand Down Expand Up @@ -77,6 +80,9 @@
'key' => 'MY KEY Content',
], true)->once();

$this->remote->shouldReceive('resolvePrivateKeyUsing')->once();
$this->remote->shouldReceive('ensureSshIsConfigured')->once();

$this->artisan('ssh:configure', ['server' => 2])
->expectsQuestion('<fg=yellow>‣</> <options=bold>Which Key Would You Like To Use</>', 1)
->expectsQuestion('<fg=yellow>‣</> <options=bold>What Should The SSH Key Be Named In Forge</>', 'driesvints')
Expand Down

0 comments on commit 51dd724

Please sign in to comment.