kube_cluster 0.20.1 → 1.0.0

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +34 -0
  4. data/Gemfile.lock +5 -37
  5. data/flake.nix +2 -1
  6. data/kube_cluster.gemspec +2 -4
  7. data/lib/kube/cluster/container.rb +17 -17
  8. data/lib/kube/cluster/manifest.rb +158 -158
  9. data/lib/kube/cluster/middleware/annotations.rb +42 -42
  10. data/lib/kube/cluster/middleware/hpa_for_deployment.rb +134 -134
  11. data/lib/kube/cluster/middleware/ingress_for_service.rb +75 -75
  12. data/lib/kube/cluster/middleware/labels.rb +58 -58
  13. data/lib/kube/cluster/middleware/pod_anti_affinity.rb +104 -104
  14. data/lib/kube/cluster/middleware/resource_preset.rb +145 -145
  15. data/lib/kube/cluster/middleware/security_context.rb +127 -127
  16. data/lib/kube/cluster/middleware/service_for_deployment.rb +120 -120
  17. data/lib/kube/cluster/middleware.rb +219 -221
  18. data/lib/kube/cluster/resource/dirty_tracking.rb +388 -388
  19. data/lib/kube/cluster/resource.rb +16 -16
  20. data/lib/kube/cluster/standard/cdi/data_volume.rb +13 -13
  21. data/lib/kube/cluster/standard/cloud_native_pg/cluster.rb +11 -11
  22. data/lib/kube/cluster/standard/cloud_native_pg/database_with_external_secret.rb +11 -11
  23. data/lib/kube/cluster/standard/cloud_native_pg/external_secret.rb +11 -11
  24. data/lib/kube/cluster/standard/cloud_native_pg/helm.rb +26 -26
  25. data/lib/kube/cluster/standard/config_map.rb +11 -11
  26. data/lib/kube/cluster/standard/cron_job.rb +13 -13
  27. data/lib/kube/cluster/standard/cron_job_with_service_account.rb +12 -12
  28. data/lib/kube/cluster/standard/custom_resource_definition.rb +12 -12
  29. data/lib/kube/cluster/standard/daemon_set.rb +12 -12
  30. data/lib/kube/cluster/standard/deployment_with_service.rb +82 -82
  31. data/lib/kube/cluster/standard/env_processing.rb +15 -15
  32. data/lib/kube/cluster/standard/eso/external_secret.rb +13 -13
  33. data/lib/kube/cluster/standard/forgejo/helm.rb +11 -11
  34. data/lib/kube/cluster/standard/gateway_api/http_route.rb +322 -19
  35. data/lib/kube/cluster/standard/job.rb +12 -12
  36. data/lib/kube/cluster/standard/job_with_service_account.rb +11 -11
  37. data/lib/kube/cluster/standard/kube_virt/virtual_machine.rb +11 -11
  38. data/lib/kube/cluster/standard/meta_controller/composite_controller.rb +13 -13
  39. data/lib/kube/cluster/standard/meta_controller/decorator_controller.rb +13 -13
  40. data/lib/kube/cluster/standard/perses/perses.rb +9 -9
  41. data/lib/kube/cluster/standard/perses/perses_datasource.rb +13 -13
  42. data/lib/kube/cluster/standard/persistent_volume_claim.rb +12 -12
  43. data/lib/kube/cluster/standard/role.rb +12 -12
  44. data/lib/kube/cluster/standard/role_binding.rb +10 -10
  45. data/lib/kube/cluster/standard/secret.rb +11 -11
  46. data/lib/kube/cluster/standard/service.rb +12 -12
  47. data/lib/kube/cluster/standard/service_account.rb +9 -9
  48. data/lib/kube/cluster/standard/service_account_with_role.rb +10 -10
  49. data/lib/kube/cluster/standard/victoria_metrics/vl_agent.rb +9 -9
  50. data/lib/kube/cluster/standard/victoria_metrics/vl_single.rb +9 -9
  51. data/lib/kube/cluster/standard/victoria_metrics/vm_agent.rb +9 -9
  52. data/lib/kube/cluster/standard/victoria_metrics/vm_node_scrape.rb +9 -9
  53. data/lib/kube/cluster/standard/victoria_metrics/vm_service_scrape.rb +9 -9
  54. data/lib/kube/cluster/standard/victoria_metrics/vm_single.rb +9 -9
  55. data/lib/kube/cluster/standard/volume_processing.rb +3 -3
  56. data/lib/kube/cluster/version.rb +1 -1
  57. data/lib/kube/cluster.rb +137 -1
  58. data/lib/kube/helm/chart.rb +323 -323
  59. data/lib/kube/helm/endpoint.rb +58 -58
  60. data/lib/kube/helm/repo.rb +160 -160
  61. metadata +7 -20
