Skip to content

Commit

Permalink
Merge pull request #117 from dunglas/feat/kubeconfigFactory
Browse files Browse the repository at this point in the history
feat: add a factory to create an instance from the current kubeconfig files
  • Loading branch information
rennokki authored Sep 5, 2021
2 parents 46e981e + af14f58 commit ce9b9cc
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/Traits/Cluster/LoadsFromKubeConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace RenokiCo\PhpK8s\Traits\Cluster;

use Exception;
use Illuminate\Support\Arr;
use RenokiCo\PhpK8s\Exceptions\KubeConfigClusterNotFound;
use RenokiCo\PhpK8s\Exceptions\KubeConfigContextNotFound;
use RenokiCo\PhpK8s\Exceptions\KubeConfigUserNotFound;
Expand Down Expand Up @@ -30,6 +31,44 @@ public static function setTempFolder(string $tempFolder)
static::$tempFolder = $tempFolder;
}

/**
* Loads the configuration fro the KubernetesCluster instance
* according to the current KUBECONFIG environment variable.
*
* @param string|null $context
* @return $this
* @throws \RenokiCo\PhpK8s\Exceptions\KubeConfigClusterNotFound
* @throws \RenokiCo\PhpK8s\Exceptions\KubeConfigContextNotFound
* @throws \RenokiCo\PhpK8s\Exceptions\KubeConfigUserNotFound
*/
public function fromKubeConfigVariable(string $context = null)
{
if (! isset($_SERVER['KUBECONFIG'])) {
return $this;
}

$paths = array_unique(explode(':', $_SERVER['KUBECONFIG']));
$kubeconfig = [];

foreach ($paths as $path) {
if (! @is_readable($path) || ($yaml = yaml_parse_file($path)) === false) {
continue;
}

$kubeconfig = static::mergeKubeconfigContents($kubeconfig, $yaml);
}

if ($kubeconfig === []) {
return $this;
}

if (! $context && isset($kubeconfig['current-context'])) {
$context = $kubeconfig['current-context'];
}

$this->loadKubeConfigFromArray($kubeconfig, $context);
}

/**
* Load configuration from a Kube Config context.
*
Expand Down Expand Up @@ -154,4 +193,30 @@ protected function writeTempFileForContext(string $context, string $fileName, st

return $tempFilePath;
}

/**
* Merge the two kubeconfig contents.
*
* @param array $kubeconfig1
* @param array $kubeconfig2
* @return array
*/
protected static function mergeKubeconfigContents(array $kubeconfig1, array $kubeconfig2): array
{
$kubeconfig1 += $kubeconfig2;

foreach ($kubeconfig1 as $key => $value) {
if (
is_array($value) &&
isset($kubeconfig2[$key]) &&
is_array($kubeconfig2[$key]) &&
! Arr::isAssoc($value) &&
! Arr::isAssoc($kubeconfig2[$key])
) {
$kubeconfig1[$key] = array_merge($kubeconfig1[$key], $kubeconfig2[$key]);
}
}

return $kubeconfig1;
}
}
31 changes: 31 additions & 0 deletions tests/KubeConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ public function setUp(): void
KubernetesCluster::setTempFolder(__DIR__.DIRECTORY_SEPARATOR.'temp');
}

/**
* {@inheritDoc}
*/
public function tearDown(): void
{
parent::tearDown();

unset($_SERVER['KUBECONFIG']);
}

public function test_kube_config_from_yaml_file_with_base64_encoded_ssl()
{
$cluster = new KubernetesCluster('http://127.0.0.1:8080');
Expand Down Expand Up @@ -187,4 +197,25 @@ public function test_in_cluster_config()

K8sResource::setDefaultNamespace('default');
}

/**
* @dataProvider environmentVariableContextProvider
*/
public function test_from_environment_variable(string $context = null, string $expectedDomain)
{
$_SERVER['KUBECONFIG'] = __DIR__.'/cluster/kubeconfig.yaml::'.__DIR__.'/cluster/kubeconfig-2.yaml';

$cluster = new KubernetesCluster("https://{$expectedDomain}:8443");

$cluster->fromKubeConfigVariable($context);

$this->assertSame("https://{$expectedDomain}:8443/?", $cluster->getCallableUrl('/', []));
}

public function environmentVariableContextProvider(): iterable
{
yield [null, 'minikube'];
yield ['minikube-2', 'minikube-2'];
yield ['minikube-3', 'minikube-3'];
}
}
10 changes: 10 additions & 0 deletions tests/cluster/kubeconfig-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
clusters:
- cluster:
certificate-authority-data: c29tZS1jYQo= # "some-ca"
server: https://minikube-3:8443
name: minikube-3
contexts:
- context:
cluster: minikube-3
user: minikube
name: minikube-3

0 comments on commit ce9b9cc

Please sign in to comment.