kube_cluster 0.3.8 → 0.3.9

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.
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if __FILE__ == $0
4
- require "bundler/setup"
5
- require "kube/cluster"
6
- end
3
+ require "bundler/setup"
4
+ require "kube/cluster"
7
5
 
8
6
  module Kube
9
7
  module Cluster
@@ -115,179 +113,159 @@ module Kube
115
113
  end
116
114
  end
117
115
 
118
- if __FILE__ == $0
119
- require "minitest/autorun"
120
-
121
- class HPAForDeploymentMiddlewareTest < Minitest::Test
122
- Middleware = Kube::Cluster::Middleware
123
-
124
- def test_generates_hpa_from_deployment
125
- m = manifest(Kube::Cluster["Deployment"].new {
126
- metadata.name = "web"
127
- metadata.namespace = "production"
128
- metadata.labels = {
129
- "app.kubernetes.io/name": "web",
130
- "app.kubernetes.io/autoscale": "2-10",
131
- }
132
- spec.selector.matchLabels = { app: "web" }
133
- spec.template.metadata.labels = { app: "web" }
134
- spec.template.spec.containers = [
135
- { name: "web", image: "nginx" },
136
- ]
137
- })
116
+ test do
117
+ Middleware = Kube::Cluster::Middleware
118
+
119
+ it "generates_hpa_from_deployment" do
120
+ m = manifest(Kube::Cluster["Deployment"].new {
121
+ metadata.name = "web"
122
+ metadata.namespace = "production"
123
+ metadata.labels = {
124
+ "app.kubernetes.io/name": "web",
125
+ "app.kubernetes.io/autoscale": "2-10",
126
+ }
127
+ spec.selector.matchLabels = { app: "web" }
128
+ spec.template.metadata.labels = { app: "web" }
129
+ spec.template.spec.containers = [
130
+ { name: "web", image: "nginx" },
131
+ ]
132
+ })
133
+
134
+ Middleware::HPAForDeployment.new.call(m)
135
+
136
+ deploy, hpa = m.resources
137
+ hh = hpa.to_h
138
+ metrics = hh.dig(:spec, :metrics)
139
+
140
+ metrics[1].dig(:resource, :target, :averageUtilization).should == 80
141
+ end
138
142
 
139
- Middleware::HPAForDeployment.new.call(m)
143
+ it "custom_cpu_and_memory_targets" do
144
+ m = manifest(Kube::Cluster["Deployment"].new {
145
+ metadata.name = "web"
146
+ metadata.labels = { "app.kubernetes.io/autoscale": "1-3" }
147
+ spec.selector.matchLabels = { app: "web" }
148
+ spec.template.metadata.labels = { app: "web" }
149
+ spec.template.spec.containers = [
150
+ { name: "web", image: "nginx" },
151
+ ]
152
+ })
153
+
154
+ Middleware::HPAForDeployment.new(cpu: 60, memory: 70).call(m)
155
+ hpa = m.resources.last.to_h
156
+
157
+ hpa.dig(:spec, :metrics, 1, :resource, :target, :averageUtilization).should == 70
158
+ end
140
159
 
141
- assert_equal 2, m.resources.size
142
-
143
- deploy, hpa = m.resources
144
- assert_equal "Deployment", deploy.to_h[:kind]
145
- assert_equal "HorizontalPodAutoscaler", hpa.to_h[:kind]
146
-
147
- hh = hpa.to_h
148
- assert_equal "web", hh.dig(:metadata, :name)
149
- assert_equal "production", hh.dig(:metadata, :namespace)
150
- assert_equal 2, hh.dig(:spec, :minReplicas)
151
- assert_equal 10, hh.dig(:spec, :maxReplicas)
152
-
153
- ref = hh.dig(:spec, :scaleTargetRef)
154
- assert_equal "apps/v1", ref[:apiVersion]
155
- assert_equal "Deployment", ref[:kind]
156
- assert_equal "web", ref[:name]
157
-
158
- metrics = hh.dig(:spec, :metrics)
159
- assert_equal 2, metrics.size
160
- assert_equal "cpu", metrics[0].dig(:resource, :name)
161
- assert_equal 75, metrics[0].dig(:resource, :target, :averageUtilization)
162
- assert_equal "memory", metrics[1].dig(:resource, :name)
163
- assert_equal 80, metrics[1].dig(:resource, :target, :averageUtilization)
164
- end
160
+ it "strips_autoscale_label_from_hpa" do
161
+ m = manifest(Kube::Cluster["Deployment"].new {
162
+ metadata.name = "web"
163
+ metadata.labels = {
164
+ "app.kubernetes.io/name": "web",
165
+ "app.kubernetes.io/autoscale": "1-5",
166
+ }
167
+ spec.selector.matchLabels = { app: "web" }
168
+ spec.template.metadata.labels = { app: "web" }
169
+ spec.template.spec.containers = [
170
+ { name: "web", image: "nginx" },
171
+ ]
172
+ })
173
+
174
+ Middleware::HPAForDeployment.new.call(m)
175
+ hpa_labels = m.resources.last.to_h.dig(:metadata, :labels)
176
+
177
+ hpa_labels[:"app.kubernetes.io/autoscale"].should.be.nil
178
+ end
165
179
 