@@ -4,30 +4,333 @@ require "bundler/setup"
4
4
  require "kube/cluster"
5
5
 
6
6
  module Kube
7
- module Cluster
7
+ module Cluster
8
8
  module Standard
9
9
  module GatewayApi
10
- #class HTTPRoute < Kube::Cluster::Manifest
11
- #end
10
+ # A single-rule HTTPRoute attached to the cluster's one traefik-gateway.
11
+ #
12
+ # Every route in ns/ shares the same parentRefs (the `traefik-gateway`
13
+ # in kube-system) and differs only by listener section, host(s), the
14
+ # backing Service, the path matches, and an optional chain of traefik
15
+ # middlewares. This collapses that boilerplate to a keyword call.
16
+ #
17
+ # Deliberately models exactly ONE rule: one set of matches -> one
18
+ # backend (or a terminal redirect), with one filter chain. Routes that
19
+ # need distinct backends or filters per path (fanout) are expressed as
20
+ # several instances on the same host -- the gateway merges them and the
21
+ # more-specific match wins.
22
+ #
23
+ # Standard::GatewayApi::HTTPRoute.new(
24
+ # name: "sourcebot",
25
+ # gateway: "example-com-https",
26
+ # domains: ["sg.example.com"],
27
+ # service: { namespace: "sourcebot", name: "sourcebot", port: 3000 },
28
+ # middleware: "forwardauth-oauth2-proxy-example",
29
+ # )
30
+ #
31
+ # Many matches -> one backend (forgejo git smart-HTTP):
32
+ #
33
+ # Standard::GatewayApi::HTTPRoute.new(
34
+ # name: "forgejo-git", gateway: "example-net-https", domains: ["git.example.net"],
35
+ # regex: ["/.+/info/refs", "/.+/git-upload-pack", "/.+/git-receive-pack"],
36
+ # prefix: ["/api", "/v2"],
37
+ # service: { namespace: "default", name: "forgejo-http", port: 3000 },
38
+ # timeouts: { request: "600s", backendRequest: "600s" },
39
+ # )
40
+ #
41
+ # Terminal http->https redirect (the `-http` sibling):
42
+ #
43
+ # Standard::GatewayApi::HTTPRoute.new(
44
+ # name: "sourcebot-http", gateway: "example-com-http",
45
+ # domains: ["sg.example.com"], prefix: ["/"], redirect: true,
46
+ # )
47
+ class HTTPRoute < Kube::Cluster["HTTPRoute"]
48
+ GATEWAY_GROUP = "gateway.networking.k8s.io"
49
+ GATEWAY_NAME = "traefik-gateway"
50
+ GATEWAY_NS = "kube-system"
51
+
52
+ # traefik middlewares are attached to a rule via an ExtensionRef filter.
53
+ MIDDLEWARE_GROUP = "traefik.io"
54
+ MIDDLEWARE_KIND = "Middleware"
55
+
56
+ PATH_TYPES = {
57
+ prefix: "PathPrefix",
58
+ exact: "Exact",
59
+ regex: "RegularExpression",
60
+ }.freeze
61
+
62
+ def initialize(
63
+ name:,
64
+ gateway:,
65
+ domains:,
66
+ service: nil,
67
+ prefix: nil,
68
+ exact: nil,
69
+ regex: nil,
70
+ headers: nil,
71
+ middleware: nil,
72
+ redirect: nil,
73
+ header_modifier: nil,
74
+ timeouts: nil,
75
+ namespace: "kube-system",
76
+ &block
77
+ )
78
+ hostnames = Array(domains)
79
+ matches = _matches(prefix: prefix, exact: exact, regex: regex, headers: headers)
80
+ filters = _filters(middleware: middleware, redirect: redirect, header_modifier: header_modifier)
81
+
82
+ rule = { matches: matches }
83
+ rule[:filters] = filters unless filters.empty?
84
+ rule[:backendRefs] = [_backend(service)] if service
85
+ rule[:timeouts] = timeouts if timeouts
86
+
87
+ super() {
88
+ metadata.name = name
89
+ # A co-located route (namespace: nil) omits metadata.namespace so
90
+ # it lands in whatever namespace applies it; cross-namespace routes
91
+ # in kube-system set it explicitly.
92
+ metadata.namespace = namespace if namespace
93
+
94
+ spec.hostnames = hostnames
95
+ spec.parentRefs = [{
96
+ group: GATEWAY_GROUP,
97
+ kind: "Gateway",
98
+ name: GATEWAY_NAME,
99
+ namespace: GATEWAY_NS,
100
+ sectionName: gateway,
101
+ }]
102
+ spec.rules = [rule]
103
+
104
+ instance_exec(&block) if block_given?
105
+ }
106
+ end
107
+
108
+ private
109
+
110
+ # Build the rule's `matches`: one entry per path across the typed
111
+ # arrays, all sharing the single backend. A path match is mandatory --
112
+ # every route (including a redirect-only one) must state its path, so
113
+ # this raises rather than silently assuming `/` when none is given.
114
+ def _matches(prefix:, exact:, regex:, headers:)
115
+ entries = []
116
+ { prefix: prefix, exact: exact, regex: regex }.each do |kind, values|
117
+ Array(values).each do |value|
118
+ entries << { path: { type: PATH_TYPES.fetch(kind), value: value } }
119
+ end
120
+ end
121
+ if entries.empty?
122
+ raise ArgumentError,
123
+ "HTTPRoute requires at least one path match: pass prefix:, exact:, or regex:"
124
+ end
125
+
126
+ hdrs = _headers(headers)
127
+ hdrs.empty? ? entries : entries.map { |m| m.merge(headers: hdrs) }
128
+ end
129
+
130
+ # Accepts either a { "Header" => "value" } hash (Exact match) or a
131
+ # ready-made array of Gateway API header-match hashes.
132
+ def _headers(headers)
133
+ return [] if headers.nil? || headers.empty?
134
+ return headers if headers.is_a?(Array)
135
+
136
+ headers.map { |name, value| { type: "Exact", name: name.to_s, value: value } }
137
+ end
138
+
139
+ # Filter chain. Order: header rewrite, then middleware(s), then a
140
+ # terminal redirect (which needs no backend).
141
+ def _filters(middleware:, redirect:, header_modifier:)
142
+ filters = []
143
+
144
+ if header_modifier
145
+ filters << { type: "RequestHeaderModifier", requestHeaderModifier: header_modifier }
146
+ end
147
+
148
+ Array(middleware).each do |name|
149
+ filters << {
150
+ type: "ExtensionRef",
151
+ extensionRef: { group: MIDDLEWARE_GROUP, kind: MIDDLEWARE_KIND, name: name },
152
+ }
153
+ end
154
+
155
+ if redirect
156
+ filters << { type: "RequestRedirect", requestRedirect: _redirect(redirect) }
157
+ end
158
+
159
+ filters
160
+ end
161
+
162
+ # `redirect: true` is the common http->https 301. A hash customises
163
+ # scheme / status / path (ReplaceFullPath) / hostname.
164
+ def _redirect(redirect)
165
+ opts = redirect == true ? {} : redirect
166
+
167
+ rr = {
168
+ scheme: opts.fetch(:scheme, "https"),
169
+ statusCode: opts[:status] || opts[:statusCode] || 301,
170
+ }
171
+ rr[:path] = { type: "ReplaceFullPath", replaceFullPath: opts[:path] } if opts[:path]
172
+ rr[:hostname] = opts[:hostname] if opts[:hostname]
173
+ rr
174
+ end
175
+
176
+ # backendRef in the convention's field order. The Service `namespace`
177
+ # is emitted only when the route lives in a different namespace than
178
+ # the backend (the cross-namespace model, which needs a ReferenceGrant
179
+ # the caller supplies). Omitting it yields the co-located short form.
180
+ def _backend(service)
181
+ ref = {}
182
+ # Cross-namespace backends carry the explicit group/kind/namespace
183
+ # (and need a ReferenceGrant); a co-located Service uses the bare
184
+ # short form. Emitting group/kind only in the former keeps both
185
+ # shapes byte-identical to the hand-written routes they replace.
186
+ if service[:namespace]
187
+ ref[:group] = ""
188
+ ref[:kind] = "Service"
189
+ ref[:name] = service.fetch(:name)
190
+ ref[:namespace] = service[:namespace]
191
+ else
192
+ ref[:name] = service.fetch(:name)
193
+ end
194
+ ref[:port] = service.fetch(:port)
195
+ ref[:weight] = service.fetch(:weight, 1)
196
+ ref
197
+ end
198
+ end
12
199
  end
