kube_cluster 0.7.0 → 0.8.0

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: 0f1c23db70574ae658780a8fcdcaefa84a23b917f206cce85749c84739ccd8c1
4
- data.tar.gz: bd673c8ab74f4a2c6c046d27e40994cd7a819ad6e552b5a98e14fc1974f52bcc
3
+ metadata.gz: 28348c8c7bfb6bb1e1340efeba20451d4b29c11a8e75454e87d805e3b6c4b36f
4
+ data.tar.gz: c1aa1ee8775553e15026dce80414949bd57da1371dac6bda72766aeba117db1f
5
5
  SHA512:
6
- metadata.gz: 49d328773bd999a1270386fec416f6a4afa0aa88d8fe6fe51e42af84e134154ac80b0220426c7be1b45e534ab2c164dc5ff22a9c0208f2d623c67aaba1be621e
7
- data.tar.gz: fe000f50ed0f0b55a2b4efedc4fbedbf0bfcbf61039b64dd8584384cd0cf317d31e8b8db2d1bb79ae1b46dffcd6165ce27835d57cd5a9b86fbabdf976675dd21
6
+ metadata.gz: 48d13d3cd9b6578d44d2007392f89d3c1a3ab0838e1fcde8825d86b1e8cfe263f538ff3b5f92bf70155273c4e58bc68d2d7212c75a6c16a3bf1c06c56c0d91d8
7
+ data.tar.gz: 8cba24053f71e5f4d9efd117c7a477b00b5cdba21b57f6a2afa88a53f632e93f26791d532bdde06d8842477d3e40b15a0c9434b4a50245bc94a3db357ffbab72
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kube_cluster (0.7.0)
4
+ kube_cluster (0.8.0)
5
+ activesupport (~> 8.0)
5
6
  kube_kubectl (~> 2.0)
6
7
  kube_schema (~> 1.5)
7
8
  scampi (~> 0.1)
@@ -9,6 +10,19 @@ PATH
9
10
  GEM
10
11
  remote: https://rubygems.org/
11
12
  specs:
13
+ activesupport (8.1.3)
14
+ base64
15
+ bigdecimal
16
+ concurrent-ruby (~> 1.0, >= 1.3.1)
17
+ connection_pool (>= 2.2.5)
18
+ drb
19
+ i18n (>= 1.6, < 2)
20
+ json
21
+ logger (>= 1.4.2)
22
+ minitest (>= 5.1)
23
+ securerandom (>= 0.3)
24
+ tzinfo (~> 2.0, >= 2.0.5)
25
+ uri (>= 0.13.1)
12
26
  ast (2.4.3)
13
27
  async (2.39.0)
14
28
  console (~> 1.29)
@@ -60,12 +74,14 @@ GEM
60
74
  bake-releases (0.5.4)
61
75
  bake (~> 0.21)
62
76
  markly (~> 0.8)
77
+ base64 (0.3.0)
63
78
  bigdecimal (4.1.2)
64
79
  build-files (1.10.2)
65
80
  colorize (1.1.0)
66
81
  colorize-extended (0.1.0)
67
82
  colorize (~> 1.1)
68
83
  concurrent-ruby (1.3.6)
84
+ connection_pool (3.0.2)
69
85
  console (1.34.3)
70
86
  fiber-annotation
71
87
  fiber-local (~> 1.1)
@@ -77,6 +93,7 @@ GEM
77
93
  decode (0.27.0)
78
94
  prism
79
95
  rbs
96
+ drb (2.2.3)
80
97
  erb (6.0.4)
81
98
  falcon (0.55.3)
82
99
  async
@@ -97,6 +114,8 @@ GEM
97
114
  fiber-storage (1.0.1)
98
115
  hana (1.3.7)
99
116
  http-accept (2.2.1)
117
+ i18n (1.14.8)
118
+ concurrent-ruby (~> 1.0)
100
119
  io-console (0.8.2)
101
120
  io-endpoint (0.17.2)
102
121
  io-event (1.16.0)
@@ -140,6 +159,9 @@ GEM
140
159
  mime-types-data (~> 3.2025, >= 3.2025.0507)
141
160
  mime-types-data (3.2026.0414)
142
161
  mini_mime (1.1.5)
162
+ minitest (6.0.6)
163
+ drb (~> 2.0)
164
+ prism (~> 1.5)
143
165
  msgpack (1.8.0)