166
- def test_custom_cpu_and_memory_targets
167
- m = manifest(Kube::Cluster["Deployment"].new {
168
- metadata.name = "web"
169
- metadata.labels = { "app.kubernetes.io/autoscale": "1-3" }
170
- spec.selector.matchLabels = { app: "web" }
171
- spec.template.metadata.labels = { app: "web" }
172
- spec.template.spec.containers = [
173
- { name: "web", image: "nginx" },
174
- ]
175
- })
176
-
177
- Middleware::HPAForDeployment.new(cpu: 60, memory: 70).call(m)
178
- hpa = m.resources.last.to_h
179
-
180
- assert_equal 60, hpa.dig(:spec, :metrics, 0, :resource, :target, :averageUtilization)
181
- assert_equal 70, hpa.dig(:spec, :metrics, 1, :resource, :target, :averageUtilization)
182
- end
180
+ it "skips_deployment_without_autoscale_label" do
181
+ m = manifest(Kube::Cluster["Deployment"].new {
182
+ metadata.name = "web"
183
+ spec.selector.matchLabels = { app: "web" }
184
+ spec.template.metadata.labels = { app: "web" }
185
+ spec.template.spec.containers = [
186
+ { name: "web", image: "nginx" },
187
+ ]
188
+ })
183
189
 
184
- def test_strips_autoscale_label_from_hpa
185
- m = manifest(Kube::Cluster["Deployment"].new {
186
- metadata.name = "web"
187
- metadata.labels = {
188
- "app.kubernetes.io/name": "web",
189
- "app.kubernetes.io/autoscale": "1-5",
190
- }
191
- spec.selector.matchLabels = { app: "web" }
192
- spec.template.metadata.labels = { app: "web" }
193
- spec.template.spec.containers = [
194
- { name: "web", image: "nginx" },
195
- ]
196
- })
190
+ Middleware::HPAForDeployment.new.call(m)
197
191
 
198
- Middleware::HPAForDeployment.new.call(m)
199
- hpa_labels = m.resources.last.to_h.dig(:metadata, :labels)
192
+ m.resources.size.should == 1
193
+ end
200
194
 
201
- assert_nil hpa_labels[:"app.kubernetes.io/autoscale"]
202
- assert_equal "web", hpa_labels[:"app.kubernetes.io/name"]
203
- end
195
+ it "skips_non_pod_bearing_resources" do
196
+ m = manifest(Kube::Cluster["ConfigMap"].new {
197
+ metadata.name = "config"
198
+ metadata.labels = { "app.kubernetes.io/autoscale": "1-5" }
199
+ })
204
200
 
205
- def test_skips_deployment_without_autoscale_label
206
- m = manifest(Kube::Cluster["Deployment"].new {
207
- metadata.name = "web"
208
- spec.selector.matchLabels = { app: "web" }
209
- spec.template.metadata.labels = { app: "web" }
210
- spec.template.spec.containers = [
211
- { name: "web", image: "nginx" },
212
- ]
213
- })
201
+ Middleware::HPAForDeployment.new.call(m)
214
202
 
215
- Middleware::HPAForDeployment.new.call(m)
203
+ m.resources.size.should == 1
204
+ end
216
205
 
217
- assert_equal 1, m.resources.size
206
+ it "raises_on_invalid_range_format" do
207
+ m = manifest(Kube::Cluster["Deployment"].new {
208
+ metadata.name = "web"
209
+ metadata.labels = { "app.kubernetes.io/autoscale": "bad" }
210
+ spec.selector.matchLabels = { app: "web" }
211
+ spec.template.metadata.labels = { app: "web" }
212
+ spec.template.spec.containers = [
213
+ { name: "web", image: "nginx" },
214
+ ]
215
+ })
216
+
217
+ error = nil
218
+ begin
219
+ Middleware::HPAForDeployment.new.call(m)
220
+ rescue ArgumentError => e
221
+ error = e
218
222
  end