13
200
  end
14
201
  end
15
202
  end
16
203
 
17
- test do
18
- #describe "GatewayApi::HTTPRoute" do
19
- # it "initializes without error" do
20
- # Kube::Cluster::Standard::GatewayApi::HTTPRoute
21
- # .new(
22
- # name: nil,
23
- # hostname: nil,
24
- # service: nil,
25
- # namespace: nil,
26
- # port: nil,
27
- # )
28
- # .to_yaml
29
- # .is_a?(String)
30
- # .should == true
31
- # end
32
- #end
204
+ __END__
205
+
206
+ describe "GatewayApi::HTTPRoute" do
207
+ route = proc { |**kw| Kube::Cluster::Standard::GatewayApi::HTTPRoute.new(**kw) }
208
+
209
+ it "initializes without error" do
210
+ route.(
211
+ name: "docuseal",
212
+ gateway: "example-com-https",
213
+ domains: ["docuseal.example.com"],
214
+ prefix: ["/"],
215
+ service: { namespace: "ai", name: "docuseal", port: 3000 },
216
+ ).to_yaml.is_a?(String).should == true
217
+ end
218
+
219
+ it "wires the fixed traefik-gateway parentRef with the given section" do
220
+ yaml = route.(
221
+ name: "docuseal",
222
+ gateway: "example-com-https",
223
+ domains: ["docuseal.example.com"],
224
+ prefix: ["/"],
225
+ service: { namespace: "ai", name: "docuseal", port: 3000 },
226
+ ).to_yaml
227
+
228
+ yaml.should.include "traefik-gateway"
229
+ yaml.should.include "example-com-https"
230
+ yaml.should.include "docuseal.example.com"
231
+ yaml.should.include "PathPrefix"
232
+ end
233
+
234
+ it "renders many typed matches onto one backend with timeouts" do
235
+ yaml = route.(
236
+ name: "forgejo-git",
237
+ gateway: "example-net-https",
238
+ domains: ["git.example.net"],
239
+ regex: ["/.+/info/refs", "/.+/git-upload-pack", "/.+/git-receive-pack"],
240
+ prefix: ["/api", "/v2"],
241
+ service: { namespace: "default", name: "forgejo-http", port: 3000 },
242
+ timeouts: { request: "600s", backendRequest: "600s" },
243
+ ).to_yaml
244
+
245
+ yaml.should.include "RegularExpression"
246
+ yaml.should.include "git-upload-pack"
247
+ yaml.should.include "backendRequest: 600s"
248
+ # three regex matches share the single backend
249
+ yaml.scan(/RegularExpression/).length.should == 3
250
+ end
251
+
252
+ it "renders a terminal https redirect with no backend" do
253
+ yaml = route.(
254
+ name: "sourcebot-http",
255
+ gateway: "example-com-http",
256
+ domains: ["sg.example.com"],
257
+ prefix: ["/"],
258
+ redirect: true,
259
+ ).to_yaml
260
+
261
+ yaml.should.include "RequestRedirect"
262
+ yaml.should.include "statusCode: 301"
263
+ yaml.should.not.include "backendRefs"
264
+ end
265
+
266
+ it "renders a custom redirect with ReplaceFullPath and a 302" do
267
+ yaml = route.(
268
+ name: "forgejo-login",
269
+ gateway: "example-net-https",
270
+ domains: ["git.example.net"],
271
+ exact: ["/user/login"],
272
+ redirect: { path: "/user/oauth2/authelia", status: 302 },
273
+ ).to_yaml
274
+
275
+ yaml.should.include "ReplaceFullPath"
276
+ yaml.should.include "statusCode: 302"
277
+ yaml.should.include "Exact"
278
+ end
279
+
280
+ it "chains multiple middlewares as ExtensionRef filters" do
281
+ yaml = route.(
282
+ name: "docker-registry",
283
+ gateway: "example-net-https",
284
+ domains: ["registry.example.net"],
285
+ prefix: ["/"],
286
+ service: { namespace: "docker-registry", name: "docker-registry", port: 80 },
287
+ middleware: ["clear-site-data-cookies", "forwardauth-oauth2-proxy-example"],
288
+ ).to_yaml
289
+
290
+ yaml.scan(/ExtensionRef/).length.should == 2
291
+ yaml.should.include "clear-site-data-cookies"
292
+ yaml.should.include "forwardauth-oauth2-proxy-example"
293
+ end
294
+
295
+ it "renders a header modifier and a co-located short-form backend" do
296
+ yaml = route.(
297
+ name: "sogo",
298
+ namespace: "mail",
299
+ gateway: "example-com-https",
300
+ domains: ["sogo.example.com"],
301
+ prefix: ["/"],
302
+ service: { name: "sogo", port: 80 },
303
+ header_modifier: { remove: ["x-webobjects-remote-user"] },
304
+ ).to_yaml
305
+
306
+ yaml.should.include "RequestHeaderModifier"
307
+ yaml.should.include "x-webobjects-remote-user"
308
+ end
309
+
310
+ it "supports a websocket header match" do
311
+ yaml = route.(
312
+ name: "chrome-tool-ws",
313
+ gateway: "example-com-https",
314
+ domains: ["chrome-tool-ws.example.com"],
315
+ prefix: ["/"],
316
+ service: { namespace: "ai", name: "chrome-tool-ws", port: 8765 },
317
+ headers: { "Upgrade" => "websocket" },
318
+ ).to_yaml
319
+
320
+ yaml.should.include "Upgrade"
321
+ yaml.should.include "websocket"
322
+ end
323
+
324
+ it "renders multiple hostnames on one route" do
325
+ yaml = route.(
326
+ name: "git",
327
+ gateway: "example-net-https",
328
+ domains: ["git.example.net", "git.example.com"],
329
+ prefix: ["/"],
330
+ service: { namespace: "default", name: "forgejo-http", port: 3000 },
331
+ ).to_yaml
332
+
333
+ yaml.should.include "git.example.net"
334
+ yaml.should.include "git.example.com"
335
+ end
33
336
  end
