kube_schema 1.4.3 → 1.4.4

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: ba7602c0c24945ada55520a025190b13f6ce4c6981e62dc8b455df3c3f0c921b
4
- data.tar.gz: c91e8b6607bda7c787a7fe2d0260bf8068114d4ccf88deb4b07a03b52d6c5e13
3
+ metadata.gz: e9695974cb2703c11c69c41aa624cd96cf6ac5f8bcf9859ebce423be49146250
4
+ data.tar.gz: 23210ffab5ca166dacfa3f1ba2ce2d24742a36127d95fa1a1b0d896c464ef1ed
5
5
  SHA512:
6
- metadata.gz: 2b5f9c5715375c44d3961a260d5c9dcb60b4b8b8ccee542b8bc945fde1c1dccc26c854943e6ae36255033cb7ad671d7c46aea62f5f191c2f6453a5d4fc1d4755
7
- data.tar.gz: 942e526bbe5bdbcf939cf7722e64e623da0150413e93cea7dcb5b607b34328c8db0e6d9f5c835cb1046a2da5ce50568fe59da91064ef7dbd0400a1ebcab0f1e6
6
+ metadata.gz: aac9d217ba2235bda3206de3391ece4da353a938b40e0ae58c98932bf03c9deee679e4c2072bbbdf5566e4663b0551b75ff700573481893bd44127e01de0f30e
7
+ data.tar.gz: 1fc8fc7a0fd40fb47168c48b194f1c51522479652d391d3aa372928d91c08c348595c3e451db2f9ff53187fa4eabaed709f65e63a1e1e119588cc31426b77c65
@@ -0,0 +1,57 @@
1
+ name: Github Pages
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - trench
7
+
8
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages:
9
+ permissions:
10
+ contents: read
11
+ pages: write
12
+ id-token: write
13
+
14
+ # Allow one concurrent deployment:
15
+ concurrency:
16
+ group: "pages"
17
+ cancel-in-progress: true
18
+
19
+ env:
20
+ BUNDLE_WITH: maintenance
21
+
22
+ jobs:
23
+ generate:
24
+ runs-on: ubuntu-latest
25
+
26
+ steps:
27
+ - uses: actions/checkout@v6
28
+
29
+ - uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ruby
32
+ bundler-cache: true
33
+
34
+ - name: Installing packages
35
+ run: sudo apt-get install wget
36
+
37
+ - name: Generate documentation
38
+ timeout-minutes: 5
39
+ run: bundle exec bake utopia:project:static --force no
40
+
41
+ - name: Upload documentation artifact
42
+ uses: actions/upload-pages-artifact@v4
43
+ with:
44
+ path: docs
45
+
46
+ deploy:
47
+ runs-on: ubuntu-latest
48
+
49
+ environment:
50
+ name: github-pages
51
+ url: ${{steps.deployment.outputs.page_url}}
52
+
53
+ needs: generate
54
+ steps:
55
+ - name: Deploy to GitHub Pages
56
+ id: deployment
57
+ uses: actions/deploy-pages@v4
data/Gemfile CHANGED
@@ -3,3 +3,10 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
+
7
+ group :maintenance, optional: true do
8
+ gem "utopia-project"
9
+ gem "bake-gem"
10
+ gem "bake-modernize"
11
+ gem "bake-releases"
12
+ end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kube_schema (1.4.3)
4
+ kube_schema (1.4.4)
5
5
  json_schemer (~> 2.5.0)
6
6
  rubyshell (~> 1.5.0)
7
7
 
@@ -9,9 +9,97 @@ GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
11
  ast (2.4.3)