219
223
 
220
- def test_skips_non_pod_bearing_resources
221
- m = manifest(Kube::Cluster["ConfigMap"].new {
222
- metadata.name = "config"
223
- metadata.labels = { "app.kubernetes.io/autoscale": "1-5" }
224
- })
224
+ error.message.should.include "Invalid autoscale label"
225
+ end
225
226
 
227
+ it "raises_on_invalid_range_values" do
228
+ m = manifest(Kube::Cluster["Deployment"].new {
229
+ metadata.name = "web"
230
+ metadata.labels = { "app.kubernetes.io/autoscale": "5-2" }
231
+ spec.selector.matchLabels = { app: "web" }
232
+ spec.template.metadata.labels = { app: "web" }
233
+ spec.template.spec.containers = [
234
+ { name: "web", image: "nginx" },
235
+ ]
236
+ })
237
+
238
+ error = nil
239
+ begin
226
240
  Middleware::HPAForDeployment.new.call(m)
227
-
228
- assert_equal 1, m.resources.size
241
+ rescue ArgumentError => e
242
+ error = e
229
243
  end
230
244
 
231
- def test_raises_on_invalid_range_format
232
- m = manifest(Kube::Cluster["Deployment"].new {
233
- metadata.name = "web"
234
- metadata.labels = { "app.kubernetes.io/autoscale": "bad" }
235
- spec.selector.matchLabels = { app: "web" }
236
- spec.template.metadata.labels = { app: "web" }
237
- spec.template.spec.containers = [
238
- { name: "web", image: "nginx" },
239
- ]
240
- })
241
-
242
- error = assert_raises(ArgumentError) do
243
- Middleware::HPAForDeployment.new.call(m)
244
- end
245
-
246
- assert_includes error.message, "Invalid autoscale label"
247
- end
245
+ error.message.should.include "Invalid autoscale range"
246
+ end
248
247
 
249
- def test_raises_on_invalid_range_values
250
- m = manifest(Kube::Cluster["Deployment"].new {
251
- metadata.name = "web"
252
- metadata.labels = { "app.kubernetes.io/autoscale": "5-2" }
253
- spec.selector.matchLabels = { app: "web" }
254
- spec.template.metadata.labels = { app: "web" }
255
- spec.template.spec.containers = [
256
- { name: "web", image: "nginx" },
257
- ]
258
- })
259
-
260
- error = assert_raises(ArgumentError) do
261
- Middleware::HPAForDeployment.new.call(m)
262
- end
248
+ it "works_with_statefulset" do
249
+ m = manifest(Kube::Cluster["StatefulSet"].new {
250
+ metadata.name = "db"
251
+ metadata.labels = { "app.kubernetes.io/autoscale": "1-3" }
252
+ spec.selector.matchLabels = { app: "db" }
253
+ spec.template.metadata.labels = { app: "db" }
254
+ spec.template.spec.containers = [
255
+ { name: "postgres", image: "postgres:16" },
256
+ ]
257
+ })
263
258
 
264
- assert_includes error.message, "Invalid autoscale range"
265
- end
259
+ Middleware::HPAForDeployment.new.call(m)
266
260
 
267
- def test_works_with_statefulset
268
- m = manifest(Kube::Cluster["StatefulSet"].new {
269
- metadata.name = "db"
270
- metadata.labels = { "app.kubernetes.io/autoscale": "1-3" }
271
- spec.selector.matchLabels = { app: "db" }
272
- spec.template.metadata.labels = { app: "db" }
273
- spec.template.spec.containers = [
274
- { name: "postgres", image: "postgres:16" },
275
- ]
276
- })
261
+ m.resources.last.to_h.dig(:spec, :scaleTargetRef, :kind).should == "StatefulSet"
262
+ end
277
263
 
278
- Middleware::HPAForDeployment.new.call(m)
264
+ private
279
265
 
280
- assert_equal 2, m.resources.size
281
- hpa = m.resources.last.to_h
282
- assert_equal "StatefulSet", hpa.dig(:spec, :scaleTargetRef, :kind)
266
+ def manifest(*resources)
267
+ m = Kube::Cluster::Manifest.new
268
+ resources.each { |r| m << r }
269
+ m
283
270
  end
284
-
285
- private
286
-
287
- def manifest(*resources)
288
- m = Kube::Cluster::Manifest.new
289
- resources.each { |r| m << r }
290
- m
291
- end
292
- end
293
271
  end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if __FILE__ == $0
