From 3698d3a088907286e2de2357525dadacb4500ff6 Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Wed, 15 Sep 2021 13:44:25 +0300 Subject: [PATCH 1/5] Added ::register() for K8sResources to register CRDs easier --- src/Kinds/K8sResource.php | 12 ++++++++++++ tests/MacroTest.php | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Kinds/K8sResource.php b/src/Kinds/K8sResource.php index f1c3f00b..59931e65 100644 --- a/src/Kinds/K8sResource.php +++ b/src/Kinds/K8sResource.php @@ -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; @@ -48,6 +49,17 @@ 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); + } + /** * Get the plural resource name. * diff --git a/tests/MacroTest.php b/tests/MacroTest.php index 93bac72f..690ea647 100644 --- a/tests/MacroTest.php +++ b/tests/MacroTest.php @@ -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()); From 2fdc8a0f185c1899d5ba924920f95d34d5c89e6b Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Wed, 15 Sep 2021 13:44:47 +0300 Subject: [PATCH 2/5] Added missing registerCrd() --- src/KubernetesCluster.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KubernetesCluster.php b/src/KubernetesCluster.php index 19fbfc13..9c11a778 100644 --- a/src/KubernetesCluster.php +++ b/src/KubernetesCluster.php @@ -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 */ From d3547833060ca39cf90b177b60d33f1fd8f2753e Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Wed, 15 Sep 2021 14:12:33 +0300 Subject: [PATCH 3/5] Added unique macro to CRDs so they can be pulled from YAML --- src/K8s.php | 17 +++- src/Kinds/K8sResource.php | 17 ++++ src/Traits/Resource/HasVersion.php | 10 +++ tests/Kinds/IstioGateway.php | 30 +++++++ .../Kinds/IstioGatewayNoNamespacedVersion.php | 30 +++++++ tests/YamlTest.php | 86 +++++++++++++++++++ 6 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 tests/Kinds/IstioGateway.php create mode 100644 tests/Kinds/IstioGatewayNoNamespacedVersion.php diff --git a/src/K8s.php b/src/K8s.php index 6ec6b979..ce75c9bb 100644 --- a/src/K8s.php +++ b/src/K8s.php @@ -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; @@ -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; }, []); @@ -97,6 +105,13 @@ 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); + } + ); } /** diff --git a/src/Kinds/K8sResource.php b/src/Kinds/K8sResource.php index 59931e65..f560bb26 100644 --- a/src/Kinds/K8sResource.php +++ b/src/Kinds/K8sResource.php @@ -60,6 +60,23 @@ 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. * diff --git a/src/Traits/Resource/HasVersion.php b/src/Traits/Resource/HasVersion.php index 302b7eff..db1f025b 100644 --- a/src/Traits/Resource/HasVersion.php +++ b/src/Traits/Resource/HasVersion.php @@ -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 diff --git a/tests/Kinds/IstioGateway.php b/tests/Kinds/IstioGateway.php new file mode 100644 index 00000000..54feaee9 --- /dev/null +++ b/tests/Kinds/IstioGateway.php @@ -0,0 +1,30 @@ +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)); + } } From 7405df7b4e974f770d26afec06f400edbc1f73d1 Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Wed, 15 Sep 2021 14:15:15 +0300 Subject: [PATCH 4/5] csfixing --- tests/YamlTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/YamlTest.php b/tests/YamlTest.php index 15e7872e..85b07418 100644 --- a/tests/YamlTest.php +++ b/tests/YamlTest.php @@ -128,6 +128,6 @@ public function test_yaml_import_for_crds_without_namespace() */ protected function arrayToYaml(array $arr) { - return str_replace("---\n", "", yaml_emit($arr)); + return str_replace("---\n", '', yaml_emit($arr)); } } From 9d87f9376f0eaa0192c5308b5b38966eecdd1beb Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Wed, 15 Sep 2021 14:32:40 +0300 Subject: [PATCH 5/5] Flush macros between tests --- src/K8s.php | 10 ++++++++++ tests/TestCase.php | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/K8s.php b/src/K8s.php index ce75c9bb..48691157 100644 --- a/src/K8s.php +++ b/src/K8s.php @@ -114,6 +114,16 @@ function ($cluster = null, array $attributes = []) use ($class) { ); } + /** + * Flush the macros. + * + * @return void + */ + public static function flushMacros(): void + { + static::$macros = []; + } + /** * Proxy the K8s call to cluster object. * diff --git a/tests/TestCase.php b/tests/TestCase.php index 397d0cd7..5cf00c4a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -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 @@ -34,6 +35,8 @@ public function setUp(): void dump($exception->getMessage()); } }); + + K8s::flushMacros(); } /**