12
+ async (2.39.0)
13
+ console (~> 1.29)
14
+ fiber-annotation
15
+ io-event (~> 1.11)
16
+ metrics (~> 0.12)
17
+ traces (~> 0.18)
18
+ async-container (0.34.5)
19
+ async (~> 2.22)
20
+ async-http (0.95.0)
21
+ async (>= 2.10.2)
22
+ async-pool (~> 0.11)
23
+ io-endpoint (~> 0.14)
24
+ io-stream (~> 0.6)
25
+ metrics (~> 0.12)
26
+ protocol-http (~> 0.62)
27
+ protocol-http1 (~> 0.39)
28
+ protocol-http2 (~> 0.26)
29
+ protocol-url (~> 0.2)
30
+ traces (~> 0.10)
31
+ async-http-cache (0.4.6)
32
+ async-http (~> 0.56)
33
+ async-ollama (0.10.3)
34
+ async
35
+ async-rest
36
+ async-pool (0.11.2)
37
+ async (>= 2.0)
38
+ async-rest (0.20.0)
39
+ async-http (~> 0.42)
40
+ protocol-url (~> 0.2)
41
+ async-service (0.22.0)
42
+ async
43
+ async-container (~> 0.34)
44
+ string-format (~> 0.2)
45
+ async-utilization (0.3.2)
46
+ console (~> 1.0)
47
+ bake (0.24.1)
48
+ bigdecimal
49
+ samovar (~> 2.1)
50
+ bake-gem (0.13.1)
51
+ console (~> 1.25)
52
+ bake-modernize (0.54.1)
53
+ async-http
54
+ async-ollama (~> 0.10)
55
+ bake
56
+ build-files (~> 1.6)
57
+ markly (~> 0.13)
58
+ rugged
59
+ bake-releases (0.5.4)
60
+ bake (~> 0.21)
61
+ markly (~> 0.8)
12
62
  bigdecimal (4.1.2)
63
+ build-files (1.10.2)
64
+ concurrent-ruby (1.3.6)
65
+ console (1.34.3)
66
+ fiber-annotation
67
+ fiber-local (~> 1.1)
68
+ json
69
+ date (3.5.1)
70
+ decode (0.27.0)
71
+ prism
72
+ rbs
13
73
  diff-lcs (1.6.2)
74
+ erb (6.0.4)
75
+ falcon (0.55.3)
76
+ async
77
+ async-container (~> 0.20)
78
+ async-http (~> 0.75)
79
+ async-http-cache (~> 0.4)
80
+ async-service (~> 0.19)
81
+ async-utilization (~> 0.3)
82
+ bundler
83
+ localhost (~> 1.1)
84
+ openssl (>= 3.0)
85
+ protocol-http (~> 0.31)
86
+ protocol-rack (~> 0.7)
87
+ samovar (~> 2.3)
88
+ fiber-annotation (0.2.0)
89
+ fiber-local (1.1.0)
90
+ fiber-storage
91
+ fiber-storage (1.0.1)
14
92
  hana (1.3.7)
93
+ http-accept (2.2.1)
94
+ io-console (0.8.2)
95
+ io-endpoint (0.17.2)
96
+ io-event (1.15.1)
97
+ io-stream (0.13.0)
98
+ irb (1.18.0)
99
+ pp (>= 0.6.0)
100
+ prism (>= 1.3.0)
101
+ rdoc (>= 4.0.0)
102
+ reline (>= 0.4.2)
15
103
  json (2.19.3)
16
104
  json_schemer (2.5.0)
17
105
  bigdecimal
@@ -20,15 +108,75 @@ GEM
20
108
  simpleidn (~> 0.2)
21
109
  language_server-protocol (3.17.0.5)
22
110
  lint_roller (1.1.0)
111
+ localhost (1.7.0)
112
+ logger (1.7.0)
113
+ mail (2.9.0)
114
+ logger
115
+ mini_mime (>= 0.1.1)
116
+ net-imap
117
+ net-pop
118
+ net-smtp
119
+ mapping (1.1.3)
120
+ markly (0.16.0)
121
+ metrics (0.15.0)
122
+ mime-types (3.7.0)
123
+ logger
124
+ mime-types-data (~> 3.2025, >= 3.2025.0507)
125
+ mime-types-data (3.2026.0414)
126
+ mini_mime (1.1.5)
127
+ msgpack (1.8.0)
128
+ net-imap (0.6.4)
129
+ date
130
+ net-protocol
131
+ net-pop (0.1.2)
132
+ net-protocol
133
+ net-protocol (0.2.2)
134
+ timeout
135
+ net-smtp (0.5.1)
136
+ net-protocol
137
+ openssl (4.0.1)
23
138
  parallel (2.0.1)
24
139
  parser (3.3.11.1)
25
140
  ast (~> 2.4.1)
26
141
  racc