@@ -34,17 +34,17 @@ module Kube
34
34
  end
35
35
  end
36
36
 
37
- test do
38
- describe "Job" do
39
- it "initializes without error" do
40
- Kube::Cluster::Standard::Job
41
- .new(
42
- name: "my-job",
43
- image: "nixery.dev/cowsay", # nixery.dev is pretty sick, mate!
44
- )
45
- .to_yaml
46
- .is_a?(String)
47
- .should == true
48
- end
37
+ __END__
38
+
39
+ describe "Job" do
40
+ it "initializes without error" do
41
+ Kube::Cluster::Standard::Job
42
+ .new(
43
+ name: "my-job",
44
+ image: "nixery.dev/cowsay", # nixery.dev is pretty sick, mate!
45
+ )
46
+ .to_yaml
47
+ .is_a?(String)
48
+ .should == true
49
49
  end
50
50
  end
@@ -51,17 +51,17 @@ module Kube
51
51
  end
52
52
  end
53
53
 
54
- test do
55
- describe "JobWithServiceAccount" do
56
- it "emits the RBAC trio plus the job" do
57
- m = Kube::Cluster::Standard::JobWithServiceAccount.new(
58
- name: "seed",
59
- image: "nixery.dev/shell/kubectl",
60
- rules: ["batch/jobs" => %w[create]],
61
- command: ["true"],
62
- )
54
+ __END__
63
55
 