4
- require "bundler/setup"
5
- require "kube/cluster"
6
- end
3
+ require "bundler/setup"
4
+ require "kube/cluster"
7
5
 
8
6
  module Kube
9
7
  module Cluster
@@ -95,124 +93,100 @@ module Kube
95
93
  end
96
94
  end
97
95
 
98
- if __FILE__ == $0
99
- require "minitest/autorun"
100
-
101
- class IngressForServiceMiddlewareTest < Minitest::Test
102
- Middleware = Kube::Cluster::Middleware
103
-
104
- def test_generates_ingress_from_service_with_expose_label
105
- m = manifest(Kube::Cluster["Service"].new {
106
- metadata.name = "web"
107
- metadata.namespace = "production"
108
- metadata.labels = { "app.kubernetes.io/expose": "app.example.com" }
109
- spec.selector = { app: "web" }
110
- spec.ports = [{ name: "http", port: 80, targetPort: "http" }]
111
- })
112
-
113
- Middleware::IngressForService.new.call(m)
114
-
115
- assert_equal 2, m.resources.size
116
-
117
- service, ingress = m.resources
118
- assert_equal "Service", service.to_h[:kind]
119
- assert_equal "Ingress", ingress.to_h[:kind]
120
-
121
- ih = ingress.to_h
122
- assert_equal "web", ih.dig(:metadata, :name)
123
- assert_equal "production", ih.dig(:metadata, :namespace)
124
- assert_equal "nginx", ih.dig(:spec, :ingressClassName)
125
- assert_equal "letsencrypt-prod", ih.dig(:metadata, :annotations, :"cert-manager.io/cluster-issuer")
126
- assert_equal "true", ih.dig(:metadata, :annotations, :"nginx.ingress.kubernetes.io/ssl-redirect")
127
-
128
- # TLS
129
- tls = ih.dig(:spec, :tls, 0)
130
- assert_equal ["app.example.com"], tls[:hosts]
131
- assert_equal "web-tls", tls[:secretName]
132
-
133
- # Rules
134
- rule = ih.dig(:spec, :rules, 0)
135
- assert_equal "app.example.com", rule[:host]
136
- assert_equal "web", rule.dig(:http, :paths, 0, :backend, :service, :name)
137
- assert_equal "http", rule.dig(:http, :paths, 0, :backend, :service, :port, :name)
138
- end
96
+ test do
97
+ Middleware = Kube::Cluster::Middleware
139
98
 
140
- def test_custom_issuer_and_ingress_class
141
- m = manifest(Kube::Cluster["Service"].new {
142
- metadata.name = "web"
143
- metadata.labels = { "app.kubernetes.io/expose": "app.example.com" }
144
- spec.ports = [{ name: "http", port: 80 }]
145
- })
146
-
147
- Middleware::IngressForService.new(
148
- issuer: "letsencrypt-staging",
149
- ingress_class: "traefik",
150
- ).call(m)
151
-
152
- ingress = m.resources.last.to_h
153
- assert_equal "traefik", ingress.dig(:spec, :ingressClassName)
154
- assert_equal "letsencrypt-staging", ingress.dig(:metadata, :annotations, :"cert-manager.io/cluster-issuer")
155
- end
99
+ it "generates_ingress_from_service_with_expose_label" do
100
+ m = manifest(Kube::Cluster["Service"].new {
101
+ metadata.name = "web"
102
+ metadata.namespace = "production"
103
+ metadata.labels = { "app.kubernetes.io/expose": "app.example.com" }
104
+ spec.selector = { app: "web" }
105
+ spec.ports = [{ name: "http", port: 80, targetPort: "http" }]
106
+ })
156
107
 
157
- def test_expose_true_uses_name_as_hostname
158
- m = manifest(Kube::Cluster["Service"].new {
159
- metadata.name = "api"
160
- metadata.labels = { "app.kubernetes.io/expose": "true" }
161
- spec.ports = [{ name: "http", port: 80 }]
162
- })
108
+ Middleware::IngressForService.new.call(m)
163
109
 
164
- Middleware::IngressForService.new.call(m)
165
- ingress = m.resources.last.to_h
110
+ service, ingress = m.resources
111
+ ih = ingress.to_h
112
+ rule = ih.dig(:spec, :rules, 0)
166
113
 
167
- assert_equal "api.local", ingress.dig(:spec, :rules, 0, :host)
168
- assert_equal ["api.local"], ingress.dig(:spec, :tls, 0, :hosts)
169
- end
114
+ rule.dig(:http, :paths, 0, :backend, :service, :port, :name).should == "http"
115
+ end
170
116
 
