kube_cluster 0.2.1 → 0.3.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +8 -10
  3. data/examples/01-basic-redis-pod/manifest.rb +3 -3
  4. data/examples/02-manifest-with-middleware/manifest.rb +37 -0
  5. data/examples/02-manifest-with-middleware/middleware/labels.rb +4 -0
  6. data/examples/02-manifest-with-middleware/middleware/namespace.rb +4 -0
  7. data/examples/02-manifest-with-middleware/templates/config_map.rb +13 -0
  8. data/examples/02-manifest-with-middleware/templates/deployment.rb +59 -0
  9. data/examples/02-manifest-with-middleware/templates/horizontal_pod_autoscaler.rb +30 -0
  10. data/examples/02-manifest-with-middleware/templates/ingress.rb +38 -0
  11. data/examples/02-manifest-with-middleware/templates/service.rb +12 -0
  12. data/examples/{version2 → 03-app-with-database}/demo.rb +2 -2
  13. data/examples/{version2 → 03-app-with-database}/postgresql.rb +4 -4
  14. data/examples/{version2 → 03-app-with-database}/ruby_on_rails.rb +1 -1
  15. data/kube_cluster.gemspec +1 -1
  16. data/lib/kube/cluster/manifest.rb +13 -64
  17. data/lib/kube/cluster/middleware/annotations.rb +32 -0
  18. data/lib/kube/cluster/middleware/hpa_for_deployment.rb +111 -0
  19. data/lib/kube/cluster/{manifest/middleware → middleware}/ingress_for_service.rb +36 -34
  20. data/lib/kube/cluster/middleware/labels.rb +59 -0
  21. data/lib/kube/cluster/middleware/namespace.rb +31 -0
  22. data/lib/kube/cluster/middleware/pod_anti_affinity.rb +61 -0
  23. data/lib/kube/cluster/middleware/resource_preset.rb +64 -0
  24. data/lib/kube/cluster/middleware/security_context.rb +84 -0
  25. data/lib/kube/cluster/middleware/service_for_deployment.rb +71 -0
  26. data/lib/kube/cluster/middleware/stack.rb +43 -0
  27. data/lib/kube/cluster/middleware.rb +69 -0
  28. data/lib/kube/cluster/resource.rb +78 -0
  29. data/lib/kube/cluster/version.rb +1 -1
  30. data/lib/kube/cluster.rb +21 -0
  31. metadata +27 -21
  32. data/examples/database/manifest.rb +0 -238
  33. data/examples/web-app/manifest.rb +0 -215
  34. data/lib/kube/cluster/manifest/middleware/annotations.rb +0 -32
  35. data/lib/kube/cluster/manifest/middleware/hpa_for_deployment.rb +0 -109
  36. data/lib/kube/cluster/manifest/middleware/labels.rb +0 -59
  37. data/lib/kube/cluster/manifest/middleware/namespace.rb +0 -31
  38. data/lib/kube/cluster/manifest/middleware/pod_anti_affinity.rb +0 -61
  39. data/lib/kube/cluster/manifest/middleware/resource_preset.rb +0 -64
  40. data/lib/kube/cluster/manifest/middleware/security_context.rb +0 -84
  41. data/lib/kube/cluster/manifest/middleware/service_for_deployment.rb +0 -69
  42. data/lib/kube/cluster/manifest/middleware.rb +0 -178
  43. data/lib/kube/cluster/manifest/stack.rb +0 -56
  44. /data/examples/{version2 → 03-app-with-database}/helpers.rb +0 -0
  45. /data/examples/{version2 → 03-app-with-database}/my_app.rb +0 -0
data/lib/kube/cluster.rb CHANGED
@@ -7,6 +7,7 @@ require_relative "cluster/connection"
7
7
  require_relative "cluster/instance"
8
8
  require_relative "cluster/resource"
9
9
  require_relative "cluster/manifest"
10
+ require_relative "cluster/middleware"
10
11
  require 'kube/ctl'
11
12
 
12
13
  module Kube
@@ -18,5 +19,25 @@ module Kube
18
19
  def self.connect(kubeconfig:)
19
20
  Instance.new(kubeconfig: kubeconfig)
20
21
  end
