Skip to content

Commit

Permalink
Merge pull request #132 from renoki-co/fix/macro-call-for-crds
Browse files Browse the repository at this point in the history
[fix] Macro calls are not pulling CRDs from YAML
  • Loading branch information
rennokki authored Sep 15, 2021
2 parents 7fa9598 + 9d87f93 commit 221ea94
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 3 deletions.
27 changes: 26 additions & 1 deletion src/K8s.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Closure;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;
use RenokiCo\PhpK8s\Kinds\K8sResource;
use RenokiCo\PhpK8s\Traits\InitializesInstances;
use RenokiCo\PhpK8s\Traits\InitializesResources;

Expand All @@ -28,10 +29,17 @@ public static function fromYaml($cluster, string $yaml)
{
$instances = collect(yaml_parse($yaml, -1))->reduce(function ($classes, $yaml) use ($cluster) {
$kind = $yaml['kind'];
$apiVersion = $yaml['apiVersion'];

unset($yaml['apiVersion'], $yaml['kind']);

$classes[] = static::{$kind}($cluster, $yaml);
if (static::hasMacro($macro = K8sResource::getUniqueCrdMacro($kind, $apiVersion))) {
$classes[] = static::{$macro}($cluster, $yaml);
}

if (method_exists(static::class, $kind)) {
$classes[] = static::{$kind}($cluster, $yaml);
}

return $classes;
}, []);
Expand Down Expand Up @@ -97,6 +105,23 @@ function ($cluster = null, array $attributes = []) use ($class) {
return new $class($cluster, $attributes);
}
);

static::macro(
$class::getUniqueCrdMacro(),
function ($cluster = null, array $attributes = []) use ($class) {
return new $class($cluster, $attributes);
}
);
}

/**
* Flush the macros.
*
* @return void
*/
public static function flushMacros(): void
{
static::$macros = [];
}

/**
Expand Down
29 changes: 29 additions & 0 deletions src/Kinds/K8sResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use RenokiCo\PhpK8s\Exceptions\KubernetesAPIException;
use RenokiCo\PhpK8s\K8s;
use RenokiCo\PhpK8s\KubernetesCluster;
use RenokiCo\PhpK8s\Traits\Resource\HasAnnotations;
use RenokiCo\PhpK8s\Traits\Resource\HasAttributes;
Expand Down Expand Up @@ -48,6 +49,34 @@ public function __construct($cluster = null, array $attributes = [])
}
}

/**
* Register the current resource in macros.
*
* @param string|null $name
* @return void
*/
public static function register(string $name = null): void
{
K8s::registerCrd(static::class, $name);
}

/**
* This method should be used only for CRDs.
* It returns an internal macro name to help transition from YAML to resource
* when importing YAML.
*
* @param string|null $kind
* @param string|null $defaultVersion
* @return string
*/
public static function getUniqueCrdMacro(string $kind = null, string $defaultVersion = null): string
{
$kind = $kind ?: static::getKind();
$defaultVersion = $defaultVersion ?: static::getDefaultVersion();

return Str::of($kind.explode('/', $defaultVersion)[0])->camel()->slug();
}

/**
* Get the plural resource name.
*
Expand Down
1 change: 1 addition & 0 deletions src/KubernetesCluster.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
* @method \RenokiCo\PhpK8s\Kinds\K8sResource|array[\RenokiCo\PhpK8s\Kinds\K8sResource] fromYaml(string $yaml)
* @method \RenokiCo\PhpK8s\Kinds\K8sResource|array[\RenokiCo\PhpK8s\Kinds\K8sResource] fromYamlFile(string $path, \Closure $callback = null)
* @method \RenokiCo\PhpK8s\Kinds\K8sResource|array[\RenokiCo\PhpK8s\Kinds\K8sResource] fromTemplatedYamlFile(string $path, array $replace, \Closure $callback = null)
* @method static void registerCrd(string $class, string $name = null)
*
* @see \RenokiCo\PhpK8s\K8s
*/
Expand Down
10 changes: 10 additions & 0 deletions src/Traits/Resource/HasVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ public static function setDefaultVersion(string $version)
static::$defaultVersion = $version;
}

/**
* Get the default version of the resource.
*
* @return string
*/
public static function getDefaultVersion(): string
{
return static::$defaultVersion;
}

/**
* Get the API version of the resource.
* This function can be overwritten at the resource
Expand Down
30 changes: 30 additions & 0 deletions tests/Kinds/IstioGateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace RenokiCo\PhpK8s\Test\Kinds;

use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
use RenokiCo\PhpK8s\Kinds\K8sResource;

class IstioGateway extends K8sResource implements InteractsWithK8sCluster
{
/**
* The resource Kind parameter.
*
* @var null|string
*/
protected static $kind = 'Gateway';

