kube_cluster 0.21.0 → 1.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e702b334081767a62c208fcc0527bd69e531b1663c8f0073f5fd4cec5880263
4
- data.tar.gz: fb4289693ab12e0a4ab9ed97d477d68440a5caae4a92f3ed6b8605daef59a430
3
+ metadata.gz: cff2cff26d95919ba88b763d17c91b4fd48b024e038bf5bcbaba269fbf549f6b
4
+ data.tar.gz: cb2b14a5cc86d623c2871517771f7b4e3ecfad529d8ac48093e573065fc80f9d
5
5
  SHA512:
6
- metadata.gz: 614b806784409a283a0998004d19e5522b114a92d0b46798586f173eafd5718b88a66935f578a60406f6f779a4206c099d7bc8fee7f92429abad8c1facfbcaf1
7
- data.tar.gz: b546741f901ee256ed2f603fa3ca76c348d2a728151e54a96a4206da81c710712684c541b8c65cd304b51c25ced7dbbb23578d697346b122ec9ce8f84047d3d1
6
+ metadata.gz: b6333f789ef8a88beaef674cc32752a42a885a300f5d6bb5ab09f14c2dcab973f111e5ccb20f360605177e24beb3eac69769cd2e85269e98907c162d217adf25
7
+ data.tar.gz: 2cf30bce0097d24f98a20691b99a3f47514581dde2642d4ec2d1dd04c0cf4daf5c660befdbf511976728e084a0083ec21eb283edd5b5c43b9f593946cbfb9204
data/CHANGELOG.md ADDED
@@ -0,0 +1,42 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.1] - 2026-07-13
9
+
10
+ ### Added
11
+ - `require "kube/cluster/standard"` — an aggregator that loads the entire
12
+ Standard tree at once, for projects that use most of it. The tree remains
13
+ opt-in (`require "kube/cluster"` alone does not load it), so resolve overrides
14
+ still take effect. The core auto-require now also skips this aggregator file.
15
+
16
+ ## [1.0.0] - 2026-07-13
17
+
18
+ ### Added
19
+ - `Kube::Cluster.config` / `resolve` DSL backed by an internal resolve table
20
+ that `Kube::Cluster.[]` consults first, so a bare kind can be pinned to an
21
+ explicit `group/version/Kind` instead of whatever the schema registry lists
22
+ first.
23
+ - Resolve-table pins for every bare kind referenced under
24
+ `kube/cluster/standard` — Perses (`v1alpha2`), Gateway API (`v1`), built-in
25
+ Kubernetes kinds, and the Metacontroller, CloudNativePG, External Secrets,
26
+ KubeVirt, k3s HelmChart, and VictoriaMetrics CRDs.
27
+ - `config` warns when `Kube::Cluster::Standard` is already loaded, since those
28
+ classes have already bound their (now stale) superclasses.
29
+ - Test guarding that every bare kind used in the standard tree is pinned in the
30
+ resolve table.
31
+
32
+ ### Changed
33
+ - **Breaking:** the `kube/cluster/standard` tree is no longer auto-required by
34
+ `require "kube/cluster"`. Projects must require the specific standard classes
35
+ they use, so resolve overrides can be configured beforehand.
36
+
37
+ ### Fixed
38
+ - `Standard::Perses::Perses` and `Standard::Perses::PersesDatasource` now resolve
39
+ to `perses.dev/v1alpha2` instead of the deprecated `v1alpha1` a bare-kind
40
+ lookup defaulted to.
41
+
42
+ [1.0.0]: https://github.com/general-intelligence-systems/kube_cluster/releases/tag/v1.0.0
data/Gemfile.lock CHANGED
@@ -1,10 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kube_cluster (0.20.0)
4
+ kube_cluster (1.0.1)
5
5
  activesupport (~> 8.0)
6
6
  kube_kubectl (~> 2.0)
7
- kube_schema (~> 1.8)
7
+ kube_schema (~> 1.9.2)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
@@ -132,7 +132,7 @@ GEM
132
132
  rubyshell (~> 1.5)
133
133
  shellwords (~> 0.2.2)
134
134
  string_builder (~> 1.2.2)