64
- m.map { |r| r.to_h[:kind] }.sort.should == %w[Job Role RoleBinding ServiceAccount]
65
- end
56
+ describe "JobWithServiceAccount" do
57
+ it "emits the RBAC trio plus the job" do
58
+ m = Kube::Cluster::Standard::JobWithServiceAccount.new(
59
+ name: "seed",
60
+ image: "nixery.dev/shell/kubectl",
61
+ rules: ["batch/jobs" => %w[create]],
62
+ command: ["true"],
63
+ )
64
+
65
+ m.map { |r| r.to_h[:kind] }.sort.should == %w[Job Role RoleBinding ServiceAccount]
66
66
  end
67
67
  end
@@ -21,16 +21,16 @@ module Kube
21
21
  end
22
22
  end
23
23
 
24
- test do
25
- describe "KubeVirt::VirtualMachine" do
26
- it "initializes without error" do
27
- Kube::Cluster::Standard::KubeVirt::VirtualMachine
28
- .new(
29
- name: "my-virtual-machine"
30
- )
31
- .to_yaml
32
- .is_a?(String)
33
- .should == true
34
- end
24
+ __END__
25
+
26
+ describe "KubeVirt::VirtualMachine" do
27
+ it "initializes without error" do
28
+ Kube::Cluster::Standard::KubeVirt::VirtualMachine
29
+ .new(
30
+ name: "my-virtual-machine"
31
+ )
32
+ .to_yaml
33
+ .is_a?(String)
34
+ .should == true
35
35
  end