22
+
23
+ # Returns an anonymous subclass of Kube::Cluster::Resource for the
24
+ # given Kubernetes kind, mirroring Kube::Schema[kind] but with
25
+ # dirty tracking, persistence, and resource helper methods.
26
+ #
27
+ # Kube::Cluster["Deployment"].new { metadata.name = "web" }
28
+ #
29
+ def self.[](kind)
30
+ @resource_classes ||= {}
31
+ @resource_classes[kind] ||= begin
32
+ schema_class = Kube::Schema[kind]
33
+ Class.new(Resource) do
34
+ @schema = schema_class.schema
35
+ @defaults = schema_class.defaults
36
+
37
+ def self.schema = @schema || superclass.schema
38
+ def self.defaults = @defaults || superclass.defaults
39
+ end
40
+ end
41
+ end
21
42
  end
22
43
  end
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.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan K
@@ -57,14 +57,14 @@ dependencies:
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 1.2.0
60
+ version: 1.3.0
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: 1.2.0
67
+ version: 1.3.0
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: kube_kit
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -121,13 +121,19 @@ files:
121
121
  - bin/test
122
122
  - docker-compose.yml
123
123
  - examples/01-basic-redis-pod/manifest.rb
124
- - examples/database/manifest.rb
125
- - examples/version2/demo.rb
126
- - examples/version2/helpers.rb
127
- - examples/version2/my_app.rb
128
- - examples/version2/postgresql.rb
129
- - examples/version2/ruby_on_rails.rb
130
- - examples/web-app/manifest.rb
124
+ - examples/02-manifest-with-middleware/manifest.rb
125
+ - examples/02-manifest-with-middleware/middleware/labels.rb
126
+ - examples/02-manifest-with-middleware/middleware/namespace.rb
127
+ - examples/02-manifest-with-middleware/templates/config_map.rb
128
+ - examples/02-manifest-with-middleware/templates/deployment.rb
129
+ - examples/02-manifest-with-middleware/templates/horizontal_pod_autoscaler.rb
130
+ - examples/02-manifest-with-middleware/templates/ingress.rb
131
+ - examples/02-manifest-with-middleware/templates/service.rb
132
+ - examples/03-app-with-database/demo.rb
133
+ - examples/03-app-with-database/helpers.rb
134
+ - examples/03-app-with-database/my_app.rb
135
+ - examples/03-app-with-database/postgresql.rb
136
+ - examples/03-app-with-database/ruby_on_rails.rb
131
137
  - flake.lock
132
138
  - flake.nix
133
139
  - kube_cluster.gemspec
@@ -136,17 +142,17 @@ files:
136
142
  - lib/kube/cluster/connection.rb
137
143
  - lib/kube/cluster/instance.rb
138
144
  - lib/kube/cluster/manifest.rb
139
- - lib/kube/cluster/manifest/middleware.rb
140
- - lib/kube/cluster/manifest/middleware/annotations.rb
141
- - lib/kube/cluster/manifest/middleware/hpa_for_deployment.rb
142
- - lib/kube/cluster/manifest/middleware/ingress_for_service.rb
143
- - lib/kube/cluster/manifest/middleware/labels.rb
144
- - lib/kube/cluster/manifest/middleware/namespace.rb
145
- - lib/kube/cluster/manifest/middleware/pod_anti_affinity.rb
146
- - lib/kube/cluster/manifest/middleware/resource_preset.rb
147
- - lib/kube/cluster/manifest/middleware/security_context.rb
148
- - lib/kube/cluster/manifest/middleware/service_for_deployment.rb
149
- - lib/kube/cluster/manifest/stack.rb
145
+ - lib/kube/cluster/middleware.rb
146
+ - lib/kube/cluster/middleware/annotations.rb
147
+ - lib/kube/cluster/middleware/hpa_for_deployment.rb
148
+ - lib/kube/cluster/middleware/ingress_for_service.rb
149
+ - lib/kube/cluster/middleware/labels.rb
150
+ - lib/kube/cluster/middleware/namespace.rb
151
+ - lib/kube/cluster/middleware/pod_anti_affinity.rb
152
+ - lib/kube/cluster/middleware/resource_preset.rb
153
+ - lib/kube/cluster/middleware/security_context.rb
154
+ - lib/kube/cluster/middleware/service_for_deployment.rb
155
+ - lib/kube/cluster/middleware/stack.rb
150
156
  - lib/kube/cluster/resource.rb
151
157
  - lib/kube/cluster/resource/dirty_tracking.rb