135
- kube_schema (1.9.1)
135
+ kube_schema (1.9.2)
136
136
  json_schemer (~> 2.5.0)
137
137
  rubyshell (~> 1.5.0)
138
138
  localhost (1.8.0)
data/kube_cluster.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "rake", "~> 13.0"
32
32
  spec.add_development_dependency "scampi", "~> 1.0"
33
33
 
34
- spec.add_dependency "kube_schema", "~> 1.9.1"
34
+ spec.add_dependency "kube_schema", "~> 1.9.2"
35
35
  spec.add_dependency "kube_kubectl", "~> 2.0"
36
36
  spec.add_dependency "activesupport", "~> 8.0"
37
37
  end
@@ -22,16 +22,16 @@ module Kube
22
22
  #
23
23
  # Standard::GatewayApi::HTTPRoute.new(
24
24
  # name: "sourcebot",
25
- # gateway: "kremlin-email-https",
26
- # domains: ["sg.kremlin.email"],
25
+ # gateway: "example-com-https",
26
+ # domains: ["sg.example.com"],
27
27
  # service: { namespace: "sourcebot", name: "sourcebot", port: 3000 },
28
- # middleware: "forwardauth-oauth2-proxy-kremlin",
28
+ # middleware: "forwardauth-oauth2-proxy-example",
29
29
  # )
30
30
  #
31
31
  # Many matches -> one backend (forgejo git smart-HTTP):
32
32
  #
33
33
  # Standard::GatewayApi::HTTPRoute.new(
34
- # name: "forgejo-git", gateway: "cia-net-https", domains: ["git.cia.net"],
34
+ # name: "forgejo-git", gateway: "example-net-https", domains: ["git.example.net"],
35
35
  # regex: ["/.+/info/refs", "/.+/git-upload-pack", "/.+/git-receive-pack"],
36
36
  # prefix: ["/api", "/v2"],
37
37
  # service: { namespace: "default", name: "forgejo-http", port: 3000 },
@@ -41,8 +41,8 @@ module Kube
41
41
  # Terminal http->https redirect (the `-http` sibling):
42
42
  #
43
43
  # Standard::GatewayApi::HTTPRoute.new(
44
- # name: "sourcebot-http", gateway: "kremlin-email-http",
45
- # domains: ["sg.kremlin.email"], prefix: ["/"], redirect: true,
44
+ # name: "sourcebot-http", gateway: "example-com-http",
45
+ # domains: ["sg.example.com"], prefix: ["/"], redirect: true,
46
46
  # )
47
47
  class HTTPRoute < Kube::Cluster["HTTPRoute"]
48
48
  GATEWAY_GROUP = "gateway.networking.k8s.io"
@@ -86,7 +86,10 @@ module Kube
86
86
 
