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 +4 -4
- data/.github/workflows/gh-pages.yml +57 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +189 -1
- data/guides/block-dsl/readme.md +50 -0
- data/guides/getting-started/readme.md +37 -0
- data/guides/links.yaml +10 -0
- data/guides/manifests/readme.md +68 -0
- data/guides/schema-versions/readme.md +31 -0
- data/guides/validation/readme.md +31 -0
- data/kube_schema.gemspec +1 -1
- data/lib/kube/monkey_patches.rb +18 -0
- data/lib/kube/schema/version.rb +1 -1
- data/readme.md +28 -0
- metadata +10 -3
- data/README.md +0 -259
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9695974cb2703c11c69c41aa624cd96cf6ac5f8bcf9859ebce423be49146250
|
|
4
|
+
data.tar.gz: 23210ffab5ca166dacfa3f1ba2ce2d24742a36127d95fa1a1b0d896c464ef1ed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
kube_schema (1.4.
|
|
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,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"] =
|
|
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)/}) }
|
data/lib/kube/monkey_patches.rb
CHANGED
|
@@ -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
|
data/lib/kube/schema/version.rb
CHANGED
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.
|
|
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://
|
|
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
|
-

|
|
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.
|