kube_cluster 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bundler/setup"
4
+ require "kube/cluster"
3
5
  require "tempfile"
4
6
  require "yaml"
5
7
 
@@ -148,7 +150,7 @@ module Kube
148
150
  ver = version_flag
149
151
  release_name = name || "crds"
150
152
 
151
- cmd = helm.call { template.(release_name).(source_ref).include_crds(true) }
153
+ cmd = helm.call { template.(release_name).(source_ref).include_crds(true) }
152
154
  cmd = cmd.version(ver) if ver
153
155
  cmd = cmd.set("installCRDs=true")
154
156
 
@@ -201,3 +203,412 @@ module Kube
201
203
  end
202
204
  end
203
205
  end
206
+
207
+ test do
208
+ # ── initialization ────────────────────────────────────────────────────
209
+
210
+ it "initializes_with_data_hash" do
211
+ chart = Kube::Helm::Chart.new({ "name" => "my-app", "version" => "1.0.0", "appVersion" => "2.5.0" })
212
+ chart.name.should == "my-app"
213
+ end
214
+
215
+ it "initializes_with_block" do
216
+ chart = Kube::Helm::Chart.new {
217
+ self.name = "my-app"
218
+ self.version = "1.0.0"
219
+ self.appVersion = "2.5.0"
220
+ self.description = "A test chart"
221
+ }
222
+
223
+ chart.description.should == "A test chart"
224
+ end
225
+
226
+ it "initializes_empty" do
227
+ chart = Kube::Helm::Chart.new
228
+ chart.dependencies.should == []
229
+ end
230
+
231
+ it "initializes_with_path" do
232
+ chart = Kube::Helm::Chart.new({ "name" => "x" }, path: "/tmp/charts/x")
233
+ chart.path.should == "/tmp/charts/x"
234
+ end
235
+
236
+ it "initializes_with_cluster" do
237
+ cluster = Kube::Cluster.connect(kubeconfig: "/tmp/test-kubeconfig")
238
+ chart = Kube::Helm::Chart.new({ "name" => "x" }, cluster: cluster)
239
+ chart.cluster.should == cluster
240
+ end
241
+
242
+ # ── Chart.open ───────────────────────────────────────────────────────
243
+
244
+ it "open_reads_chart_yaml" do
245
+ Dir.mktmpdir do |dir|
246
+ File.write(File.join(dir, "Chart.yaml"), {
247
+ "name" => "test-chart",
248
+ "version" => "0.1.0",
249
+ "appVersion" => "1.0.0",
250
+ "description" => "A test chart",
251
+ "type" => "application",
252
+ }.to_yaml)
253
+
254
+ chart = Kube::Helm::Chart.open(dir)
255
+ chart.name.should == "test-chart"
256
+ end
257
+ end
258
+
259
+ it "open_raises_without_chart_yaml" do
260
+ Dir.mktmpdir do |dir|
261
+ lambda { Kube::Helm::Chart.open(dir) }.should.raise Kube::Error
262
+ end
263
+ end
264
+
265
+ it "open_with_cluster" do
266
+ Dir.mktmpdir do |dir|
267
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "x", "version" => "1.0.0" }.to_yaml)
268
+ cluster = Kube::Cluster.connect(kubeconfig: "/tmp/test-kubeconfig")
269
+
270
+ chart = Kube::Helm::Chart.open(dir, cluster: cluster)
271
+ chart.cluster.should == cluster
272
+ end
273
+ end
274
+
275
+ # ── to_s ──────────────────────────────────────────────────────────────
276
+
277
+ it "to_s_with_version" do
278
+ chart = Kube::Helm::Chart.new({ "name" => "nginx", "version" => "18.1.0" })
279
+ chart.to_s.should == "nginx:18.1.0"
280
+ end
281
+
282
+ it "to_s_without_version" do
283
+ chart = Kube::Helm::Chart.new({ "name" => "nginx" })
284
+ chart.to_s.should == "nginx"
285
+ end
286
+
287
+ # ── apply_values ─────────────────────────────────────────────────────
288
+
289
+ it "apply_values_raises_without_source" do
290
+ chart = Kube::Helm::Chart.new({ "name" => "my-app" })
291
+ lambda { chart.apply_values({ "replicaCount" => 3 }) }.should.raise Kube::Error
292
+ end
293
+
294
+ it "apply_values_builds_correct_command" do
295
+ Dir.mktmpdir do |dir|
296
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
297
+ chart = Kube::Helm::Chart.open(dir)
298
+
299
+ captured_cmd = nil
300
+ stub_yaml = { "kind" => "Deployment", "apiVersion" => "apps/v1", "metadata" => { "name" => "web" } }.to_yaml
301
+
302
+ original = Kube::Helm.method(:run)
303
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
304
+ begin
305
+ chart.apply_values({ "replicaCount" => 3 })
306
+ ensure
307
+ Kube::Helm.define_singleton_method(:run, original)
308
+ end
309
+
310
+ captured_cmd.should.include dir
311
+ end
312
+ end
313
+
314
+ it "apply_values_with_custom_release" do
315
+ Dir.mktmpdir do |dir|
316
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
317
+ chart = Kube::Helm::Chart.open(dir)
318
+
319
+ captured_cmd = nil
320
+ stub_yaml = { "kind" => "Pod", "apiVersion" => "v1" }.to_yaml
321
+
322
+ original = Kube::Helm.method(:run)
323
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
324
+ begin
325
+ chart.apply_values({}, release: "custom-release")
326
+ ensure
327
+ Kube::Helm.define_singleton_method(:run, original)
328
+ end
329
+
330
+ captured_cmd.should.include "custom-release"
331
+ end
332
+ end
333
+
334
+ it "apply_values_with_namespace" do
335
+ Dir.mktmpdir do |dir|
336
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
337
+ chart = Kube::Helm::Chart.open(dir)
338
+
339
+ captured_cmd = nil
340
+ stub_yaml = { "kind" => "Pod", "apiVersion" => "v1" }.to_yaml
341
+
342
+ original = Kube::Helm.method(:run)
343
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
344
+ begin
345
+ chart.apply_values({}, namespace: "production")
346
+ ensure
347
+ Kube::Helm.define_singleton_method(:run, original)
348
+ end
349
+
350
+ captured_cmd.should.include "--namespace=production"
351
+ end
352
+ end
353
+
354
+ it "apply_values_returns_manifest" do
355
+ Dir.mktmpdir do |dir|
356
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
357
+ chart = Kube::Helm::Chart.open(dir)
358
+
359
+ stub_yaml = [
360
+ { "kind" => "Deployment", "apiVersion" => "apps/v1", "metadata" => { "name" => "web" } },
361
+ { "kind" => "Service", "apiVersion" => "v1", "metadata" => { "name" => "web" } },
362
+ ].map(&:to_yaml).join("")
363
+
364
+ original = Kube::Helm.method(:run)
365
+ Kube::Helm.define_singleton_method(:run) { |_cmd| stub_yaml }
366
+ begin
367
+ result = chart.apply_values({ "replicaCount" => 3 })
368
+ ensure
369
+ Kube::Helm.define_singleton_method(:run, original)
370
+ end
371
+
372
+ result.should.be.instance_of Kube::Schema::Manifest
373
+ end
374
+ end
375
+
376
+ it "apply_values_defaults_release_to_chart_name" do
377
+ Dir.mktmpdir do |dir|
378
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "nginx", "version" => "1.0.0" }.to_yaml)
379
+ chart = Kube::Helm::Chart.open(dir)
380
+
381
+ captured_cmd = nil
382
+ stub_yaml = { "kind" => "Pod", "apiVersion" => "v1" }.to_yaml
383
+
384
+ original = Kube::Helm.method(:run)
385
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
386
+ begin
387
+ chart.apply_values({})
388
+ ensure
389
+ Kube::Helm.define_singleton_method(:run, original)
390
+ end
391
+
392
+ captured_cmd.should.include "nginx"
393
+ end
394
+ end
395
+
396
+ # ── show_values ──────────────────────────────────────────────────────
397
+
398
+ it "show_values" do
399
+ Dir.mktmpdir do |dir|
400
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
401
+ chart = Kube::Helm::Chart.open(dir)
402
+
403
+ captured_cmd = nil
404
+ stub_yaml = { "replicaCount" => 1, "service" => { "type" => "ClusterIP" } }.to_yaml
405
+
406
+ original = Kube::Helm.method(:run)
407
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
408
+ begin
409
+ result = chart.show_values
410
+ result["replicaCount"].should == 1
411
+ ensure
412
+ Kube::Helm.define_singleton_method(:run, original)
413
+ end
414
+ end
415
+ end
416
+
417
+ it "show_values_raises_without_source" do
418
+ chart = Kube::Helm::Chart.new({ "name" => "my-app" })
419
+ lambda { chart.show_values }.should.raise Kube::Error
420
+ end
421
+
422
+ # ── crds ─────────────────────────────────────────────────────────────
423
+
424
+ it "crds_returns_custom_resource_definition_objects" do
425
+ Dir.mktmpdir do |dir|
426
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "cert-manager", "version" => "1.0.0" }.to_yaml)
427
+ chart = Kube::Helm::Chart.open(dir)
428
+
429
+ stub_yaml = [
430
+ { "kind" => "Deployment", "apiVersion" => "apps/v1", "metadata" => { "name" => "cm" } },
431
+ {
432
+ "kind" => "CustomResourceDefinition",
433
+ "apiVersion" => "apiextensions.k8s.io/v1",
434
+ "metadata" => { "name" => "clusterissuers.cert-manager.io" },
435
+ "spec" => {
436
+ "group" => "cert-manager.io",
437
+ "names" => { "kind" => "ClusterIssuer" },
438
+ "versions" => [
439
+ {
440
+ "name" => "v1",
441
+ "schema" => {
442
+ "openAPIV3Schema" => {
443
+ "type" => "object",
444
+ "properties" => { "spec" => { "type" => "object" } },
445
+ },
446
+ },
447
+ },
448
+ ],
449
+ },
450
+ },
451
+ ].map(&:to_yaml).join("")
452
+
453
+ original = Kube::Helm.method(:run)
454
+ Kube::Helm.define_singleton_method(:run) { |_cmd| stub_yaml }
455
+ begin
456
+ result = chart.crds
457
+ ensure
458
+ Kube::Helm.define_singleton_method(:run, original)
459
+ end
460
+
461
+ result.length.should == 1
462
+ end
463
+ end
464
+
465
+ it "crds_raises_without_source" do
466
+ chart = Kube::Helm::Chart.new({ "name" => "my-app" })
467
+ lambda { chart.crds }.should.raise Kube::Error
468
+ end
469
+
470
+ # ── cluster scoping ──────────────────────────────────────────────────
471
+
472
+ it "apply_values_uses_cluster_helm_instance" do
473
+ Dir.mktmpdir do |dir|
474
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
475
+ cluster = Kube::Cluster.connect(kubeconfig: "/tmp/test-kubeconfig")
476
+ chart = Kube::Helm::Chart.open(dir, cluster: cluster)
477
+
478
+ captured_cmd = nil
479
+ stub_yaml = { "kind" => "Pod", "apiVersion" => "v1" }.to_yaml
480
+
481
+ helm = cluster.connection.helm
482
+ original = helm.method(:run)
483
+ helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
484
+ begin
485
+ chart.apply_values({ "foo" => "bar" })
486
+ ensure
487
+ helm.define_singleton_method(:run, original)
488
+ end
489
+
490
+ captured_cmd.should.include "template"
491
+ end
492
+ end
493
+
494
+ it "show_values_uses_cluster_helm_instance" do
495
+ Dir.mktmpdir do |dir|
496
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
497
+ cluster = Kube::Cluster.connect(kubeconfig: "/tmp/test-kubeconfig")
498
+ chart = Kube::Helm::Chart.open(dir, cluster: cluster)
499
+
500
+ captured_cmd = nil
501
+ stub_yaml = { "replicaCount" => 1 }.to_yaml
502
+
503
+ helm = cluster.connection.helm
504
+ original = helm.method(:run)
505
+ helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
506
+ begin
507
+ chart.show_values
508
+ ensure
509
+ helm.define_singleton_method(:run, original)
510
+ end
511
+
512
+ captured_cmd.should.include "show"
513
+ end
514
+ end
515
+
516
+ # ── remote chart (ref-based) ─────────────────────────────────────────
517
+
518
+ it "initializes_with_ref" do
519
+ chart = Kube::Helm::Chart.new({ "name" => "nginx", "version" => "18.1.0" }, ref: "bitnami/nginx")
520
+ chart.ref.should == "bitnami/nginx"
521
+ end
522
+
523
+ it "apply_values_with_ref_uses_ref_and_version" do
524
+ chart = Kube::Helm::Chart.new(
525
+ { "name" => "nginx", "version" => "18.1.0" },
526
+ ref: "bitnami/nginx"
527
+ )
528
+
529
+ captured_cmd = nil
530
+ stub_yaml = { "kind" => "Deployment", "apiVersion" => "apps/v1", "metadata" => { "name" => "web" } }.to_yaml
531
+
532
+ original = Kube::Helm.method(:run)
533
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
534
+ begin
535
+ chart.apply_values({ "replicaCount" => 3 })
536
+ ensure
537
+ Kube::Helm.define_singleton_method(:run, original)
538
+ end
539
+
540
+ captured_cmd.should.include "--version=18.1.0"
541
+ end
542
+
543
+ it "apply_values_with_path_does_not_add_version_flag" do
544
+ Dir.mktmpdir do |dir|
545
+ File.write(File.join(dir, "Chart.yaml"), { "name" => "my-app", "version" => "1.0.0" }.to_yaml)
546
+ chart = Kube::Helm::Chart.open(dir)
547
+
548
+ captured_cmd = nil
549
+ stub_yaml = { "kind" => "Pod", "apiVersion" => "v1" }.to_yaml
550
+
551
+ original = Kube::Helm.method(:run)
552
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
553
+ begin
554
+ chart.apply_values({})
555
+ ensure
556
+ Kube::Helm.define_singleton_method(:run, original)
557
+ end
558
+
559
+ captured_cmd.should.not.include "--version"
560
+ end
561
+ end
562
+
563
+ it "show_values_with_ref" do
564
+ chart = Kube::Helm::Chart.new(
565
+ { "name" => "nginx", "version" => "18.1.0" },
566
+ ref: "bitnami/nginx"
567
+ )
568
+
569
+ captured_cmd = nil
570
+ stub_yaml = { "replicaCount" => 1 }.to_yaml
571
+
572
+ original = Kube::Helm.method(:run)
573
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
574
+ begin
575
+ chart.show_values
576
+ ensure
577
+ Kube::Helm.define_singleton_method(:run, original)
578
+ end
579
+
580
+ captured_cmd.should.include "--version=18.1.0"
581
+ end
582
+
583
+ it "crds_with_ref" do
584
+ chart = Kube::Helm::Chart.new(
585
+ { "name" => "cert-manager", "version" => "1.17.2" },
586
+ ref: "jetstack/cert-manager"
587
+ )
588
+
589
+ stub_yaml = [
590
+ {
591
+ "kind" => "CustomResourceDefinition",
592
+ "apiVersion" => "apiextensions.k8s.io/v1",
593
+ "metadata" => { "name" => "issuers.cert-manager.io" },
594
+ "spec" => {
595
+ "group" => "cert-manager.io",
596
+ "names" => { "kind" => "Issuer" },
597
+ "versions" => [
598
+ { "name" => "v1", "schema" => { "openAPIV3Schema" => { "type" => "object" } } },
599
+ ],
600
+ },
601
+ },
602
+ ].map(&:to_yaml).join("")
603
+
604
+ captured_cmd = nil
605
+ original = Kube::Helm.method(:run)
606
+ Kube::Helm.define_singleton_method(:run) { |cmd| captured_cmd = cmd; stub_yaml }
607
+ begin
608
+ result = chart.crds
609
+ result.length.should == 1
610
+ ensure
611
+ Kube::Helm.define_singleton_method(:run, original)
612
+ end
613
+ end
614
+ end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "bundler/setup"
4
+ require "kube/cluster"
5
+
3
6
  module Kube