87
87
  super() {
88
88
  metadata.name = name
89
- metadata.namespace = namespace
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
90
93
 
91
94
  spec.hostnames = hostnames
92
95
  spec.parentRefs = [{
@@ -175,10 +178,21 @@ module Kube
175
178
  # the backend (the cross-namespace model, which needs a ReferenceGrant
176
179
  # the caller supplies). Omitting it yields the co-located short form.
177
180
  def _backend(service)
178
- ref = { group: "", kind: "Service", name: service.fetch(:name) }
179
- ref[:namespace] = service[:namespace] if service[:namespace]
180
- ref[:port] = service.fetch(:port)
181
- ref[:weight] = service.fetch(:weight, 1)
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)
182
196
  ref
183
197
  end
184
198
  end
@@ -195,8 +209,9 @@ describe "GatewayApi::HTTPRoute" do
195
209
  it "initializes without error" do
196
210
  route.(
197
211
  name: "docuseal",
198
- gateway: "kremlin-email-https",
199
- domains: ["docuseal.kremlin.email"],
212
+ gateway: "example-com-https",
213
+ domains: ["docuseal.example.com"],
214
+ prefix: ["/"],
200
215
  service: { namespace: "ai", name: "docuseal", port: 3000 },
201
216
  ).to_yaml.is_a?(String).should == true
202
217
  end
@@ -204,22 +219,23 @@ describe "GatewayApi::HTTPRoute" do
204
219
  it "wires the fixed traefik-gateway parentRef with the given section" do
205
220
  yaml = route.(
206
221
  name: "docuseal",
207
- gateway: "kremlin-email-https",
208
- domains: ["docuseal.kremlin.email"],
222
+ gateway: "example-com-https",
223
+ domains: ["docuseal.example.com"],
224
+ prefix: ["/"],
209
225
  service: { namespace: "ai", name: "docuseal", port: 3000 },
210
226
  ).to_yaml
211
227
 
212
228
  yaml.should.include "traefik-gateway"
213
- yaml.should.include "kremlin-email-https"
214
- yaml.should.include "docuseal.kremlin.email"
229
+ yaml.should.include "example-com-https"
230
+ yaml.should.include "docuseal.example.com"
215
231
  yaml.should.include "PathPrefix"
216
232
  end
217
233
 
218
234
  it "renders many typed matches onto one backend with timeouts" do
219
235
  yaml = route.(
220
236
  name: "forgejo-git",
221
- gateway: "cia-net-https",
222
- domains: ["git.cia.net"],
237
+ gateway: "example-net-https",
238
+ domains: ["git.example.net"],
223
239
  regex: ["/.+/info/refs", "/.+/git-upload-pack", "/.+/git-receive-pack"],
224
240
  prefix: ["/api", "/v2"],
225
241
  service: { namespace: "default", name: "forgejo-http", port: 3000 },
@@ -236,8 +252,8 @@ describe "GatewayApi::HTTPRoute" do
236
252
  it "renders a terminal https redirect with no backend" do
237
253
  yaml = route.(
238
254
  name: "sourcebot-http",
239
- gateway: "kremlin-email-http",
240
- domains: ["sg.kremlin.email"],
255
+ gateway: "example-com-http",
256
+ domains: ["sg.example.com"],
241
257
  prefix: ["/"],
242
258
  redirect: true,
243
259
  ).to_yaml
@@ -250,8 +266,8 @@ describe "GatewayApi::HTTPRoute" do
250
266
  it "renders a custom redirect with ReplaceFullPath and a 302" do
251
267
  yaml = route.(
252
268
  name: "forgejo-login",
253
- gateway: "cia-net-https",
254
- domains: ["git.cia.net"],
269
+ gateway: "example-net-https",
270
+ domains: ["git.example.net"],
255
271
  exact: ["/user/login"],
256
272
  redirect: { path: "/user/oauth2/authelia", status: 302 },
257
273
  ).to_yaml
@@ -264,23 +280,25 @@ describe "GatewayApi::HTTPRoute" do
264
280
  it "chains multiple middlewares as ExtensionRef filters" do
265
281
  yaml = route.(
266
282
  name: "docker-registry",
267
- gateway: "cia-net-https",
268
- domains: ["registry.cia.net"],
283
+ gateway: "example-net-https",
284
+ domains: ["registry.example.net"],
285
+ prefix: ["/"],
269
286
  service: { namespace: "docker-registry", name: "docker-registry", port: 80 },
270
- middleware: ["clear-site-data-cookies", "forwardauth-oauth2-proxy-cia"],
287
+ middleware: ["clear-site-data-cookies", "forwardauth-oauth2-proxy-example"],
271
288
  ).to_yaml
272
289
 
273
290
  yaml.scan(/ExtensionRef/).length.should == 2
274
291
  yaml.should.include "clear-site-data-cookies"
275
- yaml.should.include "forwardauth-oauth2-proxy-cia"
292
+ yaml.should.include "forwardauth-oauth2-proxy-example"
276
293
  end
277
294
 
278
295
  it "renders a header modifier and a co-located short-form backend" do
279
296
  yaml = route.(
280
297
  name: "sogo",
281
298
  namespace: "mail",
282
- gateway: "kremlin-email-https",
283
- domains: ["sogo.kremlin.email"],
299
+ gateway: "example-com-https",
300
+ domains: ["sogo.example.com"],
301
+ prefix: ["/"],
284
302
  service: { name: "sogo", port: 80 },
285
303
  header_modifier: { remove: ["x-webobjects-remote-user"] },
286
304
  ).to_yaml
@@ -292,8 +310,9 @@ describe "GatewayApi::HTTPRoute" do
292
310
  it "supports a websocket header match" do
293
311
  yaml = route.(
294
312
  name: "chrome-tool-ws",
295
- gateway: "kremlin-email-https",
296
- domains: ["chrome-tool-ws.kremlin.email"],
313
+ gateway: "example-com-https",
314
+ domains: ["chrome-tool-ws.example.com"],
315
+ prefix: ["/"],
297
316
  service: { namespace: "ai", name: "chrome-tool-ws", port: 8765 },
298
317
  headers: { "Upgrade" => "websocket" },
299
318
  ).to_yaml
@@ -305,12 +324,13 @@ describe "GatewayApi::HTTPRoute" do
305
324
  it "renders multiple hostnames on one route" do
306
325
  yaml = route.(
307
326
  name: "git",
308
- gateway: "cia-net-https",
309
- domains: ["git.cia.net", "git.kremlin.email"],
327
+ gateway: "example-net-https",
328
+ domains: ["git.example.net", "git.example.com"],
329
+ prefix: ["/"],
310
330
  service: { namespace: "default", name: "forgejo-http", port: 3000 },
311
331
  ).to_yaml
312
332
 
313
- yaml.should.include "git.cia.net"
314
- yaml.should.include "git.kremlin.email"
333
+ yaml.should.include "git.example.net"
334
+ yaml.should.include "git.example.com"
315
335
  end
316
336
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Opt-in loader for the whole Standard tree.
4
+ #
5
+ # `require "kube/cluster"` deliberately does NOT auto-load the Standard classes
6
+ # (so resolve overrides can be configured before they bind their superclasses).
7
+ # Requiring this file pulls in every Standard class at once — the convenient
8
+ # "give me all of them" entry point for projects that use most of the tree.
9
+ require "kube/cluster"
10
+
11
+ Dir.glob("#{__dir__}/standard/**/*.rb").sort.each do |path|
12
+ require path
13
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kube
4
4
  module Cluster
5
- VERSION = "0.21.0"
5
+ VERSION = "1.0.1"
6
6
  end
7
7
  end
data/lib/kube/cluster.rb CHANGED
@@ -20,6 +20,42 @@ module Kube
20
20
  Instance.new(kubeconfig: kubeconfig)
21
21
  end
22
22
 
23
+ # Internal table mapping a bare kind to the group/version/Kind it should
24
+ # resolve to. Consulted first by Kube::Cluster.[] so a bare lookup lands on
25
+ # a pinned version instead of whatever the schema registry defaults to.
26
+ def self.resolve_table
27
+ @resolve_table ||= {}
28
+ end
29
+
30
+ # Configure kind resolution:
31
+ #
32
+ # Kube::Cluster.config do
33
+ # resolve "Perses", to: "perses.dev/v1alpha2/Perses"
34
+ # end
35
+ #
36
+ # Ordering matters: Kube::Cluster.[] memoizes per kind, and the Standard
37
+ # classes bind their superclass at definition time (e.g.
38
+ # `class Perses < Kube::Cluster["Perses"]`). A resolve therefore only takes
39
+ # effect for kinds looked up afterwards — so configure before requiring any
40
+ # kube/cluster/standard class. If Standard is already loaded, warn: its
41
+ # classes have already bound their (now stale) superclasses.
42
+ def self.config(&block)
43
+ if const_defined?(:Standard, false)
44
+ warn "Kube::Cluster::Standard was loaded before Kube::Cluster.config — " \
45
+ "resolve overrides will not affect the already-bound Standard classes."
46
+ end
47
+ Config.instance_eval(&block) if block
48
+ Config
49
+ end
50
+
51
+ module Config
52
+ module_function
53
+
54
+ def resolve(kind, to:)
55
+ Kube::Cluster.resolve_table[kind] = to
56
+ end
57
+ end
58
+
23
59
  # Returns an anonymous subclass of Kube::Cluster::Resource for the
24
60
  # given Kubernetes kind, mirroring Kube::Schema[kind] but with
25
61
  # dirty tracking, persistence, and resource helper methods.
@@ -27,6 +63,7 @@ module Kube
27
63
  # Kube::Cluster["Deployment"].new { metadata.name = "web" }
28
64
  #
29
65
  def self.[](kind)
66
+ kind = resolve_table.fetch(kind, kind)
30
67
  @resource_classes ||= {}
31
68
  @resource_classes[kind] ||= begin
32
69
  schema_class = Kube::Schema[kind]
@@ -48,7 +85,108 @@ require "kube/cluster/middleware"
48
85
  require "kube/cluster/resource/dirty_tracking"
49
86
  require "kube/cluster/resource/persistence"
50
87
 
88
+ # Kind resolution overrides. Registered here, at load time, so the pins are in
89
+ # place before a project requires any kube/cluster/standard class (those bind
90
+ # Kube::Cluster[kind] at definition time). The standard tree is deliberately not
91
+ # auto-required below — projects require the specific classes they use.
92
+ Kube::Cluster.config do
93
+ # Built-in Kubernetes kinds.
94
+ resolve "ConfigMap", to: "v1/ConfigMap"
95
+ resolve "PersistentVolumeClaim", to: "v1/PersistentVolumeClaim"
96
+ resolve "Secret", to: "v1/Secret"
97
+ resolve "Service", to: "v1/Service"
98
+ resolve "ServiceAccount", to: "v1/ServiceAccount"
99
+ resolve "DaemonSet", to: "apps/v1/DaemonSet"
100
+ resolve "Deployment", to: "apps/v1/Deployment"
101
+ resolve "CronJob", to: "batch/v1/CronJob"
102
+ resolve "Job", to: "batch/v1/Job"
103
+ resolve "Role", to: "rbac.authorization.k8s.io/v1/Role"
104
+ resolve "RoleBinding", to: "rbac.authorization.k8s.io/v1/RoleBinding"
105
+ resolve "CustomResourceDefinition", to: "apiextensions.k8s.io/v1/CustomResourceDefinition"
106
+
107
+ # Metacontroller.
108
+ resolve "CompositeController", to: "metacontroller.k8s.io/v1alpha1/CompositeController"
109
+ resolve "DecoratorController", to: "metacontroller.k8s.io/v1alpha1/DecoratorController"
110
+
111
+ # CloudNativePG.
112
+ resolve "Database", to: "postgresql.cnpg.io/v1/Database"
113
+
114
+ # External Secrets Operator.
115
+ resolve "ExternalSecret", to: "external-secrets.io/v1/ExternalSecret"
116
+
117
+ # KubeVirt.
118
+ resolve "VirtualMachine", to: "kubevirt.io/v1/VirtualMachine"
119
+
120
+ # k3s HelmChart.
121
+ resolve "HelmChart", to: "helm.cattle.io/v1/HelmChart"
122
+
123
+ # VictoriaMetrics operator.
124
+ resolve "VLAgent", to: "operator.victoriametrics.com/v1/VLAgent"
125
+ resolve "VLSingle", to: "operator.victoriametrics.com/v1/VLSingle"
126
+ resolve "VMAgent", to: "operator.victoriametrics.com/v1beta1/VMAgent"
127
+ resolve "VMNodeScrape", to: "operator.victoriametrics.com/v1beta1/VMNodeScrape"
128
+ resolve "VMServiceScrape", to: "operator.victoriametrics.com/v1beta1/VMServiceScrape"
129
+ resolve "VMSingle", to: "operator.victoriametrics.com/v1beta1/VMSingle"
130
+
131
+ # Gateway API — pin to the stable v1 group/version.
132
+ resolve "GatewayClass", to: "gateway.networking.k8s.io/v1/GatewayClass"
133
+ resolve "Gateway", to: "gateway.networking.k8s.io/v1/Gateway"
134
+ resolve "HTTPRoute", to: "gateway.networking.k8s.io/v1/HTTPRoute"
135
+ resolve "GRPCRoute", to: "gateway.networking.k8s.io/v1/GRPCRoute"
136
+ resolve "ReferenceGrant", to: "gateway.networking.k8s.io/v1/ReferenceGrant"
137
+
138
+ # Perses operator — pin to v1alpha2 (bare kind defaults to deprecated v1alpha1).
139
+ resolve "Perses", to: "perses.dev/v1alpha2/Perses"
140
+ resolve "PersesDashboard", to: "perses.dev/v1alpha2/PersesDashboard"
141
+ resolve "PersesDatasource", to: "perses.dev/v1alpha2/PersesDatasource"
142
+ resolve "PersesGlobalDatasource", to: "perses.dev/v1alpha2/PersesGlobalDatasource"
143
+ end
144
+
145
+ standard_root = "#{__dir__}/cluster/standard"
51
146
  Dir.glob("#{__dir__}/cluster/**/*.rb").sort.each do |path|
147
+ # The standard/ tree is opt-in — via `require "kube/cluster/standard"` or a
148
+ # specific class — so that resolve overrides can be configured beforehand.
149
+ # Skip both the tree and its aggregator loader (cluster/standard.rb).
150
+ next if path == "#{standard_root}.rb" || path.start_with?("#{standard_root}/")
151
+
52
152
  require path
53
153
  end
54
154
 
155
+ __END__
156
+
157
+ # Every Standard class binds its superclass at load time with a bare kind, e.g.
158
+ # `class Perses < Kube::Cluster["Perses"]`. A bare kind resolves to whatever
159
+ # version the schema registry lists first — sometimes a deprecated one (Perses
160
+ # defaulted to v1alpha1) — so each such kind must be pinned in the resolve table
161
+ # above. This fails if any bare kind under kube/cluster/standard is unpinned.
162
+ describe "Kube::Cluster resolve table" do
163
+ it "pins every bare kind referenced under kube/cluster/standard" do
164
+ cluster_rb = Kube::Cluster.method(:[]).source_location.first
165
+ std_dir = File.join(File.dirname(cluster_rb), "cluster", "standard")
166
+
167
+ # kind => ["relative/file.rb:lineno", ...], scanning only real code (the
168
+ # section before each file's own __END__), skipping commented-out classes.
169
+ referenced = {}
170
+ Dir.glob("#{std_dir}/**/*.rb").sort.each do |file|
171
+ head = File.read(file).split(/^__END__$\n?/, 2).first
172
+ head.each_line.with_index(1) do |line, lineno|
173
+ next if line =~ /\A\s*#/
174
+ line.scan(/Kube::Cluster\[\s*['"]([^'"]+)['"]\s*\]/) do |(ref)|
175
+ next if ref.include?("/") # already a fully-qualified GVK
176
+ (referenced[ref] ||= []) << "#{file.sub("#{std_dir}/", "")}:#{lineno}"
177
+ end
178
+ end
179
+ end
180
+
181
+ table = Kube::Cluster.resolve_table
182
+ missing = referenced.reject { |kind, _| table.key?(kind) }
183
+
184
+ unless missing.empty?
185
+ report = missing.sort.map { |kind, locs| " #{kind} (#{locs.join(", ")})" }.join("\n")
186
+ raise "Bare kinds under kube/cluster/standard missing from the resolve table:\n#{report}"
187
+ end
188
+
189
+ missing.empty?.should == true
190
+ end
191
+ end
192
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kube_cluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan K
@@ -43,14 +43,14 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 1.9.1
46
+ version: 1.9.2
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 1.9.1
53
+ version: 1.9.2
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: kube_kubectl
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -96,6 +96,7 @@ files:
96
96
  - ".github/workflows/test.yaml"
97
97
  - ".gitignore"
98
98
  - ".rubocop.yml"
99
+ - CHANGELOG.md
99
100
  - Gemfile
100
101
  - Gemfile.lock
101
102
  - LICENSE
@@ -197,6 +198,7 @@ files:
197
198
  - lib/kube/cluster/resource/extensions/custom_resource_definition.rb
198
199
  - lib/kube/cluster/resource/persistence.rb
199
200
  - lib/kube/cluster/script_command.rb
201
+ - lib/kube/cluster/standard.rb
200
202
  - lib/kube/cluster/standard/cdi/data_volume.rb
201
203
  - lib/kube/cluster/standard/cloud_native_pg/cluster.rb
202
204
  - lib/kube/cluster/standard/cloud_native_pg/database_with_external_secret.rb