142
+ pp (0.6.3)
143
+ prettyprint
144
+ prettyprint (0.2.0)
27
145
  prism (1.9.0)
146
+ protocol-hpack (1.5.1)
147
+ protocol-http (0.62.2)
148
+ protocol-http1 (0.39.0)
149
+ protocol-http (~> 0.62)
150
+ protocol-http2 (0.26.0)
151
+ protocol-hpack (~> 1.4)
152
+ protocol-http (~> 0.62)
153
+ protocol-rack (0.22.1)
154
+ io-stream (>= 0.10)
155
+ protocol-http (~> 0.58)
156
+ rack (>= 1.0)
157
+ protocol-url (0.4.0)
158
+ psych (5.3.1)
159
+ date
160
+ stringio
28
161
  racc (1.8.1)
162
+ rack (3.2.6)
163
+ rackula (1.4.1)
164
+ falcon (~> 0.46)
165
+ samovar (~> 2.1)
166
+ variant
29
167
  rainbow (3.1.1)
30
168
  rake (13.4.2)
169
+ rbs (4.0.2)
170
+ logger
171
+ prism (>= 1.6.0)
172
+ tsort
173
+ rdoc (7.2.0)
174
+ erb
175
+ psych (>= 4.0.0)
176
+ tsort
31
177
  regexp_parser (2.12.0)
178
+ reline (0.6.3)
179
+ io-console (~> 0.5)
32
180
  rspec (3.13.2)
33
181
  rspec-core (~> 3.13.0)
34
182
  rspec-expectations (~> 3.13.0)
@@ -58,20 +206,60 @@ GEM
58
206
  prism (~> 1.7)
59
207
  ruby-progressbar (1.13.0)
60
208
  rubyshell (1.5.0)
209
+ rugged (1.9.0)
210
+ samovar (2.4.1)
211
+ console (~> 1.0)
212
+ mapping (~> 1.0)
61
213
  simpleidn (0.2.3)
214
+ string-format (0.2.0)
215
+ stringio (3.2.0)
216
+ thread-local (1.1.0)
217
+ timeout (0.6.1)
218
+ traces (0.18.2)
219
+ tsort (0.2.0)
62
220
  unicode-display_width (3.2.0)
63
221
  unicode-emoji (~> 4.1)
64
222
  unicode-emoji (4.2.0)
223
+ utopia (2.32.1)
224
+ bake (~> 0.20)
225
+ concurrent-ruby (~> 1.2)
226
+ console (~> 1.24)
227
+ http-accept (~> 2.1)
228
+ irb
229
+ mail (~> 2.6)
230
+ mime-types (~> 3.0)
231
+ msgpack
232
+ net-smtp
233
+ protocol-url (~> 0.4)
234
+ rack (~> 3.0)
235
+ samovar (~> 2.1)
236
+ traces (~> 0.10)
237
+ variant (~> 0.1)
238
+ xrb (~> 0.4)
239
+ utopia-project (0.40.0)
240
+ decode (~> 0.26)
241
+ falcon
242
+ markly (~> 0.15)
243
+ rackula (~> 1.3)
244
+ thread-local
245
+ utopia (~> 2.32)
246
+ variant (0.1.1)
247
+ thread-local
248
+ xrb (0.11.2)
65
249
 
66
250
  PLATFORMS
67
251
  ruby
68
252
  x86_64-linux
69
253
 
70
254
  DEPENDENCIES
255
+ bake-gem
256
+ bake-modernize
257
+ bake-releases
71
258
  kube_schema!
72
259
  rake (~> 13.0)
73
260
  rspec (~> 3.13)
74
261
  rubocop (~> 1.21)
262
+ utopia-project
75
263
 
76
264
  BUNDLED WITH
77
265
  2.6.9