4
7
  module Helm
5
8
  # Abstracts the differences between Helm chart sources.
@@ -73,3 +76,80 @@ module Kube
73
76
  end
74
77
  end
75
78
  end
79
+
80
+ test do
81
+ # ── OCI detection ──────────────────────────────────────────────────────
82
+
83
+ it "oci_endpoint_detected" do
84
+ endpoint = Kube::Helm::Endpoint.new("oci://ghcr.io/my-org/charts")
85
+ endpoint.oci?.should.be.true
86
+ end
87
+
88
+ it "http_endpoint_not_oci" do
89
+ endpoint = Kube::Helm::Endpoint.new("https://charts.bitnami.com/bitnami")
90
+ endpoint.oci?.should.be.false
91
+ end
92
+
93
+ # ── requires_add? ─────────────────────────────────────────────────────
94
+
95
+ it "oci_does_not_require_add" do
96
+ endpoint = Kube::Helm::Endpoint.new("oci://ghcr.io/my-org/charts")
97
+ endpoint.requires_add?.should.be.false
98
+ end
99
+
100
+ it "http_requires_add" do
101
+ endpoint = Kube::Helm::Endpoint.new("https://charts.bitnami.com/bitnami")
102
+ endpoint.requires_add?.should.be.true
103
+ end
104
+
105
+ # ── chart_ref ──────────────────────────────────────────────────────────
106
+
107
+ it "oci_chart_ref" do
108
+ endpoint = Kube::Helm::Endpoint.new("oci://ghcr.io/my-org/charts")
109
+ endpoint.chart_ref("nginx").should == "oci://ghcr.io/my-org/charts/nginx"
110
+ end
111
+
112
+ it "oci_chart_ref_strips_trailing_slash" do
113
+ endpoint = Kube::Helm::Endpoint.new("oci://ghcr.io/my-org/charts/")
114
+ endpoint.chart_ref("nginx").should == "oci://ghcr.io/my-org/charts/nginx"
115
+ end
116
+
117
+ it "http_chart_ref_with_repo_name" do
118
+ endpoint = Kube::Helm::Endpoint.new("https://charts.bitnami.com/bitnami")
119
+ endpoint.chart_ref("nginx", repo_name: "bitnami").should == "bitnami/nginx"
120
+ end
121
+
122
+ it "http_chart_ref_raises_without_repo_name" do
123
+ endpoint = Kube::Helm::Endpoint.new("https://charts.bitnami.com/bitnami")
124
+ lambda { endpoint.chart_ref("nginx") }.should.raise ArgumentError
125
+ end
126
+
127
+ # ── validation ─────────────────────────────────────────────────────────
128
+
129
+ it "raises_on_empty_url" do
130
+ lambda { Kube::Helm::Endpoint.new("") }.should.raise ArgumentError
131
+ end
132
+
133
+ it "raises_on_non_string_url" do
134
+ lambda { Kube::Helm::Endpoint.new(nil) }.should.raise ArgumentError
135
+ end
136
+
137
+ # ── to_s / equality ───────────────────────────────────────────────────
138
+
139
+ it "to_s_returns_url" do
140
+ endpoint = Kube::Helm::Endpoint.new("https://charts.example.com")
141
+ endpoint.to_s.should == "https://charts.example.com"
142
+ end
143
+
144
+ it "equality" do
145
+ a = Kube::Helm::Endpoint.new("https://charts.example.com")
146
+ b = Kube::Helm::Endpoint.new("https://charts.example.com")
147
+ a.should == b
148
+ end
149
+
150
+ it "inequality" do
151
+ a = Kube::Helm::Endpoint.new("https://charts.example.com")
152
+ b = Kube::Helm::Endpoint.new("oci://ghcr.io/my-org/charts")
153
+ a.should.not == b
154
+ end
155
+ end