kube_cluster 0.16.0 → 0.17.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/kube/cluster/standard/cron_job_with_service_account.rb +71 -0
- data/lib/kube/cluster/standard/deployment_with_service.rb +71 -6
- data/lib/kube/cluster/standard/job_with_service_account.rb +67 -0
- data/lib/kube/cluster/standard/role.rb +6 -6
- data/lib/kube/cluster/standard/service_account_with_role.rb +6 -3
- data/lib/kube/cluster/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 928086733f7475611aa69193643f88719d926b70bb4aa3ed9d8a1c8f27efdec7
|
|
4
|
+
data.tar.gz: 3cc456aa515c6ca51fd87f26d35b2fcc740d984f8d907385a9f4b46bfc273a1c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9fb588b0b214cad46930473827384993fb0577d9997ae1a60a2a5e808eb23a792697d95e877d31e959661322b7adf1c2c31ecaf41cc7a910e132ad728f31bab4
|
|
7
|
+
data.tar.gz: 240eb7a87911cb284cd6fc2526608f843dadfee100f25b7b9611e6a27531d440604ae9c7b1d8586b26b5b926292c01f98ffd97e64c51659c0bad983629322e41
|
data/Gemfile.lock
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "kube/cluster"
|
|
5
|
+
|
|
6
|
+
module Kube
|
|
7
|
+
module Cluster
|
|
8
|
+
module Standard
|
|
9
|
+
# A CronJob plus the ServiceAccount/Role/RoleBinding it runs as, bundled
|
|
10
|
+
# into one Manifest. The RBAC rules use the Role shorthand; the CronJob's
|
|
11
|
+
# serviceAccountName is wired to the generated ServiceAccount. Everything
|
|
12
|
+
# is named after +name+.
|
|
13
|
+
#
|
|
14
|
+
# CronJobWithServiceAccount.new(
|
|
15
|
+
# name: "glauth-config-builder",
|
|
16
|
+
# image: "nixery.dev/shell/ruby/kubectl/cacert",
|
|
17
|
+
# schedule: "*/5 * * * *",
|
|
18
|
+
# rules: [
|
|
19
|
+
# "secrets" => %w[get list],
|
|
20
|
+
# "batch/jobs" => %w[create],
|
|
21
|
+
# ],
|
|
22
|
+
# command: RubyScript(<<~'BUILD'),
|
|
23
|
+
# ...
|
|
24
|
+
# BUILD
|
|
25
|
+
# )
|
|
26
|
+
#
|
|
27
|
+
class CronJobWithServiceAccount < Kube::Cluster::Manifest
|
|
28
|
+
def initialize(name:, image:, schedule:, rules:, env: {}, command: nil,
|
|
29
|
+
backoff_limit: 3, ttl: 300, concurrency_policy: "Forbid", &block)
|
|
30
|
+
service_account_with_role = Kube::Cluster::Standard::ServiceAccountWithRole.new(
|
|
31
|
+
service_account: Kube::Cluster::Standard::ServiceAccount.new(name: name),
|
|
32
|
+
role: Kube::Cluster::Standard::Role.new(rules: rules),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
cron_job = Kube::Cluster::Standard::CronJob.new(
|
|
36
|
+
name: name,
|
|
37
|
+
image: image,
|
|
38
|
+
schedule: schedule,
|
|
39
|
+
env: env,
|
|
40
|
+
command: command,
|
|
41
|
+
backoff_limit: backoff_limit,
|
|
42
|
+
ttl: ttl,
|
|
43
|
+
concurrency_policy: concurrency_policy,
|
|
44
|
+
) do
|
|
45
|
+
spec.jobTemplate.spec.template.spec.serviceAccountName = name
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
super(*service_account_with_role.to_a, cron_job)
|
|
49
|
+
|
|
50
|
+
instance_exec(&block) if block
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
test do
|
|
58
|
+
describe "CronJobWithServiceAccount" do
|
|
59
|
+
it "emits the RBAC trio plus the cron job" do
|
|
60
|
+
m = Kube::Cluster::Standard::CronJobWithServiceAccount.new(
|
|
61
|
+
name: "builder",
|
|
62
|
+
image: "nixery.dev/shell/kubectl",
|
|
63
|
+
schedule: "*/5 * * * *",
|
|
64
|
+
rules: ["secrets" => %w[get list]],
|
|
65
|
+
command: ["true"],
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
m.map { |r| r.to_h[:kind] }.sort.should == %w[CronJob Role RoleBinding ServiceAccount]
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -73,7 +73,7 @@ module Kube
|
|
|
73
73
|
|
|
74
74
|
instance_exec(&block) if block
|
|
75
75
|
|
|
76
|
-
_apply_limits(deployment)
|
|
76
|
+
deployment = _apply_limits(deployment)
|
|
77
77
|
_apply_probes(deployment)
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -88,7 +88,7 @@ module Kube
|
|
|
88
88
|
private
|
|
89
89
|
|
|
90
90
|
def _apply_limits(deployment)
|
|
91
|
-
return if @_limits.empty?
|
|
91
|
+
return deployment if @_limits.empty?
|
|
92
92
|
|
|
93
93
|
container = deployment.to_h[:spec][:template][:spec][:containers][0]
|
|
94
94
|
resources = {}
|
|
@@ -108,12 +108,12 @@ module Kube
|
|
|
108
108
|
container[:resources] = resources
|
|
109
109
|
h = deployment.to_h
|
|
110
110
|
h[:spec][:template][:spec][:containers][0] = container
|
|
111
|
-
deployment.rebuild(h)
|
|
111
|
+
_replace(deployment, deployment.rebuild(h))
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
def _apply_probes(deployment)
|
|
115
|
-
return if @_probes.empty?
|
|
116
|
-
return unless @_probes[:url]
|
|
115
|
+
return deployment if @_probes.empty?
|
|
116
|
+
return deployment unless @_probes[:url]
|
|
117
117
|
|
|
118
118
|
container = deployment.to_h[:spec][:template][:spec][:containers][0]
|
|
119
119
|
url = @_probes[:url]
|
|
@@ -140,7 +140,14 @@ module Kube
|
|
|
140
140
|
|
|
141
141
|
h = deployment.to_h
|
|
142
142
|
h[:spec][:template][:spec][:containers][0] = container
|
|
143
|
-
deployment.rebuild(h)
|
|
143
|
+
_replace(deployment, deployment.rebuild(h))
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# rebuild returns a new resource; swap it into this manifest so the
|
|
147
|
+
# change actually lands in the rendered output.
|
|
148
|
+
def _replace(old, rebuilt)
|
|
149
|
+
@resources[@resources.index(old)] = rebuilt
|
|
150
|
+
rebuilt
|
|
144
151
|
end
|
|
145
152
|
end
|
|
146
153
|
end
|
|
@@ -175,5 +182,63 @@ test do
|
|
|
175
182
|
yaml.include?("stdin: true").should == true
|
|
176
183
|
yaml.include?("tty: true").should == true
|
|
177
184
|
end
|
|
185
|
+
|
|
186
|
+
it "renders limits from the block DSL" do
|
|
187
|
+
yaml = Kube::Cluster::Standard::DeploymentWithService
|
|
188
|
+
.new(
|
|
189
|
+
name: "limited",
|
|
190
|
+
image: "ruby/ruby",
|
|
191
|
+
port: 3000,
|
|
192
|
+
) {
|
|
193
|
+
limits.cpu = { "500m" => Float::INFINITY }
|
|
194
|
+
limits.memory = { "1Gi" => "2Gi" }
|
|
195
|
+
}
|
|
196
|
+
.to_yaml
|
|
197
|
+
|
|
198
|
+
yaml.include?("cpu: 500m").should == true
|
|
199
|
+
yaml.include?("memory: 1Gi").should == true
|
|
200
|
+
yaml.include?("memory: 2Gi").should == true
|
|
201
|
+
# Infinity means request-only — no cpu limit is emitted.
|
|
202
|
+
yaml.scan(/cpu:/).length.should == 1
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "renders probes from the block DSL" do
|
|
206
|
+
yaml = Kube::Cluster::Standard::DeploymentWithService
|
|
207
|
+
.new(
|
|
208
|
+
name: "probed",
|
|
209
|
+
image: "ruby/ruby",
|
|
210
|
+
port: 3000,
|
|
211
|
+
) {
|
|
212
|
+
probes.url = { path: "/healthz", port: "http" }
|
|
213
|
+
probes.liveness = { 120 => 30 }
|
|
214
|
+
probes.readiness = { 60 => 10 }
|
|
215
|
+
}
|
|
216
|
+
.to_yaml
|
|
217
|
+
|
|
218
|
+
yaml.include?("livenessProbe").should == true
|
|
219
|
+
yaml.include?("readinessProbe").should == true
|
|
220
|
+
yaml.include?("path: \"/healthz\"").should == true
|
|
221
|
+
yaml.include?("initialDelaySeconds: 120").should == true
|
|
222
|
+
yaml.include?("initialDelaySeconds: 60").should == true
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it "renders limits and probes together" do
|
|
226
|
+
yaml = Kube::Cluster::Standard::DeploymentWithService
|
|
227
|
+
.new(
|
|
228
|
+
name: "both",
|
|
229
|
+
image: "ruby/ruby",
|
|
230
|
+
port: 3000,
|
|
231
|
+
) {
|
|
232
|
+
limits.memory = { "1Gi" => "2Gi" }
|
|
233
|
+
probes.url = { path: "/healthz", port: "http" }
|
|
234
|
+
probes.readiness = { 5 => 5 }
|
|
235
|
+
}
|
|
236
|
+
.to_yaml
|
|
237
|
+
|
|
238
|
+
# The probe pass must not clobber the limits pass (each rebuilds the
|
|
239
|
+
# deployment; the second must start from the first's result).
|
|
240
|
+
yaml.include?("memory: 2Gi").should == true
|
|
241
|
+
yaml.include?("readinessProbe").should == true
|
|
242
|
+
end
|
|
178
243
|
end
|
|
179
244
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "kube/cluster"
|
|
5
|
+
|
|
6
|
+
module Kube
|
|
7
|
+
module Cluster
|
|
8
|
+
module Standard
|
|
9
|
+
# A one-shot Job plus the ServiceAccount/Role/RoleBinding it runs as,
|
|
10
|
+
# bundled into one Manifest. The RBAC rules use the Role shorthand; the
|
|
11
|
+
# Job's serviceAccountName is wired to the generated ServiceAccount.
|
|
12
|
+
# Everything is named after +name+.
|
|
13
|
+
#
|
|
14
|
+
# JobWithServiceAccount.new(
|
|
15
|
+
# name: "glauth-config-seed",
|
|
16
|
+
# image: "nixery.dev/shell/kubectl",
|
|
17
|
+
# rules: [
|
|
18
|
+
# "batch/cronjobs" => %w[get],
|
|
19
|
+
# "batch/jobs" => %w[create],
|
|
20
|
+
# ],
|
|
21
|
+
# command: BashScript(<<~'SEED'),
|
|
22
|
+
# ...
|
|
23
|
+
# SEED
|
|
24
|
+
# )
|
|
25
|
+
#
|
|
26
|
+
class JobWithServiceAccount < Kube::Cluster::Manifest
|
|
27
|
+
def initialize(name:, image:, rules:, env: {}, command: nil,
|
|
28
|
+
backoff_limit: 3, ttl: 300, &block)
|
|
29
|
+
service_account_with_role = Kube::Cluster::Standard::ServiceAccountWithRole.new(
|
|
30
|
+
service_account: Kube::Cluster::Standard::ServiceAccount.new(name: name),
|
|
31
|
+
role: Kube::Cluster::Standard::Role.new(rules: rules),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
job = Kube::Cluster::Standard::Job.new(
|
|
35
|
+
name: name,
|
|
36
|
+
image: image,
|
|
37
|
+
env: env,
|
|
38
|
+
command: command,
|
|
39
|
+
backoff_limit: backoff_limit,
|
|
40
|
+
ttl: ttl,
|
|
41
|
+
) do
|
|
42
|
+
spec.template.spec.serviceAccountName = name
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
super(*service_account_with_role.to_a, job)
|
|
46
|
+
|
|
47
|
+
instance_exec(&block) if block
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
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
|
+
)
|
|
63
|
+
|
|
64
|
+
m.map { |r| r.to_h[:kind] }.sort.should == %w[Job Role RoleBinding ServiceAccount]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -16,12 +16,16 @@ module Kube
|
|
|
16
16
|
# ])
|
|
17
17
|
#
|
|
18
18
|
class Role < Kube::Cluster["Role"]
|
|
19
|
+
# The original rules shorthand, so a named copy can be rebuilt from it
|
|
20
|
+
# (rebuild downgrades the class; reconstructing keeps it a Standard::Role).
|
|
21
|
+
attr_reader :rules_input
|
|
22
|
+
|
|
19
23
|
def initialize(rules:, name: nil, &block)
|
|
20
|
-
|
|
24
|
+
@rules_input = rules
|
|
21
25
|
|
|
22
26
|
super() do
|
|
23
27
|
metadata.name = name if name
|
|
24
|
-
self.rules =
|
|
28
|
+
self.rules = Role.build_rules(rules)
|
|
25
29
|
instance_exec(&block) if block
|
|
26
30
|
end
|
|
27
31
|
end
|
|
@@ -30,10 +34,6 @@ module Kube
|
|
|
30
34
|
to_h.dig(:metadata, :name)
|
|
31
35
|
end
|
|
32
36
|
|
|
33
|
-
def name=(value)
|
|
34
|
-
metadata.name = value
|
|
35
|
-
end
|
|
36
|
-
|
|
37
37
|
def self.build_rules(rules)
|
|
38
38
|
entries = rules.is_a?(Hash) ? [rules] : Array(rules)
|
|
39
39
|
|
|
@@ -21,15 +21,18 @@ module Kube
|
|
|
21
21
|
class ServiceAccountWithRole < Kube::Cluster::Manifest
|
|
22
22
|
def initialize(service_account:, role:, name: nil, &block)
|
|
23
23
|
name ||= service_account.name
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
# Rebuild the Role with the derived name (a Standard::Role, so the
|
|
26
|
+
# binding's role.name reader works).
|
|
27
|
+
named_role = Kube::Cluster::Standard::Role.new(name: name, rules: role.rules_input)
|
|
25
28
|
|
|
26
29
|
role_binding = Kube::Cluster::Standard::RoleBinding.new(
|
|
27
|
-
role:
|
|
30
|
+
role: named_role,
|
|
28
31
|
service_account: service_account,
|
|
29
32
|
name: name,
|
|
30
33
|
)
|
|
31
34
|
|
|
32
|
-
super(service_account,
|
|
35
|
+
super(service_account, named_role, role_binding)
|
|
33
36
|
|
|
34
37
|
instance_exec(&block) if block
|
|
35
38
|
end
|
data/lib/kube/cluster/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.17.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan K
|
|
@@ -218,6 +218,7 @@ files:
|
|
|
218
218
|
- lib/kube/cluster/standard/cloud_native_pg/helm.rb
|
|
219
219
|
- lib/kube/cluster/standard/config_map.rb
|
|
220
220
|
- lib/kube/cluster/standard/cron_job.rb
|
|
221
|
+
- lib/kube/cluster/standard/cron_job_with_service_account.rb
|
|
221
222
|
- lib/kube/cluster/standard/custom_resource_definition.rb
|
|
222
223
|
- lib/kube/cluster/standard/daemon_set.rb
|
|
223
224
|
- lib/kube/cluster/standard/deployment_with_service.rb
|
|
@@ -226,6 +227,7 @@ files:
|
|
|
226
227
|
- lib/kube/cluster/standard/forgejo/helm.rb
|
|
227
228
|
- lib/kube/cluster/standard/gateway_api/http_route.rb
|
|
228
229
|
- lib/kube/cluster/standard/job.rb
|
|
230
|
+
- lib/kube/cluster/standard/job_with_service_account.rb
|
|
229
231
|
- lib/kube/cluster/standard/kube_virt/virtual_machine.rb
|
|
230
232
|
- lib/kube/cluster/standard/meta_controller/composite_controller.rb
|
|
231
233
|
- lib/kube/cluster/standard/meta_controller/decorator_controller.rb
|