Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a new kubectl transport #60

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

### Unreleased

* Support kubectl transport (#60)

### 4.1.3 / 4.1.2 - 2022/Jan/18

* Support symfony/process ^5 via illicit access to a private member (#58)
Expand Down
28 changes: 28 additions & 0 deletions src/Factory/KubectlTransportFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Consolidation\SiteProcess\Factory;

use Consolidation\SiteAlias\SiteAliasInterface;
use Consolidation\SiteProcess\Transport\KubectlTransport;

/**
* KubectlTransportFactory will create an KubectlTransport for applicable site aliases.
*/
class KubectlTransportFactory implements TransportFactoryInterface
{
/**
* @inheritdoc
*/
public function check(SiteAliasInterface $siteAlias)
{
return $siteAlias->has('kubectl');
}

/**
* @inheritdoc
*/
public function create(SiteAliasInterface $siteAlias)
{
return new KubectlTransport($siteAlias);
}
}
2 changes: 2 additions & 0 deletions src/ProcessManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Consolidation\SiteProcess;

use Consolidation\SiteProcess\Factory\KubectlTransportFactory;
use Consolidation\SiteProcess\Factory\VagrantTransportFactory;
use Psr\Log\LoggerInterface;
use Consolidation\SiteAlias\SiteAliasInterface;
Expand Down Expand Up @@ -68,6 +69,7 @@ public static function createDefault()
public static function addTransports(ProcessManager $processManager)
{
$processManager->add(new SshTransportFactory());
$processManager->add(new KubectlTransportFactory());
$processManager->add(new DockerComposeTransportFactory());
$processManager->add(new VagrantTransportFactory());

Expand Down
76 changes: 76 additions & 0 deletions src/Transport/KubectlTransport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Consolidation\SiteProcess\Transport;

use Consolidation\SiteProcess\SiteProcess;
use Consolidation\SiteAlias\SiteAliasInterface;
use Consolidation\SiteProcess\Util\Shell;

/**
* KubectlTransport knows how to wrap a command such that it runs in a container
* on Kubernetes via kubectl.
*/
class KubectlTransport implements TransportInterface
{
/** @var bool */
protected $tty;

/** @var \Consolidation\SiteAlias\SiteAliasInterface */
protected $siteAlias;

public function __construct(SiteAliasInterface $siteAlias)
{
$this->siteAlias = $siteAlias;
}

/**
* @inheritdoc
*/
public function configure(SiteProcess $process)
{
$this->tty = $process->isTty();
}

/**
* inheritdoc
*/
public function wrap($args)
{
# TODO: How/where do we complain if a required argument is not available?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@greg-1-anderson How/where do we complain if a required argument in is not available in the site alias? Is there a "standard" way (e.g. a specific custom exception that should be thrown) in this repo?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing an exception would be best; however, at the moment, this library does not provide any custom exception types. You could provide one, if you wanted, or maybe just use InvalidArgumentException. Maybe that's just similar enough to be confusing, though. Recommendations welcome.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would leave the TODO there, merge it, and make a new issue to address the need for custom exceptions. It needs to be designed well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#62

$namespace = $this->siteAlias->get('kubectl.namespace');
$tty = $this->tty && $this->siteAlias->get('kubectl.tty', false) ? "true" : "false";
$interactive = $this->tty && $this->siteAlias->get('kubectl.interactive', false) ? "true" : "false";
$resource = $this->siteAlias->get('kubectl.resource');
$container = $this->siteAlias->get('kubectl.container');

$transport = [
'kubectl',
"--namespace=$namespace",
'exec',
"--tty=$tty",
"--stdin=$interactive",
$resource,
];
if ($container) {
$transport[] = "--container=$container";
}
$transport[] = "--";

return array_merge($transport, $args);
}

/**
* @inheritdoc
*/
public function addChdir($cd_remote, $args)
{
return array_merge(
[
'cd',
$cd_remote,
Shell::op('&&'),
],
$args
);
}
}
4 changes: 2 additions & 2 deletions src/Transport/TransportInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
use Consolidation\SiteProcess\SiteProcess;

/**
* SshTransport knows how to wrap a command such that it runs on a remote
* system via the ssh cli.
* Transports know how to wrap a command such that it runs on a remote system
* via some other command.
*
* There is always a transport for every factory, and visa-versa.
*
Expand Down
68 changes: 68 additions & 0 deletions tests/Transport/KubectlTransportTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Consolidation\SiteProcess;

use Consolidation\SiteProcess\Transport\KubectlTransport;
use PHPUnit\Framework\TestCase;
use Consolidation\SiteAlias\SiteAlias;

class KubectlTransportTest extends TestCase
{
/**
* Data provider for testWrap.
*/
public function wrapTestValues()
{
return [
// Everything explicit.
[
'kubectl --namespace=vv exec --tty=false --stdin=false deploy/drupal --container=drupal -- ls',
['ls'],
[
'kubectl' => [
'tty' => false,
'interactive' => false,
'namespace' => 'vv',
'resource' => 'deploy/drupal',
'container' => 'drupal',
]
],
],

// Minimal. Kubectl will pick a container.
[
'kubectl --namespace=vv exec --tty=false --stdin=false deploy/drupal -- ls',
['ls'],
[
'kubectl' => [
'namespace' => 'vv',
'resource' => 'deploy/drupal',
]
],
],

// Don't escape arguments after "--"
[
'kubectl --namespace=vv exec --tty=false --stdin=false deploy/drupal -- asdf "double" \'single\'',
['asdf', '"double"', "'single'"],
[
'kubectl' => [
'namespace' => 'vv',
'resource' => 'deploy/drupal',
]
],
],
];
}

/**
* @dataProvider wrapTestValues
*/
public function testWrap($expected, $args, $siteAliasData)
{
$siteAlias = new SiteAlias($siteAliasData, '@alias.dev');
$dockerTransport = new KubectlTransport($siteAlias);
$actual = $dockerTransport->wrap($args);
$this->assertEquals($expected, implode(' ', $actual));
}
}