36
36
  end
@@ -59,18 +59,18 @@ module Kube
59
59
  end
60
60
  end
61
61
 
62
- test do
63
- describe "MetaController::CompositeController" do
64
- it "initializes without error" do
65
- Kube::Cluster::Standard::MetaController::CompositeController
66
- .new(
67
- name: "my-controller",
68
- webhook_url: "http://hook.default.svc/sync",
69
- parent_resource: { apiVersion: "apps/v1", resource: "deployments" },
70
- )
71
- .to_yaml
72
- .is_a?(String)
73
- .should == true
74
- end
62
+ __END__
63
+
64
+ describe "MetaController::CompositeController" do
65
+ it "initializes without error" do
66
+ Kube::Cluster::Standard::MetaController::CompositeController
67
+ .new(
68
+ name: "my-controller",
69
+ webhook_url: "http://hook.default.svc/sync",
70
+ parent_resource: { apiVersion: "apps/v1", resource: "deployments" },
71
+ )
72
+ .to_yaml
73
+ .is_a?(String)
74
+ .should == true
75
75
  end
76
76
  end
@@ -58,18 +58,18 @@ module Kube
58
58
  end
59
59
  end
60
60
 
61
- test do
62
- describe "MetaController::DecoratorController" do
63
- it "initializes without error" do
64
- Kube::Cluster::Standard::MetaController::DecoratorController
65
- .new(
66
- name: "my-controller",
67
- webhook_url: "http://hook.default.svc/sync",
68
- resources: { { apiVersion: "v1", resource: "pods" } => {} },
69
- )
70
- .to_yaml
71
- .is_a?(String)
72
- .should == true
73
- end
61
+ __END__
62
+
63
+ describe "MetaController::DecoratorController" do
64
+ it "initializes without error" do
65
+ Kube::Cluster::Standard::MetaController::DecoratorController
66
+ .new(
67
+ name: "my-controller",
68
+ webhook_url: "http://hook.default.svc/sync",
69
+ resources: { { apiVersion: "v1", resource: "pods" } => {} },
70
+ )
71
+ .to_yaml
72
+ .is_a?(String)
73
+ .should == true
74
74
  end
75
75
  end
@@ -32,14 +32,14 @@ module Kube
32
32
  end
33
33
  end
34
34
 
35
- test do
36
- describe "Perses::Perses" do
37
- it "initializes without error" do
38
- Kube::Cluster::Standard::Perses::Perses
39
- .new(name: "perses", image: "persesdev/perses:latest")
40
- .to_yaml
41
- .is_a?(String)
42
- .should == true
43
- end
35
+ __END__
36
+
37
+ describe "Perses::Perses" do
38
+ it "initializes without error" do
39
+ Kube::Cluster::Standard::Perses::Perses
40
+ .new(name: "perses", image: "persesdev/perses:latest")
41
+ .to_yaml
42
+ .is_a?(String)
43
+ .should == true
44
44
  end