/**
* The default version for the resource.
*
* @var string
*/
protected static $defaultVersion = 'networking.istio.io/v1beta1';

/**
* Wether the resource has a namespace.
*
* @var bool
*/
protected static $namespaceable = true;
}
30 changes: 30 additions & 0 deletions tests/Kinds/IstioGatewayNoNamespacedVersion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace RenokiCo\PhpK8s\Test\Kinds;

use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
use RenokiCo\PhpK8s\Kinds\K8sResource;

class IstioGatewayNoNamespacedVersion extends K8sResource implements InteractsWithK8sCluster
{
/**
* The resource Kind parameter.
*
* @var null|string
*/
protected static $kind = 'Gateway';

/**
* The default version for the resource.
*
* @var string
*/
protected static $defaultVersion = 'v100';

/**
* Wether the resource has a namespace.
*
* @var bool
*/
protected static $namespaceable = true;
}
4 changes: 2 additions & 2 deletions tests/MacroTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public function test_resource_macro()

public function test_k8s_macro()
{
K8s::registerCrd(Kinds\NewResource::class);
K8s::registerCrd(Kinds\NewResource::class, 'nr');
Kinds\NewResource::register();
Kinds\NewResource::register('nr');

$this->assertInstanceOf(Kinds\NewResource::class, K8s::newResource());
$this->assertInstanceOf(Kinds\NewResource::class, (new K8s)->newResource());
Expand Down
3 changes: 3 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Orchestra\Testbench\TestCase as Orchestra;
use RenokiCo\PhpK8s\Exceptions\PhpK8sException;
use RenokiCo\PhpK8s\K8s;
use RenokiCo\PhpK8s\KubernetesCluster;

abstract class TestCase extends Orchestra
Expand Down Expand Up @@ -34,6 +35,8 @@ public function setUp(): void
dump($exception->getMessage());
}
});

K8s::flushMacros();
}

/**
Expand Down
86 changes: 86 additions & 0 deletions tests/YamlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace RenokiCo\PhpK8s\Test;

use RenokiCo\PhpK8s\Test\Kinds\IstioGateway;
use RenokiCo\PhpK8s\Test\Kinds\IstioGatewayNoNamespacedVersion;

class YamlTest extends TestCase
{
public function test_yaml_import_multiple_kinds_in_same_file()
Expand Down Expand Up @@ -44,4 +47,87 @@ public function test_yaml_template()
$this->assertEquals('settings', $cm->getName());
$this->assertEquals(['key' => 'assigned_value_at_template'], $cm->getData());
}

public function test_yaml_import_for_crds()
{
IstioGateway::register();

$gatewayYaml = $this->arrayToYaml(
$this->cluster
->istioGateway()
->setName('test-gateway')
->setNamespace('renoki-test')
->setSpec([
'selector' => [
'istio' => 'ingressgateway',
],
'servers' => [
[
'hosts' => 'test.gateway.io',
'port' => [
'name' => 'https',
'number' => 443,
'protocol' => 'HTTPS',
],
'tls' => [
'credentialName' => 'kcertificate',
'mode' => 'SIMPLE',
],
],
],
])
->toArray()
);

$gateway = $this->cluster->fromYaml($gatewayYaml);

$this->assertInstanceOf(IstioGateway::class, $gateway);
}

public function test_yaml_import_for_crds_without_namespace()
{
IstioGatewayNoNamespacedVersion::register('istioGateway');

$gatewayYaml = $this->arrayToYaml(
$this->cluster
->istioGateway()
->setName('test-gateway')
->setNamespace('renoki-test')
->setSpec([
'selector' => [
'istio' => 'ingressgateway',
],
'servers' => [
[
'hosts' => 'test.gateway.io',
'port' => [
'name' => 'https',
'number' => 443,
'protocol' => 'HTTPS',
],
'tls' => [
'credentialName' => 'kcertificate',
'mode' => 'SIMPLE',
],
],
],
])
->toArray()
);

$gateway = $this->cluster->fromYaml($gatewayYaml);

$this->assertInstanceOf(IstioGatewayNoNamespacedVersion::class, $gateway);
}

/**
* Transform array to YAML content.
*
* @param array $arr
* @return string
*/
protected function arrayToYaml(array $arr)
{
return str_replace("---\n", '', yaml_emit($arr));
}
}

0 comments on commit 221ea94

Please sign in to comment.