152
158
  - lib/kube/cluster/resource/persistence.rb
@@ -1,238 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Database (PostgreSQL) Example
5
- #
6
- # Demonstrates the Ruby equivalents of Bitnami common chart patterns:
7
- # - Secret lifecycle management (_secrets.tpl)
8
- # - StorageClass resolution (_storage.tpl)
9
- # - StatefulSet with persistent volumes
10
- # - Headless service for stable DNS
11
- # - NetworkPolicy for database isolation
12
- # - Standard labels and naming (_labels.tpl, _names.tpl)
13
- # - Resource presets (_resources.tpl)
14
- #
15
- # Usage:
16
- # ruby examples/database/manifest.rb
17
- # ruby examples/database/manifest.rb > database.yaml
18
-
19
- require "kube/schema"
20
- require "securerandom"
21
-
22
- # ── Naming ────────────────────────────────────────────────────────────────────
23
-
24
- APP_NAME = "postgresql"
25
- RELEASE_NAME = "my-release"
26
- NAMESPACE = "database"
27
- FULLNAME = "#{RELEASE_NAME}-#{APP_NAME}"[0, 63].chomp("-")
28
-
29
- # ── Labels ────────────────────────────────────────────────────────────────────
30
-
31
- STANDARD_LABELS = {
32
- "app.kubernetes.io/name": APP_NAME,
33
- "app.kubernetes.io/instance": RELEASE_NAME,
34
- "app.kubernetes.io/version": "16.4.0",
35
- "app.kubernetes.io/component": "primary",
36
- "app.kubernetes.io/managed-by": "kube_cluster",
37
- }
38
-
39
- MATCH_LABELS = STANDARD_LABELS.slice(
40
- :"app.kubernetes.io/name",
41
- :"app.kubernetes.io/instance",
42
- :"app.kubernetes.io/component",
43
- )
44
-
45
- # ── Secrets (from _secrets.tpl) ───────────────────────────────────────────────
46
- # Bitnami's secrets.passwords.manage generates random passwords, reuses existing
47
- # ones on upgrade, and base64 encodes them. In Ruby we do this directly.
48
-
49
- POSTGRES_PASSWORD = SecureRandom.alphanumeric(24)
50
- REPLICATION_PASSWORD = SecureRandom.alphanumeric(24)
51
-
52
- def base64(str)
53
- [str].pack("m0")
54
- end
55
-
56
- # ── Storage (from _storage.tpl) ───────────────────────────────────────────────
57
- # Bitnami resolves storage class from global > persistence > default.
58
- # The "-" convention means explicitly use the default storage class (empty string).
59
-
60
- STORAGE_CLASS = "standard" # set to "-" for default, or nil to omit
61
- STORAGE_SIZE = "10Gi"
62
-
63
- # ── Resource presets ──────────────────────────────────────────────────────────
64
-
65
- RESOURCES = {
66
- requests: { cpu: "500m", memory: "512Mi" },
67
- limits: { cpu: "750m", memory: "768Mi" },
68
- }
69
-
70
- # ── Build manifests ───────────────────────────────────────────────────────────
71
-
72
- manifest = Kube::Schema::Manifest.new
73
-
74
- # -- Namespace --
75
-
76
- manifest << Kube::Schema["Namespace"].new {
77
- metadata.name = NAMESPACE
78
- metadata.labels = STANDARD_LABELS.reject { |k, _| k == :"app.kubernetes.io/component" }
79
- }
80
-
81
- # -- Secret --
82
- # Pattern from _secrets.tpl: base64-encoded credentials, separate keys for
83
- # each password, supports existing secret reuse on upgrade.
84
-
85
- manifest << Kube::Schema["Secret"].new {
86
- metadata.name = FULLNAME
87
- metadata.namespace = NAMESPACE
88
- metadata.labels = STANDARD_LABELS
89
- self.type = "Opaque"
90
- self.data = {
91
- "postgres-password": base64(POSTGRES_PASSWORD),
92
- "replication-password": base64(REPLICATION_PASSWORD),
93
- }
94
- }
95
-
96
- # -- Headless Service (for StatefulSet stable DNS) --
97
-
98
- manifest << Kube::Schema["Service"].new {
99
- metadata.name = "#{FULLNAME}-headless"
100
- metadata.namespace = NAMESPACE
101
- metadata.labels = STANDARD_LABELS
102
-
103
- spec.clusterIP = "None"
104
- spec.selector = MATCH_LABELS
105
- spec.ports = [
106
- { name: "tcp-postgresql", port: 5432, targetPort: "tcp-postgresql" },
107
- ]
108
- }
109
-
110
- # -- Primary Service (for client connections) --
111
-
112
- manifest << Kube::Schema["Service"].new {
113
- metadata.name = FULLNAME
114
- metadata.namespace = NAMESPACE
115
- metadata.labels = STANDARD_LABELS
116
-
117
- spec.selector = MATCH_LABELS
118
- spec.ports = [
119
- { name: "tcp-postgresql", port: 5432, targetPort: "tcp-postgresql" },
120
- ]
121
- }
122
-
123
- # -- StatefulSet --
124
- # Uses storage class resolution pattern, secret references, resource presets,
125
- # pod anti-affinity for spreading replicas.
126
-
127
- manifest << Kube::Schema["StatefulSet"].new {
128
- metadata.name = FULLNAME
129
- metadata.namespace = NAMESPACE
130
- metadata.labels = STANDARD_LABELS
131
-
132
- spec.serviceName = "#{FULLNAME}-headless"
133
- spec.replicas = 1
134
- spec.selector.matchLabels = MATCH_LABELS
135
-
136
- spec.template.metadata.labels = STANDARD_LABELS
137
- spec.template.spec.containers = [
138
- {
139
- name: APP_NAME,
140
- image: "docker.io/postgres:16.4-alpine",
141
- ports: [
142
- { name: "tcp-postgresql", containerPort: 5432 },
143
- ],
144
- resources: RESOURCES,
145
- env: [
146
- { name: "POSTGRES_PASSWORD", valueFrom: { secretKeyRef: { name: FULLNAME, key: "postgres-password" } } },
147
- { name: "PGDATA", value: "/var/lib/postgresql/data/pgdata" },
148
- ],
149
- volumeMounts: [
150
- { name: "data", mountPath: "/var/lib/postgresql/data" },
151
- ],
152
- livenessProbe: {
153
- exec: { command: ["pg_isready", "-U", "postgres"] },
154
- initialDelaySeconds: 30,
155
- periodSeconds: 10,
156
- timeoutSeconds: 5,
157
- failureThreshold: 6,
158
- },
159
- readinessProbe: {
160
- exec: { command: ["pg_isready", "-U", "postgres"] },
161
- initialDelaySeconds: 5,
162
- periodSeconds: 10,
163
- timeoutSeconds: 5,
164
- failureThreshold: 6,
165
- },
166
- },
167
- ]
168
-
169
- # Pod anti-affinity: hard anti-affinity to guarantee one pod per node
170
- # (from _affinities.tpl: common.affinities.pods.hard)
171
- spec.template.spec.affinity = {
172
- podAntiAffinity: {
173
- requiredDuringSchedulingIgnoredDuringExecution: [
174
- {
175
- labelSelector: { matchLabels: MATCH_LABELS },
176
- topologyKey: "kubernetes.io/hostname",
177
- },
178
- ],
179
- },
180
- }
181
-
182
- # Storage class resolution (from _storage.tpl)
183
- storage_class = STORAGE_CLASS == "-" ? "" : STORAGE_CLASS
184
-
185
- spec.volumeClaimTemplates = [
186
- {
187
- metadata: { name: "data" },
188
- spec: {
189
- accessModes: ["ReadWriteOnce"],
190
- storageClassName: storage_class,
191
- resources: { requests: { storage: STORAGE_SIZE } },
192
- },
193
- },
194
- ]
195
- }
196
-
197
- # -- NetworkPolicy --
198
- # Isolate the database: only allow ingress from pods with the app label,
199
- # deny everything else. This is a common production hardening pattern.
200
-
201
- manifest << Kube::Schema["NetworkPolicy"].new {
202
- metadata.name = FULLNAME
203
- metadata.namespace = NAMESPACE
204
- metadata.labels = STANDARD_LABELS
205
-
206
- spec.podSelector = { matchLabels: MATCH_LABELS }
207
- spec.policyTypes = ["Ingress", "Egress"]
208
- spec.ingress = [
209
- {
210
- from: [
211
- {
212
- podSelector: {
213
- matchLabels: { "app.kubernetes.io/name": "web-app" },
214
- },
215
- },
216
- ],
217
- ports: [
218
- { protocol: "TCP", port: "5432" },
219
- ],
220
- },
221
- ]
222
- # Allow DNS egress + nothing else
223
- spec.egress = [
224
- {
225
- to: [
226
- { namespaceSelector: {} },
227
- ],
228
- ports: [
229
- { protocol: "UDP", port: "53" },
230
- { protocol: "TCP", port: "53" },
231
- ],
232
- },
233
- ]
234
- }
235
-
236
- # ── Render ────────────────────────────────────────────────────────────────────
237
-
238
- puts manifest.to_yaml
@@ -1,215 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "kube/schema"
5
-
6
- MATCH_LABELS = STANDARD_LABELS.slice(
7
- :"app.kubernetes.io/name",
8
- :"app.kubernetes.io/instance",
9
- )
10
-
11
- REGISTRY = "docker.io"
12
- REPOSITORY = "nginx"
13
- TAG = "1.27.3-alpine"
14
- IMAGE = "#{REGISTRY}/#{REPOSITORY}:#{TAG}"
15
-
16
- RESOURCE_PRESETS = {
17
- "nano": { requests: { cpu: "100m", memory: "128Mi" }, limits: { cpu: "150m", memory: "192Mi" } },
18
- "micro": { requests: { cpu: "250m", memory: "256Mi" }, limits: { cpu: "375m", memory: "384Mi" } },
19
- "small": { requests: { cpu: "500m", memory: "512Mi" }, limits: { cpu: "750m", memory: "768Mi" } },
20
- "medium": { requests: { cpu: "500m", memory: "1024Mi" }, limits: { cpu: "750m", memory: "1536Mi" } },
21
- "large": { requests: { cpu: "1.0", memory: "2048Mi" }, limits: { cpu: "1.5", memory: "3072Mi" } },
22
- "xlarge": { requests: { cpu: "1.0", memory: "3072Mi" }, limits: { cpu: "3.0", memory: "6144Mi" } },
23
- "2xlarge": { requests: { cpu: "1.0", memory: "3072Mi" }, limits: { cpu: "6.0", memory: "12288Mi" } },
24
- }
25
-
26
- module AutoConfig
27
- end
28
-
29
- class MyApp < Kube::Schema::Manifest
30
- include Helpers
31
- include AutoConfig
32
-
33
- def initialize(namespace: DEFAULT_NAMESPACE, labels: STANDARD_LABELS)
34
- @app_name = "web-app"
35
- @fullname = "#{RELEASE_NAME}-#{APP_NAME}"[0, 63].chomp("-")
36
- @namespace = namespace
37
-
38
- @labels = {
39
- "app.kubernetes.io/name": @app_name
40
- "app.kubernetes.io/managed-by": "kube_cluster",
41
- }
42
- end
43
-
44
- stack do
45
- use Middleware::Namespace
46
- use Middleware::Labels
47
- end
48
-
49
- class Namespace < Kube::Schema["Namespace"]
50
- def initialize(namespace:)
51
- build {
52
- metadata.name = namespace
53
- }
54
- end
55
- end
56
-
57
- class ConfigMap < Kube::Schema["ConfigMap"]
58
- def initialize(namespace:)
59
- build {
60
- metadata.name = "#{namespace}-config"
61
- spec.data = {
62
- RAILS_ENV: "production",
63
- LOG_LEVEL: "info",
64
- WORKERS: "4",
65
- PORT: "3000",
66
- }
67
- }
68
- end
69
- end
70
-
71
- class Deployment < Kube::Schema["Deployment"]
72
- def initialize(namespace:)
73
- build {
74
- metadata.name = namespace
75
-
76
- spec.replicas = 3
77
- spec.selector.matchLabels = MATCH_LABELS
78
-
79
- spec.template.metadata.labels = STANDARD_LABELS
80
- spec.template.metadata.annotations = {
81
- # Checksum pattern from _utils.tpl -- triggers rolling restart on config change
82
- "checksum/config": "{{ sha256sum of configmap data }}",
83
- }
84
-
85
- spec.template.spec.containers = [
86
- {
87
- name: APP_NAME,
88
- image: IMAGE,
89
- ports: [{ name: "http", containerPort: 3000, protocol: "TCP" }],
90
- resources: RESOURCES,
91
- env: [
92
- { name: "PORT", value: "3000" },
93
- ],
94
- envFrom: [
95
- { configMapRef: { name: "#{FULLNAME}-config" } },
96
- ],
97
- livenessProbe: {
98
- httpGet: { path: "/healthz", port: "http" },
99
- initialDelaySeconds: 15,
100
- periodSeconds: 10,
101
- },
102
- readinessProbe: {
103
- httpGet: { path: "/readyz", port: "http" },
104
- initialDelaySeconds: 5,
105
- periodSeconds: 5,
106
- },
107
- },
108
- ]
109
-
110
- # Pod anti-affinity (from _affinities.tpl)
111
- # Soft anti-affinity: prefer spreading pods across nodes but don't enforce it
112
- spec.template.spec.affinity = {
113
- podAntiAffinity: {
114
- preferredDuringSchedulingIgnoredDuringExecution: [
115
- {
116
- weight: 1,
117
- podAffinityTerm: {
118
- labelSelector: {
119
- matchLabels: MATCH_LABELS,
120
- },
121
- topologyKey: "kubernetes.io/hostname",
122
- },
123
- },
124
- ],
125
- },
126
- }
127
- }
128
- end
129
- end
130
-
131
- class Service < Kube::Schema["Service"]
132
- def initialize(namespace:)
133
- build {
134
- metadata.name = namespace
135
-
136
- spec.selector = MATCH_LABELS
137
- spec.ports = [
138
- { name: "http", port: 80, targetPort: "http", protocol: "TCP" },
139
- ]
140
- }
141
- end
142
- end
143
-
144
- class Ingress < Kube::Schema["Ingress"]
145
- def initialize(namespace:)
146
- build {
147
- metadata.name = namespace
148
- metadata.annotations = {
149
- "cert-manager.io/cluster-issuer": "letsencrypt-prod",
150
- "nginx.ingress.kubernetes.io/ssl-redirect": "true",
151
- }
152
-
153
- spec.ingressClassName = "nginx"
154
- spec.tls = [
155
- {
156
- hosts: ["app.example.com"],
157
- secretName: "#{namespace}-tls",
158
- },
159
- ]
160
- spec.rules = [
161
- {
162
- host: "app.example.com",
163
- http: {
164
- paths: [
165
- {
166
- path: "/",
167
- pathType: "Prefix",
168
- backend: {
169
- service: {
170
- name: FULLNAME,
171
- port: { name: "http" },
172
- },
173
- },
174
- },
175
- ],
176
- },
177
- },
178
- ]
179
- }
180
- end
181
- end
182
-
183
- class HorizontalPodAutoscaler < Kube::Schema["HorizontalPodAutoscaler"]
184
- def initialize(namespace:)
185
- build {
186
- metadata.name = namespace
187
-
188
- spec.scaleTargetRef.apiVersion = "apps/v1"
189
- spec.scaleTargetRef.kind = "Deployment"
190
- spec.scaleTargetRef.name = namespace
191
-
192
- spec.minReplicas = 3
193
- spec.maxReplicas = 10
194
- spec.metrics = [
195
- {
196
- type: "Resource",
197
- resource: {
198
- name: "cpu",
199
- target: { type: "Utilization", averageUtilization: 75 },
200
- },
201
- },
202
- {
203
- type: "Resource",
204
- resource: {
205
- name: "memory",
206
- target: { type: "Utilization", averageUtilization: 80 },
207
- },
208
- },
209
- ]
210
- }
211
- end
212
- end
213
- end
214
-
215
- puts MyApp.new.to_yaml
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kube
4
- module Cluster
5
- class Manifest < Kube::Schema::Manifest
6
- class Middleware
7
- # Merges annotations into +metadata.annotations+ on every resource.
8
- # Existing annotations are preserved; the supplied annotations act
9
- # as defaults that can be overridden per-resource.
10
- #
11
- # stack do
12
- # use Middleware::Annotations,
13
- # "prometheus.io/scrape": "true",
14
- # "prometheus.io/port": "9090"
15
- # end
16
- #
17
- class Annotations < Middleware
18
- def initialize(**annotations)
19
- @annotations = annotations.transform_keys(&:to_sym).transform_values(&:to_s)
20
- end
21
-
22
- def call(resource)
23
- h = resource.to_h
24
- h[:metadata] ||= {}
25
- h[:metadata][:annotations] = @annotations.merge(h[:metadata][:annotations] || {})
26
- rebuild(resource, h)
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end