144
166
  net-imap (0.6.4)
145
167
  date
@@ -215,6 +237,7 @@ GEM
215
237
  mapping (~> 1.0)
216
238
  scampi (0.1.7)
217
239
  colorize-extended
240
+ securerandom (0.4.1)
218
241
  shellwords (0.2.2)
219
242
  simpleidn (0.2.3)
220
243
  string-format (0.2.0)
@@ -224,9 +247,12 @@ GEM
224
247
  timeout (0.6.1)
225
248
  traces (0.18.2)
226
249
  tsort (0.2.0)
250
+ tzinfo (2.0.6)
251
+ concurrent-ruby (~> 1.0)
227
252
  unicode-display_width (3.2.0)
228
253
  unicode-emoji (~> 4.1)
229
254
  unicode-emoji (4.2.0)
255
+ uri (1.1.1)
230
256
  utopia (2.32.1)
231
257
  bake (~> 0.20)
232
258
  concurrent-ruby (~> 1.2)
data/kube_cluster.gemspec CHANGED
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
35
35
 
36
36
  spec.add_dependency "kube_schema", "~> 1.5"
37
37
  spec.add_dependency "kube_kubectl", "~> 2.0"
38
+ spec.add_dependency "activesupport", "~> 8.0"
38
39
  end
@@ -0,0 +1,35 @@
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
+ module CDI
10
+ #class DataVolume < Kube::Cluster['DataVolume']
11
+ # def initialize(name:, &block)
12
+ # super() {
13
+ # metadata.name = name
14
+ # instance_exec(&block) if block
15
+ # }
16
+ # end
17
+ #end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ test do
24
+ #describe "CDI::DataVolume" do
25
+ # it "initializes without error" do
26
+ # Kube::Cluster::Standard::CDI::DataVolume
27
+ # .new(
28
+ # name: "my-example-volume"
29
+ # )
30
+ # .to_yaml
31
+ # .is_a?(String)
32
+ # .should == true
33
+ # end
34
+ #end
35
+ end
@@ -0,0 +1,27 @@
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
+ module CloudNativePg
10
+ #class Cluster < Kube::Cluster["Cluster"]
11
+ #end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ test do
18
+ #describe "CloudNativePg::Cluster" do
19
+ # it "initializes without error" do
20
+ # Kube::Cluster::Standard::CloudNativePg::Cluster
21
+ # .new()
22
+ # .to_yaml
23
+ # .is_a?(String)
24
+ # .should == true
25
+ # end
26
+ #end
27
+ end
@@ -0,0 +1,44 @@
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
+ module CloudNativePg
10
+ class DatabaseWithExternalSecret < Kube::Cluster::Manifest
11
+ def initialize(name:, cluster: "postgres", owner: "app", &block)
12
+ database = Kube::Cluster["Database"].new {
13
+ metadata.name = name
14
+ spec.cluster = { name: cluster }
15
+ spec.databaseReclaimPolicy = "retain"
16
+ spec.ensure = "present"
17
+ spec.name = name
18
+ spec.owner = owner
19
+ }
20
+
21
+ external_secret = CloudNativePg::ExternalSecret.new(name: name)
22
+
23
+ super(database, external_secret)
24
+ instance_exec(&block) if block
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ test do
33
+ describe "CloudNativePg::DatabaseWithExternalSecret" do
34
+ it "initializes without error" do
35
+ Kube::Cluster::Standard::CloudNativePg::DatabaseWithExternalSecret
36
+ .new(
37
+ name: "my-example-cluster"
38
+ )
39
+ .to_yaml
40
+ .is_a?(String)
41
+ .should == true
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,57 @@
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
+ module CloudNativePg
10
+ class ExternalSecret < Kube::Cluster["ExternalSecret"]
11
+
12
+ DB_HOST = "postgres-rw.cloudnative-pg.svc.cluster.local"
13
+
14
+ def initialize(name:, env_prefix: "DB", db_host: DB_HOST, &block)
15
+ super() {
16
+ metadata.name = "#{name}-db"
17
+ spec.refreshInterval = "1h"
18
+ spec.secretStoreRef = { kind: "ClusterSecretStore", name: "cnpg-credentials" }
19
+ spec.target = {
20
+ name: "#{name}-db",
21
+ creationPolicy: "Owner",
22
+ deletionPolicy: "Retain",
23
+ template: {
24
+ data: {
25
+ "#{env_prefix}_URL" => "jdbc:postgresql://#{db_host}:5432/#{name}",
26
+ "#{env_prefix}_USER" => "{{ .username }}",
27
+ "#{env_prefix}_PASSWORD" => "{{ .password }}",
28
+ },
29
+ },
30
+ }
31
+ spec.data = [
32
+ { secretKey: "username", remoteRef: { key: "postgres-app", property: "username" } },
33
+ { secretKey: "password", remoteRef: { key: "postgres-app", property: "password" } },
34
+ ]
35
+
36
+ instance_exec(&block) if block_given?
37
+ }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ test do
46
+ describe "CloudNativePg::ExternalSecret" do
47
+ it "initializes without error" do
48
+ Kube::Cluster::Standard::CloudNativePg::ExternalSecret
49
+ .new(
50
+ name: "my-external-secret"
51
+ )
52
+ .to_yaml
53
+ .is_a?(String)
54
+ .should == true
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,45 @@
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
+ class ConfigMap < Kube::Cluster['ConfigMap']
10
+
11
+ # wtf is this????? I hate it... claude made it and it needs to dead...
12
+ KeyRef = Struct.new(:config_map, :key_name)
13
+
14
+ def initialize(name: 'config', **options, &block)
15
+ super(**options) do
16
+ metadata.name = name
17
+ instance_exec(&block) if block
18
+ end
19
+ end
20
+
21
+ def config_map_name
22
+ to_h.dig(:metadata, :name)
23
+ end
24
+
25
+ def key(key_name)
26
+ KeyRef.new(self, key_name)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ test do
34
+ describe "ConfigMap" do
35
+ it "initializes without error" do
36
+ Kube::Cluster::Standard::ConfigMap
37
+ .new(
38
+ #name: "example-config"
39
+ )
40
+ .to_yaml
41
+ .is_a?(String)
42
+ .should == true
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,82 @@
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
+ class CustomResourceDefinition < Kube::Cluster['CustomResourceDefinition']
10
+ def initialize(
11
+ kind:, group:, version: 'v1', scope: 'Namespaced',
12
+ short_names: [], categories: [], schema: nil, &block
13
+ )
14
+
15
+ plural = kind.downcase.pluralize
16
+ singular = kind.downcase
17
+
18
+ schema ||= {
19
+ type: 'object',
20
+ 'x-kubernetes-preserve-unknown-fields': true
21
+ }
22
+
23
+ super() {
24
+ metadata.name = "#{plural}.#{group}"
25
+
26
+ spec.group = group
27
+ spec.names.kind = kind
28
+ spec.names.listKind = "#{kind}List"
29
+ spec.names.plural = plural
30
+ spec.names.singular = singular
31
+ spec.names.shortNames = short_names unless short_names.empty?
32
+ spec.names.categories = categories unless categories.empty?
33
+ spec.scope = scope
34
+ spec.versions = [{
35
+ name: version,
36
+ served: true,
37
+ storage: true,
38
+ subresources: { status: {} },
39
+ schema: {
40
+ openAPIV3Schema: schema
41
+ }
42
+ }]
43
+
44
+ instance_exec(&block) if block
45
+ }
46
+
47
+ api_version = "#{group}/#{version}"
48
+ Kube::Schema.register(
49
+ kind,
50
+ schema: {
51
+ 'type' => 'object',
52
+ 'properties' => {
53
+ 'apiVersion' => { 'type' => 'string' },
54
+ 'kind' => { 'type' => 'string' },
55
+ 'metadata' => { 'type' => 'object' },
56
+ 'spec' => { 'type' => 'object', 'x-kubernetes-preserve-unknown-fields' => true },
57
+ 'status' => { 'type' => 'object', 'x-kubernetes-preserve-unknown-fields' => true }
58
+ },
59
+ 'x-kubernetes-preserve-unknown-fields' => true
60
+ },
61
+ api_version: api_version
62
+ )
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ test do
70
+ describe "CustomResourceDefinition" do
71
+ it "initializes without error" do
72
+ Kube::Cluster::Standard::CustomResourceDefinition
73
+ .new(
74
+ kind: "Widget",
75
+ group: "example.com",
76
+ )
77
+ .to_yaml
78
+ .is_a?(String)
79
+ .should == true
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kube/cluster'
4
+ require 'kube/cluster/standard/env_processing'
5
+ require 'kube/cluster/standard/volume_processing'
6
+
7
+ module Kube
8
+ module Cluster
9
+ module Standard
10
+ class DaemonSet < Kube::Cluster['DaemonSet']
11
+ def initialize(
12
+ name:,
13
+ image:,
14
+ env: {},
15
+ volume_mounts: {},
16
+ command: nil,
17
+ service_account: nil,
18
+ node_selector: nil,
19
+ tolerations: nil,
20
+ host_pid: false,
21
+ &block
22
+ )
23
+ processed_env = EnvProcessing.process(env)
24
+ processed_volumes = VolumeProcessing.process(volume_mounts)
25
+
26
+ super() {
27
+ metadata.name = name
28
+ metadata.labels = { 'app' => name }
29
+
30
+ spec.selector.matchLabels = { 'app' => name }
31
+
32
+ spec.template.metadata.labels = { 'app' => name }
33
+ spec.template.spec.serviceAccountName = service_account || name
34
+
35
+ container = {
36
+ name: name,
37
+ image: image,
38
+ env: processed_env
39
+ }
40
+ container[:command] = command if command
41
+ container[:volumeMounts] = processed_volumes[:volume_mounts] unless processed_volumes[:volume_mounts].empty?
42
+
43
+ spec.template.spec.containers = [container]
44
+ spec.template.spec.volumes = processed_volumes[:volumes] unless processed_volumes[:volumes].empty?
45
+ spec.template.spec.hostPID = true if host_pid
46
+ spec.template.spec.nodeSelector = node_selector if node_selector
47
+ spec.template.spec.tolerations = tolerations if tolerations
48
+
49
+ instance_exec(&block) if block
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ test do
58
+ describe "DaemonSet" do
59
+ it "initializes without error" do
60
+ Kube::Cluster::Standard::DaemonSet
61
+ .new(
62
+ name: "my-daemon",
63
+ image: "busybox",
64
+ )
65
+ .to_yaml
66
+ .is_a?(String)
67
+ .should == true
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,96 @@
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
+ module ESO
10
+ class ExternalSecret < Kube::Cluster['ExternalSecret']
11
+ # Returned by .template — carries the secret ref and template value.
12
+ # When the env hash is processed, the key becomes both the env var name
13
+ # and the secret template data key.
14
+ TemplateRef = Struct.new(:secret, :template_value)
15
+
16
+ # Returned by .key — carries the secret ref and key name.
17
+ # When the volume_mounts hash is processed, this tells the volume
18
+ # processing layer to mount a single key from the secret as a file.
19
+ KeyRef = Struct.new(:secret, :key_name)
20
+
21
+ attr_reader :secret_name
22
+
23
+ def initialize(name:, store:, remote_key:, keys: nil, deletion_policy: nil, &block)
24
+ @secret_name = name
25
+ @remote_key = remote_key
26
+ @_template_data = {}
27
+ @_remote_properties = {}
28
+ @_keys = keys
29
+ @_deletion_policy = deletion_policy
30
+
31
+ super() do
32
+ metadata.name = name
33
+ spec.refreshInterval = '1h'
34
+ spec.secretStoreRef = { kind: 'ClusterSecretStore', name: store }
35
+
36
+ target = { name: name, creationPolicy: 'Owner' }
37
+ target[:deletionPolicy] = deletion_policy if deletion_policy
38
+ spec.target = target
39
+
40
+ if keys
41
+ spec.data = keys.map do |secret_key, property|
42
+ { secretKey: secret_key, remoteRef: { key: remote_key, property: property } }
43
+ end
44
+ end
45
+
46
+ instance_exec(&block) if block
47
+ end
48
+ end
49
+
50
+ # Returns a TemplateRef. The env hash processor calls .register!
51
+ # on the ref to wire up the template data and remote properties.
52
+ def template(template_string)
53
+ TemplateRef.new(self, template_string)
54
+ end
55
+ alias with_template template
56
+
57
+ # Returns a KeyRef for mounting a single key from this secret as a file.
58
+ # The volume processing layer uses this to generate the volume and mount.
59
+ def key(key_name)
60
+ KeyRef.new(self, key_name)
61
+ end
62
+
63
+ # Called by env processing to register a template entry.
64
+ def register_template!(env_key, template_string)
65
+ @_template_data[env_key] = template_string
66
+
67
+ template_string.scan(/\{\{\s*\.(\w+)\s*\}\}/) do |match|
68
+ @_remote_properties[match[0]] = true
69
+ end
70
+
71
+ @data.spec.target.template = { data: @_template_data }
72
+ @data.spec.data = @_remote_properties.keys.map do |prop|
73
+ { secretKey: prop, remoteRef: { key: @remote_key, property: prop } }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ test do
83
+ describe "ESO::ExternalSecret" do
84
+ it "initializes without error" do
85
+ Kube::Cluster::Standard::ESO::ExternalSecret
86
+ .new(
87
+ name: "my-external-secret",
88
+ store: "my-cluster-store",
89
+ remote_key: "secret/data/my-app",
90
+ )
91
+ .to_yaml
92
+ .is_a?(String)
93
+ .should == true
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,64 @@
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
+ module Forgejo
10
+ class Helm < Kube::Cluster["HelmChart"]
11
+
12
+ CHART_VERSION = "16.2.1"
13
+
14
+ def initialize(
15
+ domain:,
16
+ chart_version: CHART_VERSION,
17
+ target_namespace: "default",
18
+ storage_size: "200Gi",
19
+ storage_class: "local-path",
20
+ node_selector: nil,
21
+ &block
22
+ )
23
+ super {
24
+ metadata.name = "forgejo"
25
+ metadata.namespace = "kube-system"
26
+ spec.version = chart_version
27
+ spec.chart = "oci://codeberg.org/forgejo-contrib/forgejo"
28
+ spec.targetNamespace = target_namespace
29
+ spec.valuesContent = <<~YAML
30
+ gitea:
31
+ config:
32
+ server:
33
+ ROOT_URL: https://#{domain}/
34
+ DOMAIN: #{domain}
35
+ SSH_DOMAIN: #{domain}
36
+ persistence:
37
+ enabled: true
38
+ size: #{storage_size}
39
+ storageClass: #{storage_class}
40
+ #{node_selector ? "nodeSelector:\n kubernetes.io/hostname: #{node_selector}" : ""}
41
+ YAML
42
+
43
+ instance_exec(&block) if block
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ test do
53
+ describe "Forgejo::Helm" do
54
+ it "initializes without error" do
55
+ Kube::Cluster::Standard::Forgejo::Helm
56
+ .new(
57
+ domain: "git.facebook.com"
58
+ )
59
+ .to_yaml
60
+ .is_a?(String)
61
+ .should == true
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,33 @@
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
+ module GatewayApi
10
+ #class HTTPRoute < Kube::Cluster::Manifest
11
+ #end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ test do
18
+ #describe "GatewayApi::HTTPRoute" do
19
+ # it "initializes without error" do
20
+ # Kube::Cluster::Standard::GatewayApi::HTTPRoute
21
+ # .new(
22
+ # name: nil,
23
+ # hostname: nil,
24
+ # service: nil,
25
+ # namespace: nil,
26
+ # port: nil,
27
+ # )
28
+ # .to_yaml
29
+ # .is_a?(String)
30
+ # .should == true
31
+ # end
32
+ #end
33
+ end
@@ -0,0 +1,50 @@
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
+ class Job < Kube::Cluster["Secret"]
10
+ def initialize(name:, image:, env: {}, command: nil, backoff_limit: 3, ttl: 300, &block)
11
+ processed_env = EnvProcessing.process(env)
12
+
13
+ super() do
14
+ metadata.name = name
15
+
16
+ spec.backoffLimit = backoff_limit
17
+ spec.ttlSecondsAfterFinished = ttl
18
+ spec.template.spec.restartPolicy = 'OnFailure'
19
+
20
+ container = {
21
+ name: name,
22
+ image: image,
23
+ env: processed_env
24
+ }
25
+ container[:command] = command if command
26
+
27
+ spec.template.spec.containers = [container]
28
+
29
+ instance_exec(&block) if block
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ test do
38
+ describe "Job" do
39
+ it "initializes without error" do
40
+ Kube::Cluster::Standard::Job
41
+ .new(
42
+ name: "my-job",
43
+ image: "nixery.dev/cowsay", # nixery.dev is pretty sick, mate!
44
+ )
45
+ .to_yaml
46
+ .is_a?(String)
47
+ .should == true
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,36 @@
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
+ module KubeVirt
10
+ class VirtualMachine < Kube::Cluster['VirtualMachine']
11
+ def initialize(name:, &block)
12
+ super() {
13
+ metadata.name = name
14
+ spec.template.metadata.labels = { 'kubevirt.io/domain' => name }
15
+ instance_exec(&block) if block
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ test do
25
+ describe "KubeVirt::VirtualMachine" do
26
+ it "initializes without error" do
27
+ Kube::Cluster::Standard::KubeVirt::VirtualMachine
28
+ .new(
29
+ name: "my-virtual-machine"
30
+ )
31
+ .to_yaml
32
+ .is_a?(String)
33
+ .should == true
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TEMPORARILY DISABLED: metacontroller.k8s.io CRDs (CompositeController) are not
4
+ # registered in kube_schema, so subclassing the kind raises at load time and
5
+ # aborts `require "kube/cluster"`. Commented out until the schema is registered.
6
+ =begin
7
+ require "bundler/setup"
8
+ require "kube/cluster"
9
+
10
+ module Kube
11
+ module Cluster
12
+ module Standard
13
+ module MetaController
14
+ class CompositeController < Kube::Cluster['CompositeController']
15
+ def initialize(
16
+ name:, webhook_url:,
17
+ resync_period: 30, parent_resource:, child_resources: {}, &block
18
+ )
19
+
20
+ resolved_parent = resolve_ref(parent_resource)
21
+ resolved_children = resolve_hash(child_resources)
22
+
23
+ super() {
24
+ metadata.name = "#{name}-composite-controller"
25
+
26
+ spec.generateSelector = true
27
+ spec.resyncPeriodSeconds = resync_period
28
+ spec.hooks.sync.webhook = { url: webhook_url }
29
+ spec.parentResource = resolved_parent
30
+ spec.childResources = resolved_children
31
+
32
+ instance_exec(&block) if block
33
+ }
34
+ end
35
+
36
+ private
37
+
38
+ def resolve_ref(ref)
39
+ if ref.is_a?(Hash)
40
+ ref
41
+ else
42
+ if ref.is_a?(Class)
43
+ klass = ref
44
+ else
45
+ klass = ref.class
46
+ end
47
+
48
+ {
49
+ apiVersion: klass.defaults['apiVersion'],
50
+ resource: klass.defaults['kind'].downcase.pluralize
51
+ }
52
+ end
53
+ end
54
+
55
+ def resolve_hash(hash)
56
+ hash.map do |klass, options|
57
+ resolve_ref(klass).merge(options || {})
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ test do
67
+ describe "MetaController::CompositeController" do
68
+ it "initializes without error" do
69
+ Kube::Cluster::Standard::MetaController::CompositeController
70
+ .new(
71
+ name: nil,
72
+ webhook_url: nil,
73
+ )
74
+ .to_yaml
75
+ .is_a?(String)
76
+ .should == true
77
+ end
78
+ end
79
+ end
80
+ =end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TEMPORARILY DISABLED: metacontroller.k8s.io CRDs (DecoratorController) are not
4
+ # registered in kube_schema, so subclassing the kind raises at load time and
5
+ # aborts `require "kube/cluster"`. Commented out until the schema is registered.
6
+ =begin
7
+ require "bundler/setup"
8
+ require "kube/cluster"
9
+
10
+ module Kube
11
+ module Cluster
12
+ module Standard
13
+ module MetaController
14
+ class DecoratorController < Kube::Cluster['DecoratorController']
15
+ def initialize(
16
+ name:, webhook_url:,
17
+ resync_period: 30, resources: {}, attachments: {}, &block
18
+ )
19
+
20
+ resolved_resources = resolve_hash(resources)
21
+ resolved_attachments = resolve_hash(attachments)
22
+
23
+ super() {
24
+ metadata.name = name
25
+
26
+ spec.resources = resolved_resources
27
+ spec.attachments = resolved_attachments
28
+ spec.resyncPeriodSeconds = resync_period
29
+ spec.hooks.sync.webhook = { url: webhook_url }
30
+
31
+ instance_exec(&block) if block
32
+ }
33
+ end
34
+
35
+ private
36
+
37
+ def resolve_ref(ref)
38
+ if ref.is_a?(Hash)
39
+ ref
40
+ else
41
+ if ref.is_a?(Class)
42
+ klass = ref
43
+ else
44
+ klass = ref.class
45
+ end
46
+
47
+ {
48
+ apiVersion: klass.defaults['apiVersion'],
49
+ resource: klass.defaults['kind'].downcase.pluralize
50
+ }
51
+ end
52
+ end
53
+
54
+ def resolve_hash(hash)
55
+ hash.map do |klass, options|
56
+ resolve_ref(klass).merge(options || {})
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ test do
66
+ describe "MetaController::DecoratorController" do
67
+ it "initializes without error" do
68
+ Kube::Cluster::Standard::MetaController::DecoratorController
69
+ .new(
70
+ name: nil,
71
+ webhook_url: nil,
72
+ )
73
+ .to_yaml
74
+ .is_a?(String)
75
+ .should == true
76
+ end
77
+ end
78
+ end
79
+ =end
@@ -0,0 +1,37 @@
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
+ class PersistentVolumeClaim < Kube::Cluster["PersistentVolumeClaim"]
10
+ def initialize(name:, storage:, access_modes: ["ReadWriteOnce"], storage_class: nil, &block)
11
+ super() {
12
+ metadata.name = name
13
+ spec.accessModes = access_modes
14
+ spec.storageClassName = storage_class if storage_class
15
+ spec.resources = { requests: { storage: storage } }
16
+ instance_exec(&block) if block_given?
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ test do
25
+ describe "PersistentVolumeClaim" do
26
+ it "initializes without error" do
27
+ Kube::Cluster::Standard::PersistentVolumeClaim
28
+ .new(
29
+ name: "my-volume",
30
+ storage: "25Gi",
31
+ )
32
+ .to_yaml
33
+ .is_a?(String)
34
+ .should == true
35
+ end
36
+ end
37
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kube
4
4
  module Cluster
5
- VERSION = "0.7.0"
5
+ VERSION = "0.8.0"
6
6
  end
7
7
  end
data/lib/kube/cluster.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require "bundler/setup"
4
4
  require "scampi"
5
5
  require "kube/schema"
6
+ require "active_support/core_ext/string/inflections"
6
7
 
7
8
  require_relative "../kube/errors"
8
9
  require_relative "cluster/version"
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.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan K
@@ -79,6 +79,20 @@ dependencies:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '2.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: activesupport
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '8.0'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '8.0'
82
96
  description: 'OOP abstraction that allows you to deploy and manage kubernetes resources
83
97
  using Ruby.
84
98
 
@@ -195,10 +209,24 @@ files:
195
209
  - lib/kube/cluster/resource/extensions/custom_resource_definition.rb
196
210
  - lib/kube/cluster/resource/persistence.rb
197
211
  - lib/kube/cluster/script_command.rb
198
- - lib/kube/cluster/standard/cloud_native_pg.rb
212
+ - lib/kube/cluster/standard/cdi/data_volume.rb
213
+ - lib/kube/cluster/standard/cloud_native_pg/cluster.rb
214
+ - lib/kube/cluster/standard/cloud_native_pg/database_with_external_secret.rb
215
+ - lib/kube/cluster/standard/cloud_native_pg/external_secret.rb
199
216
  - lib/kube/cluster/standard/cloud_native_pg/helm.rb
217
+ - lib/kube/cluster/standard/config_map.rb
218
+ - lib/kube/cluster/standard/custom_resource_definition.rb
219
+ - lib/kube/cluster/standard/daemon_set.rb
200
220
  - lib/kube/cluster/standard/deployment_with_service.rb
201
221
  - lib/kube/cluster/standard/env_processing.rb
222
+ - lib/kube/cluster/standard/eso/external_secret.rb
223
+ - lib/kube/cluster/standard/forgejo/helm.rb
224
+ - lib/kube/cluster/standard/gateway_api/http_route.rb
225
+ - lib/kube/cluster/standard/job.rb
226
+ - lib/kube/cluster/standard/kube_virt/virtual_machine.rb
227
+ - lib/kube/cluster/standard/meta_controller/composite_controller.rb
228
+ - lib/kube/cluster/standard/meta_controller/decorator_controller.rb
229
+ - lib/kube/cluster/standard/persistent_volume_claim.rb
202
230
  - lib/kube/cluster/standard/secret.rb
203
231
  - lib/kube/cluster/standard/service.rb
204
232
  - lib/kube/cluster/standard/volume_processing.rb
@@ -1,17 +0,0 @@
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
- module CloudNativePg
10
- end
11
- end
12
- end
13
- end
14
-
15
- test do
16
- # no op
17
- end