171
- def test_strips_expose_label_from_ingress
172
- m = manifest(Kube::Cluster["Service"].new {
173
- metadata.name = "web"
174
- metadata.labels = {
175
- "app.kubernetes.io/expose": "app.example.com",
176
- "app.kubernetes.io/name": "web",
177
- }
178
- spec.ports = [{ name: "http", port: 80 }]
179
- })
180
-
181
- Middleware::IngressForService.new.call(m)
182
- ingress_labels = m.resources.last.to_h.dig(:metadata, :labels)
183
-
184
- assert_nil ingress_labels[:"app.kubernetes.io/expose"]
185
- assert_equal "web", ingress_labels[:"app.kubernetes.io/name"]
186
- end
117
+ it "custom_issuer_and_ingress_class" do
118
+ m = manifest(Kube::Cluster["Service"].new {
119
+ metadata.name = "web"
120
+ metadata.labels = { "app.kubernetes.io/expose": "app.example.com" }
121
+ spec.ports = [{ name: "http", port: 80 }]
122
+ })
187
123
 
188
- def test_skips_service_without_expose_label
189
- m = manifest(Kube::Cluster["Service"].new {
190
- metadata.name = "web"
191
- spec.ports = [{ name: "http", port: 80 }]
192
- })
124
+ Middleware::IngressForService.new(
125
+ issuer: "letsencrypt-staging",
126
+ ingress_class: "traefik",
127
+ ).call(m)
193
128
 
194
- Middleware::IngressForService.new.call(m)
129
+ ingress = m.resources.last.to_h
195
130
 
196
- assert_equal 1, m.resources.size
197
- end
131
+ ingress.dig(:metadata, :annotations, :"cert-manager.io/cluster-issuer").should == "letsencrypt-staging"
132
+ end
198
133
 
199
- def test_skips_non_service_resources
200
- m = manifest(Kube::Cluster["Deployment"].new {
201
- metadata.name = "web"
202
- metadata.labels = { "app.kubernetes.io/expose": "app.example.com" }
203
- })
134
+ it "expose_true_uses_name_as_hostname" do
135
+ m = manifest(Kube::Cluster["Service"].new {
136
+ metadata.name = "api"
137
+ metadata.labels = { "app.kubernetes.io/expose": "true" }
138
+ spec.ports = [{ name: "http", port: 80 }]
139
+ })
204
140
 
205
- Middleware::IngressForService.new.call(m)
141
+ Middleware::IngressForService.new.call(m)
142
+ ingress = m.resources.last.to_h
206
143
 
207
- assert_equal 1, m.resources.size
208
- end
144
+ ingress.dig(:spec, :tls, 0, :hosts).should == ["api.local"]
145
+ end
209
146
 
210
- private
147
+ it "strips_expose_label_from_ingress" do
148
+ m = manifest(Kube::Cluster["Service"].new {
149
+ metadata.name = "web"
150
+ metadata.labels = {
151
+ "app.kubernetes.io/expose": "app.example.com",
152
+ "app.kubernetes.io/name": "web",
153
+ }
154
+ spec.ports = [{ name: "http", port: 80 }]
155
+ })
211
156
 
212
- def manifest(*resources)
213
- m = Kube::Cluster::Manifest.new
214
- resources.each { |r| m << r }
215
- m
216
- end
157
+ Middleware::IngressForService.new.call(m)
158
+ ingress_labels = m.resources.last.to_h.dig(:metadata, :labels)
159
+
160
+ ingress_labels[:"app.kubernetes.io/expose"].should.be.nil
217
161
  end
162
+
163
+ it "skips_service_without_expose_label" do
164
+ m = manifest(Kube::Cluster["Service"].new {
165
+ metadata.name = "web"
166
+ spec.ports = [{ name: "http", port: 80 }]
167
+ })
168
+
169
+ Middleware::IngressForService.new.call(m)
170
+
171
+ m.resources.size.should == 1
172
+ end
173
+
174
+ it "skips_non_service_resources" do
175
+ m = manifest(Kube::Cluster["Deployment"].new {
176
+ metadata.name = "web"
177
+ metadata.labels = { "app.kubernetes.io/expose": "app.example.com" }
178
+ })
179
+
180
+ Middleware::IngressForService.new.call(m)
181
+
182
+ m.resources.size.should == 1
183
+ end
184
+
185
+ private
186
+
187
+ def manifest(*resources)
188
+ m = Kube::Cluster::Manifest.new
189
+ resources.each { |r| m << r }
190
+ m
191
+ end
218
192
  end