45
45
  end
@@ -34,18 +34,18 @@ module Kube
34
34
  end
35
35
  end
36
36
 
37
- test do
38
- describe "Perses::PersesDatasource" do
39
- it "initializes without error" do
40
- Kube::Cluster::Standard::Perses::PersesDatasource
41
- .new(
42
- name: "victoriametrics",
43
- plugin_kind: "PrometheusDatasource",
44
- url: "http://vmsingle-vmsingle.metrics.svc:8429",
45
- )
46
- .to_yaml
47
- .is_a?(String)
48
- .should == true
49
- end
37
+ __END__
38
+
39
+ describe "Perses::PersesDatasource" do
40
+ it "initializes without error" do
41
+ Kube::Cluster::Standard::Perses::PersesDatasource
42
+ .new(
43
+ name: "victoriametrics",
44
+ plugin_kind: "PrometheusDatasource",
45
+ url: "http://vmsingle-vmsingle.metrics.svc:8429",
46
+ )
47
+ .to_yaml
48
+ .is_a?(String)
49
+ .should == true
50
50
  end
51
51
  end
@@ -21,17 +21,17 @@ module Kube
21
21
  end
22
22
  end
23
23
 
24
- test do
25
- describe "PersistentVolumeClaim" do
26
- it "initializes without error" do
27
- Kube::Cluster::Standard::PersistentVolumeClaim
28
- .new(
29
- name: "my-volume",
30
- storage: "25Gi",
31
- )
32
- .to_yaml
33
- .is_a?(String)
34
- .should == true
35
- end
24
+ __END__
25
+
26
+ describe "PersistentVolumeClaim" do
27
+ it "initializes without error" do
28
+ Kube::Cluster::Standard::PersistentVolumeClaim
29
+ .new(
30
+ name: "my-volume",
31
+ storage: "25Gi",
32
+ )
33
+ .to_yaml
34
+ .is_a?(String)
35
+ .should == true
36
36
  end
37
37
  end
@@ -49,18 +49,18 @@ module Kube
49
49
  end
50
50
  end
51
51
 
52
- test do
53
- describe "Role" do
54
- it "expands the rules shorthand" do
55
- yaml = Kube::Cluster::Standard::Role
56
- .new(name: "r", rules: [
57
- "secrets" => %w[get list],
58
- "batch/cronjobs" => %w[get],
59
- ])
60
- .to_yaml
52
+ __END__
61
53
 
62
- yaml.include?("resources").should == true
63
- yaml.include?("batch").should == true
64
- end
54
+ describe "Role" do
55
+ it "expands the rules shorthand" do
56
+ yaml = Kube::Cluster::Standard::Role
57
+ .new(name: "r", rules: [
58
+ "secrets" => %w[get list],
59
+ "batch/cronjobs" => %w[get],
60
+ ])
61
+ .to_yaml
62
+
63
+ yaml.include?("resources").should == true
64
+ yaml.include?("batch").should == true
65
65
  end
66
66
  end
@@ -38,16 +38,16 @@ module Kube
38
38
  end
39
39
  end
40
40
 
41
- test do
42
- describe "RoleBinding" do
43
- it "references the role and service account" do
44
- yaml = Kube::Cluster::Standard::RoleBinding.new(
45
- role: Kube::Cluster::Standard::Role.new(name: "r", rules: ["secrets" => %w[get]]),
46
- service_account: Kube::Cluster::Standard::ServiceAccount.new(name: "sa"),
47
- ).to_yaml
41
+ __END__
48
42
 
49
- yaml.include?("name: r").should == true
50
- yaml.include?("name: sa").should == true
51
- end
43
+ describe "RoleBinding" do
44
+ it "references the role and service account" do
45
+ yaml = Kube::Cluster::Standard::RoleBinding.new(
46
+ role: Kube::Cluster::Standard::Role.new(name: "r", rules: ["secrets" => %w[get]]),
47
+ service_account: Kube::Cluster::Standard::ServiceAccount.new(name: "sa"),
48
+ ).to_yaml
49
+
50
+ yaml.include?("name: r").should == true
51
+ yaml.include?("name: sa").should == true
52
52
  end
53
53
  end