@@ -0,0 +1,50 @@
1
+ # The Block DSL
2
+
3
+ This guide covers the block DSL for defining Kubernetes resources with nested attributes.
4
+
5
+ ## Nested Attributes
6
+
7
+ No intermediate hashes, no string keys:
8
+
9
+ ```ruby
10
+ deploy = Kube::Schema["Deployment"].new {
11
+ metadata.name = "web"
12
+ metadata.namespace = "prod"
13
+ metadata.labels = { app: "web" }
14
+
15
+ spec.replicas = 3
16
+ spec.selector.matchLabels = { app: "web" }
17
+
18
+ spec.template.metadata.labels = { app: "web" }
19
+ spec.template.spec.containers = [
20
+ { name: "app", image: "nginx:1.27", ports: [{ containerPort: 80 }] }
21
+ ]
22
+ }
23
+ ```
24
+
25
+ `apiVersion` and `kind` are derived from the schema automatically:
26
+
27
+ ```ruby
28
+ deploy.to_h[:apiVersion] # => "apps/v1"
29
+ deploy.to_h[:kind] # => "Deployment"
30
+ ```
31
+
32
+ ## Subclassing
33
+
34
+ ```ruby
35
+ class RailsApp < Kube::Schema["Deployment"]
36
+ def default_image
37
+ "ruby:3.4"
38
+ end
39
+ end
40
+
41
+ app = RailsApp.new {
42
+ metadata.name = "rails"
43
+ spec.template.spec.containers = [
44
+ { name: "web", image: "myapp:latest" }
45
+ ]
46
+ }
47
+
48
+ app.default_image # => "ruby:3.4"
49
+ app.valid? # => true
50
+ ```
@@ -0,0 +1,37 @@
1
+ # Getting Started
2
+
3
+ This guide walks you through installing kube_schema and creating your first Kubernetes resource object.
4
+
5
+ ## Install
6
+
7
+ ```
8
+ gem install kube_schema
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ Every Kubernetes kind is a class. Fetch it by name:
14
+
15
+ ```ruby
16
+ Kube::Schema["Deployment"] # => Class < Kube::Schema::Resource
17
+ Kube::Schema["Service"]
18
+ Kube::Schema["ConfigMap"]
19
+ Kube::Schema["NetworkPolicy"]
20
+ ```
21
+
22
+ Specific versions:
23
+
24
+ ```ruby
25
+ Kube::Schema["1.34"]["Deployment"]
26
+ Kube::Schema["1.31"]["Pod"]
27
+ ```
28
+
29
+ Discovery:
30
+
31
+ ```ruby
32
+ Kube::Schema.schema_versions # => ["1.19", "1.20", ..., "1.35"]
33
+ Kube::Schema.latest_version # => "1.35"
34
+
35
+ Kube::Schema["1.34"].list_resources
36
+ # => ["Binding", "CSIDriver", "ConfigMap", "Deployment", ...]
37
+ ```
data/guides/links.yaml ADDED
@@ -0,0 +1,10 @@
1
+ getting-started:
2
+ order: 1
3
+ block-dsl:
4
+ order: 2
5
+ validation:
6
+ order: 3
7
+ manifests:
8
+ order: 4
9
+ schema-versions:
10
+ order: 5
@@ -0,0 +1,68 @@
1
+ # Manifests
2
+
3
+ This guide covers grouping resources into multi-document YAML manifests.
4
+
5
+ ## Creating a Manifest
6
+
7
+ ```ruby
8
+ manifest = Kube::Schema::Manifest.new
9
+
10
+ manifest << Kube::Schema["Namespace"].new {
11
+ metadata.name = "prod"
12
+ }
13
+
14
+ manifest << Kube::Schema["Deployment"].new {
15
+ metadata.name = "web"
16
+ metadata.namespace = "prod"
17
+ spec.replicas = 3
18
+ spec.template.spec.containers = [
19
+ { name: "app", image: "nginx:1.27" }
20
+ ]
21
+ }
22
+
23
+ manifest << Kube::Schema["Service"].new {
24
+ metadata.name = "web"
25
+ metadata.namespace = "prod"
26
+ spec.selector = { app: "web" }
27
+ spec.ports = [{ port: 80, targetPort: 8080 }]
28
+ }
29
+
30
+ puts manifest.to_yaml
31
+ ```
32
+
33
+ ## File I/O
34
+
35
+ ```ruby
36
+ # Write
37
+ manifest.write("cluster.yaml")
38
+
39
+ # Read
40
+ loaded = Kube::Schema::Manifest.open("cluster.yaml")
41
+
42
+ # Modify and write back
43
+ loaded << new_resource
44
+ loaded.write
45
+ ```
46
+
47
+ ## Composition
48
+
49
+ Manifests flatten into each other. No nesting.
50
+
51
+ ```ruby
52
+ infra = Kube::Schema::Manifest.new(namespace, configmap, secret)
53
+ app = Kube::Schema::Manifest.new(deployment, service)
54
+
55
+ combined = Kube::Schema::Manifest.new
56
+ combined << infra
57
+ combined << app
58
+ combined.size # => 5
59
+ ```
60
+
61
+ ## Enumerable
62
+
63
+ ```ruby
64
+ manifest.map { |r| r.to_h[:kind] }
65
+ manifest.select { |r| r.to_h[:kind] == "Service" }
66
+ manifest.any? { |r| r.to_h[:kind] == "Pod" }
67
+ manifest.count
68
+ ```
@@ -0,0 +1,31 @@
1
+ # Schema Versions
2
+
3
+ This guide covers working with different Kubernetes schema versions.
4
+
5
+ ## Bundled Schemas
6
+
7
+ Bundled schemas ship with the gem for Kubernetes 1.19 through 1.35. Updated automatically via CI.
8
+
9
+ ## Setting a Version
10
+
11
+ ```ruby
12
+ Kube::Schema.schema_version = "1.31"
13
+ Kube::Schema["Deployment"] # uses 1.31
14
+ ```
15
+
16
+ ## Discovery
17
+
18
+ ```ruby
19
+ Kube::Schema.schema_versions # => ["1.19", "1.20", ..., "1.35"]
20
+ Kube::Schema.latest_version # => "1.35"
21
+
22
+ Kube::Schema["1.34"].list_resources
23
+ # => ["Binding", "CSIDriver", "ConfigMap", "Deployment", ...]
24
+ ```
25
+
26
+ ## Version-Specific Access
27
+
28
+ ```ruby
29
+ Kube::Schema["1.34"]["Deployment"]
30
+ Kube::Schema["1.31"]["Pod"]
31
+ ```
@@ -0,0 +1,31 @@
1
+ # Validation
2
+
3
+ This guide covers schema validation against the full Kubernetes OpenAPI spec.
4
+
5
+ ## Basic Validation
6
+
7
+ ```ruby
8
+ deploy.valid? # => true
9
+
10
+ bad = Kube::Schema["Deployment"].new {
11
+ self.apiVersion = 12345
12
+ }
13
+
14
+ bad.valid? # => false
15
+
16
+ bad.valid!
17
+ # Kube::ValidationError: Schema validation failed for Deployment:
18
+ # - apiVersion = 12345 -- expected string, got Integer
19
+ ```
20
+
21
+ ## Serialization Safety
22
+
23
+ `to_yaml` refuses to serialize invalid resources:
24
+
25
+ ```ruby
26
+ bad.to_yaml # raises Kube::ValidationError
27
+ ```
28
+
29
+ ## Error Messages
30
+
31
+ Validation errors render annotated YAML with color-coded diagnostics. Error lines are highlighted in red, missing required keys are injected inline, and each problem gets a clear explanation.
data/kube_schema.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.metadata["homepage_uri"] = spec.homepage
22
22
  spec.metadata["source_code_uri"] = spec.homepage
23
- spec.metadata["documentation_uri"] = spec.homepage
23
+ spec.metadata["documentation_uri"] = "https://general-intelligence-systems.github.io/kube_schema/"
24
24
  spec.metadata["rubygems_mfa_required"] = "true"
25
25
 
26
26
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
@@ -33,4 +33,22 @@ class Hash
33
33
  def self.vivify(&block)
34
34
  new.tap { |h| h.instance_exec(&block) }
35
35
  end
36
+
37
+ # Deep-stringify keys so symbol keys don't leak into YAML as `:key:`.
38
+ def to_yaml(*)
39
+ Hash._deep_stringify_keys(self).then { |h| Psych.dump(h) }
40
+ end
41
+
42
+ def self._deep_stringify_keys(obj)
43
+ case obj
44
+ when Hash
45
+ obj.each_with_object({}) do |(k, v), result|
46
+ result[k.to_s] = _deep_stringify_keys(v)
47
+ end
48
+ when Array
49
+ obj.map { |v| _deep_stringify_keys(v) }
50
+ else
51
+ obj
52
+ end
53
+ end
36
54
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kube
4
4
  module Schema
5
- VERSION = "1.4.3"
5
+ VERSION = "1.4.4"
6
6
  end
7
7
  end
data/readme.md ADDED
@@ -0,0 +1,28 @@
1
+ # kube_schema
2
+
3
+ Ruby objects for every Kubernetes resource. Validated against the real OpenAPI spec. No YAML. No hash literals. Just Ruby blocks that know their schema.
4
+
5
+ ## Usage
6
+
7
+ Please see the [project documentation](https://general-intelligence-systems.github.io/kube_schema/) for more details.
8
+
9
+ - [Getting Started](https://general-intelligence-systems.github.io/kube_schema/guides/getting-started/index) - This guide walks you through installing kube_schema and creating your first Kubernetes resource object.
10
+
11
+ - [The Block DSL](https://general-intelligence-systems.github.io/kube_schema/guides/block-dsl/index) - This guide covers the block DSL for defining Kubernetes resources with nested attributes.
12
+
13
+ - [Validation](https://general-intelligence-systems.github.io/kube_schema/guides/validation/index) - This guide covers schema validation against the full Kubernetes OpenAPI spec.
14
+
15
+ - [Manifests](https://general-intelligence-systems.github.io/kube_schema/guides/manifests/index) - This guide covers grouping resources into multi-document YAML manifests.
16
+
17
+ - [Schema Versions](https://general-intelligence-systems.github.io/kube_schema/guides/schema-versions/index) - This guide covers working with different Kubernetes schema versions.
18
+
19
+ ## Related Projects
20
+
21
+ - [kube_cluster](https://github.com/general-intelligence-systems/kube_cluster) -- OOP resource management with dirty tracking and persistence
22
+ - [kube_kubectl](https://github.com/general-intelligence-systems/kube_ctl) -- Ruby DSL that compiles to kubectl and helm commands
23
+ - [kube_kit](https://github.com/general-intelligence-systems/kube_kit) -- Generators for kube_cluster projects
24
+ - [kube_engine](https://github.com/general-intelligence-systems/kube_engine) -- Kubernetes engine
25
+
26
+ ## License
27
+
28
+ Apache-2.0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kube_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan K
@@ -91,6 +91,7 @@ extra_rdoc_files: []
91
91
  files:
92
92
  - ".envrc"
93
93
  - ".github/workflows/convert-schemas.yml"
94
+ - ".github/workflows/gh-pages.yml"
94
95
  - ".github/workflows/update-crds-catalog.yml"
95
96
  - ".github/workflows/update-schema-index.yml"
96
97
  - ".github/workflows/update-schemas.yml"
@@ -98,7 +99,6 @@ files:
98
99
  - ".rubocop.yml"
99
100
  - Gemfile
100
101
  - Gemfile.lock
101
- - README.md
102
102
  - Rakefile
103
103
  - assets/validation-error.png
104
104
  - bin/console
@@ -117,6 +117,12 @@ files:
117
117
  - examples/vcluster.rb
118
118
  - flake.lock
119
119
  - flake.nix
120
+ - guides/block-dsl/readme.md
121
+ - guides/getting-started/readme.md
122
+ - guides/links.yaml
123
+ - guides/manifests/readme.md
124
+ - guides/schema-versions/readme.md
125
+ - guides/validation/readme.md
120
126
  - kube_schema.gemspec
121
127
  - lib/kube/errors.rb
122
128
  - lib/kube/monkey_patches.rb
@@ -127,6 +133,7 @@ files:
127
133
  - lib/kube/schema/sub_spec.rb
128
134
  - lib/kube/schema/version.rb
129
135
  - lib/kube/schema/version.rb.erb
136
+ - readme.md
130
137
  - schemas/crd-definitions.json
131
138
  - schemas/kubevirt-definitions.json
132
139
  - schemas/loft-definitions.json
@@ -144,7 +151,7 @@ licenses:
144
151
  metadata:
145
152
  homepage_uri: https://github.com/general-intelligence-systems/kube_schema
146
153
  source_code_uri: https://github.com/general-intelligence-systems/kube_schema
147
- documentation_uri: https://github.com/general-intelligence-systems/kube_schema
154
+ documentation_uri: https://general-intelligence-systems.github.io/kube_schema/
148
155
  rubygems_mfa_required: 'true'
149
156
  rdoc_options: []
150
157
  require_paths:
data/README.md DELETED
@@ -1,259 +0,0 @@
1
- # kube_schema
2
-
3
- Ruby objects for every Kubernetes resource. Validated against the real OpenAPI spec.
4
-
5
- ```ruby
6
- Kube::Schema["Deployment"].new {
7
- metadata.name = "web"
8
- metadata.namespace = "prod"
9
- spec.replicas = 3
10
- spec.template.spec.containers = [
11
- { name: "app", image: "nginx:1.27", ports: [{ containerPort: 80 }] }
12
- ]
13
- }
14
- ```
15
-
16
- No YAML. No hash literals. Just Ruby blocks that know their schema.
17
-
18
- ## Contents
19
-
20
- - [Install](#install)
21
- - [Resources](#resources)
22
- - [The block DSL](#the-block-dsl)
23
- - [Subclassing](#subclassing)
24
- - [Validation](#validation)
25
- - [Error messages](#error-messages)
26
- - [Manifests](#manifests)
27
- - [File I/O](#file-io)
28
- - [Composition](#composition)
29
- - [Enumerable](#enumerable)
30
- - [Schema versions](#schema-versions)
31
- - [Related projects](#related-projects)
32
- - [Built with](#built-with)
33
-
34
- ## Install
35
-
36
- ```
37
- gem install kube_schema
38
- ```
39
-
40
- ## Resources
41
-
42
- Every Kubernetes kind is a class. Fetch it by name.
43
-
44
- ```ruby
45
- Kube::Schema["Deployment"] # => Class < Kube::Schema::Resource
46
- Kube::Schema["Service"]
47
- Kube::Schema["ConfigMap"]
48
- Kube::Schema["NetworkPolicy"]
49
- ```
50
-
51
- Specific versions:
52
-
53
- ```ruby
54
- Kube::Schema["1.34"]["Deployment"]
55
- Kube::Schema["1.31"]["Pod"]
56
- ```
57
-
58
- Discovery:
59
-
60
- ```ruby
61
- Kube::Schema.schema_versions # => ["1.19", "1.20", ..., "1.35"]
62
- Kube::Schema.latest_version # => "1.35"
63
-
64
- Kube::Schema["1.34"].list_resources
65
- # => ["Binding", "CSIDriver", "ConfigMap", "Deployment", ...]
66
- ```
67
-
68
- ## The block DSL
69
-
70
- Nested attributes just work. No intermediate hashes, no string keys.
71
-
72
- ```ruby
73
- deploy = Kube::Schema["Deployment"].new {
74
- metadata.name = "web"
75
- metadata.namespace = "prod"
76
- metadata.labels = { app: "web" }
77
-
78
- spec.replicas = 3
79
- spec.selector.matchLabels = { app: "web" }
80
-
81
- spec.template.metadata.labels = { app: "web" }
82
- spec.template.spec.containers = [
83
- { name: "app", image: "nginx:1.27", ports: [{ containerPort: 80 }] }
84
- ]
85
- }
86
- ```
87
-
88
- `apiVersion` and `kind` are derived from the schema automatically:
89
-
90
- ```ruby
91
- deploy.to_h[:apiVersion] # => "apps/v1"
92
- deploy.to_h[:kind] # => "Deployment"
93
- ```
94
-
95
- ## Subclassing
96
-
97
- ```ruby
98
- class RailsApp < Kube::Schema["Deployment"]
99
- def default_image
100
- "ruby:3.4"
101
- end
102
- end
103
-
104
- app = RailsApp.new {
105
- metadata.name = "rails"
106
- spec.template.spec.containers = [
107
- { name: "web", image: "myapp:latest" }
108
- ]
109
- }
110
-
111
- app.default_image # => "ruby:3.4"
112
- app.valid? # => true
113
- ```
114
-
115
- ## Validation
116
-
117
- Every resource validates against the full Kubernetes OpenAPI spec.
118
-
119
- ```ruby
120
- deploy.valid? # => true
121
-
122
- bad = Kube::Schema["Deployment"].new {
123
- self.apiVersion = 12345
124
- }
125
-
126
- bad.valid? # => false
127
-
128
- bad.valid!
129
- # Kube::ValidationError: Schema validation failed for Deployment:
130
- # - apiVersion = 12345 — expected string, got Integer
131
- ```
132
-
133
- `to_yaml` refuses to serialize invalid resources:
134
-
135
- ```ruby
136
- bad.to_yaml # raises Kube::ValidationError
137
- ```
138
-
139
- ## Error messages
140
-
141
- Validation errors render annotated YAML with color-coded diagnostics. Error lines are highlighted in red, missing required keys are injected inline, and each problem gets a clear explanation:
142
-
143
- ![Validation error output](assets/validation-error.png)
144
-
145
- ## Manifests
146
-
147
- Group resources into multi-document YAML.
148
-
149
- ```ruby
150
- manifest = Kube::Schema::Manifest.new
151
-
152
- manifest << Kube::Schema["Namespace"].new {
153
- metadata.name = "prod"
154
- }
155
-
156
- manifest << Kube::Schema["Deployment"].new {
157
- metadata.name = "web"
158
- metadata.namespace = "prod"
159
- spec.replicas = 3
160
- spec.template.spec.containers = [
161
- { name: "app", image: "nginx:1.27" }
162
- ]
163
- }
164
-
165
- manifest << Kube::Schema["Service"].new {
166
- metadata.name = "web"
167
- metadata.namespace = "prod"
168
- spec.selector = { app: "web" }
169
- spec.ports = [{ port: 80, targetPort: 8080 }]
170
- }
171
-
172
- puts manifest.to_yaml
173
- ```
174
-
175
- ```yaml
176
- ---
177
- apiVersion: v1
178
- kind: Namespace
179
- metadata:
180
- name: prod
181
- ---
182
- apiVersion: apps/v1
183
- kind: Deployment
184
- metadata:
185
- name: web
186
- namespace: prod
187
- spec:
188
- replicas: 3
189
- ...
190
- ---
191
- apiVersion: v1
192
- kind: Service
193
- metadata:
194
- name: web
195
- namespace: prod
196
- spec:
197
- selector:
198
- app: web
199
- ports:
200
- - port: 80
201
- targetPort: 8080
202
- ```
203
-
204
- ### File I/O
205
-
206
- ```ruby
207
- # Write
208
- manifest.write("cluster.yaml")
209
-
210
- # Read
211
- loaded = Kube::Schema::Manifest.open("cluster.yaml")
212
-
213
- # Modify and write back
214
- loaded << new_resource
215
- loaded.write
216
- ```
217
-
218
- ### Composition
219
-
220
- Manifests flatten into each other. No nesting.
221
-
222
- ```ruby
223
- infra = Kube::Schema::Manifest.new(namespace, configmap, secret)
224
- app = Kube::Schema::Manifest.new(deployment, service)
225
-
226
- combined = Kube::Schema::Manifest.new
227
- combined << infra
228
- combined << app
229
- combined.size # => 5
230
- ```
231
-
232
- ### Enumerable
233
-
234
- ```ruby
235
- manifest.map { |r| r.to_h[:kind] }
236
- manifest.select { |r| r.to_h[:kind] == "Service" }
237
- manifest.any? { |r| r.to_h[:kind] == "Pod" }
238
- manifest.count
239
- ```
240
-
241
- ## Schema versions
242
-
243
- Bundled schemas ship with the gem for Kubernetes 1.19 through 1.35. Updated automatically via CI.
244
-
245
- ```ruby
246
- Kube::Schema.schema_version = "1.31"
247
- Kube::Schema["Deployment"] # uses 1.31
248
- ```
249
-
250
- ## Related projects
251
-
252
- - [kube_cluster](https://github.com/general-intelligence-systems/kube_cluster) -- OOP resource management with dirty tracking and persistence
253
- - [kube_kubectl](https://github.com/general-intelligence-systems/kube_ctl) -- Ruby DSL that compiles to kubectl and helm commands
254
- - [kube_kit](https://github.com/general-intelligence-systems/kube_kit) -- Generators for kube_cluster projects
255
- - [kube_engine](https://github.com/general-intelligence-systems/kube_engine) -- Kubernetes engine
256
-
257
- ## Built with
258
-
259
- [json_schemer](https://github.com/davishmcclurg/json_schemer) -- JSON Schema validation against the real Kubernetes OpenAPI specs.