kube_cluster 0.6.0 → 0.7.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: 4cfe0887eeac1f4f52fc6f4f9730e5db9dacc66e132765301380d2a16933ebe7
4
- data.tar.gz: 9ab9e7350e92274bc4f4ba73f5ffc025d18035a87fee5ed2a1c1d29e1e9dfc5b
3
+ metadata.gz: 0f1c23db70574ae658780a8fcdcaefa84a23b917f206cce85749c84739ccd8c1
4
+ data.tar.gz: bd673c8ab74f4a2c6c046d27e40994cd7a819ad6e552b5a98e14fc1974f52bcc
5
5
  SHA512:
6
- metadata.gz: 4d2f96411424735612533763d8e79430bcc52792399732de0b06ab9e9a5f07e3ec3329ffd04a479353d050753e404b6b0d66dbb920a26cc2f985a066dad10751
7
- data.tar.gz: aff4fe39dabe60aee449c15e57656c7deaf33e73de8bbbc5a046186bec2fe6c79370e024ae86a4acb8f5b00218515a41bbf5fcf0468a56a8352474a8b6c5885f
6
+ metadata.gz: 49d328773bd999a1270386fec416f6a4afa0aa88d8fe6fe51e42af84e134154ac80b0220426c7be1b45e534ab2c164dc5ff22a9c0208f2d623c67aaba1be621e
7
+ data.tar.gz: fe000f50ed0f0b55a2b4efedc4fbedbf0bfcbf61039b64dd8584384cd0cf317d31e8b8db2d1bb79ae1b46dffcd6165ce27835d57cd5a9b86fbabdf976675dd21
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kube_cluster (0.6.0)
4
+ kube_cluster (0.7.0)
5
5
  kube_kubectl (~> 2.0)
6
6
  kube_schema (~> 1.5)
7
7
  scampi (~> 0.1)
@@ -30,7 +30,7 @@ module Kube
30
30
  # class Cluster < Kube::Cluster["HelmChart"]
31
31
  # def initialize(&block)
32
32
  # super {
33
- # metadata.name = "cloudnative-pg"
33
+ # metadata.name = "cloudnative-pg--cluster"
34
34
  # metadata.namespace = "kube-system"
35
35
  # spec.chart = "cluster"
36
36
  # spec.version = "0.6.1"
@@ -46,7 +46,7 @@ module Kube
46
46
  class Barman < Kube::Cluster["HelmChart"]
47
47
  def initialize(&block)
48
48
  super {
49
- metadata.name = "cloudnative-pg"
49
+ metadata.name = "plugin-barman-cloud"
50
50
  metadata.namespace = "kube-system"
51
51
  spec.chart = "plugin-barman-cloud"
52
52
  spec.version = "0.6.0"
@@ -65,27 +65,33 @@ module Kube
65
65
  end
66
66
 
67
67
  test do
68
- it "Operator initializes without error" do
69
- Kube::Cluster::Standard::CloudNativePg::Helm::Operator
70
- .new()
71
- .to_yaml
72
- .is_a?(String)
73
- .should == true
68
+ describe "Operator" do
69
+ it "initializes without error" do
70
+ Kube::Cluster::Standard::CloudNativePg::Helm::Operator
71
+ .new()
72
+ .to_yaml
73
+ .is_a?(String)
74
+ .should == true
75
+ end
74
76
  end
75
77
 
76
- # it "Cluster initializes without error" do
77
- # Kube::Cluster::Standard::CloudNativePg::Helm::Cluster
78
- # .new()
79
- # .to_yaml
80
- # .is_a?(String)
81
- # .should == true
82
- # end
78
+ #describe "Cluster" do
79
+ # it "initializes without error" do
80
+ # Kube::Cluster::Standard::CloudNativePg::Helm::Cluster
81
+ # .new()
82
+ # .to_yaml
83
+ # .is_a?(String)
84
+ # .should == true
85
+ # end
86
+ #end
83
87
 
84
- it "Barman initializes without error" do
85
- Kube::Cluster::Standard::CloudNativePg::Helm::Barman
86
- .new()
87
- .to_yaml
88
- .is_a?(String)
89
- .should == true
88
+ describe "Barman" do
89
+ it "initializes without error" do
90
+ Kube::Cluster::Standard::CloudNativePg::Helm::Barman
91
+ .new()
92
+ .to_yaml
93
+ .is_a?(String)
94
+ .should == true
95
+ end
90
96
  end
91
97
  end
@@ -0,0 +1,152 @@
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 DeploymentWithService < Kube::Cluster::Manifest
10
+ def initialize(
11
+ name:,
12
+ image:,
13
+ port:,
14
+ namespace: 'default',
15
+ env: {},
16
+ security_context: nil,
17
+ pod_security_context: nil,
18
+ volume_mounts: {},
19
+ service_port: nil,
20
+ &block
21
+ )
22
+ @_limits = {}
23
+ @_probes = {}
24
+
25
+ processed_env = EnvProcessing.process(env)
26
+ processed_volumes = VolumeProcessing.process(volume_mounts)
27
+
28
+ service_ports = Array(service_port || port)
29
+
30
+ service = Kube::Cluster::Standard::Service.new(
31
+ name: name,
32
+ namespace: namespace,
33
+ ports: service_ports
34
+ )
35
+
36
+ deployment = Kube::Cluster['Deployment'].new do
37
+ metadata.name = name
38
+ metadata.namespace = namespace
39
+ metadata.labels = { 'app' => name }
40
+
41
+ spec.replicas = 1
42
+ spec.selector.matchLabels = { 'app' => name }
43
+
44
+ spec.template.metadata.labels = { 'app' => name }
45
+ spec.template.spec.securityContext = pod_security_context if pod_security_context
46
+
47
+ container = {
48
+ name: name,
49
+ image: image,
50
+ ports: [{ name: 'http', containerPort: port, protocol: 'TCP' }],
51
+ env: processed_env
52
+ }
53
+ container[:securityContext] = security_context if security_context
54
+ container[:volumeMounts] = processed_volumes[:volume_mounts] unless processed_volumes[:volume_mounts].empty?
55
+
56
+ spec.template.spec.containers = [container]
57
+ spec.template.spec.volumes = processed_volumes[:volumes] unless processed_volumes[:volumes].empty?
58
+ end
59
+
60
+ super(deployment, service)
61
+
62
+ instance_exec(&block) if block
63
+
64
+ _apply_limits(deployment)
65
+ _apply_probes(deployment)
66
+ end
67
+
68
+ def limits
69
+ @_limits
70
+ end
71
+
72
+ def probes
73
+ @_probes
74
+ end
75
+
76
+ private
77
+
78
+ def _apply_limits(deployment)
79
+ return if @_limits.empty?
80
+
81
+ container = deployment.to_h[:spec][:template][:spec][:containers][0]
82
+ resources = {}
83
+
84
+ @_limits.each do |resource_type, mapping|
85
+ mapping.each do |request, limit|
86
+ resources[:requests] ||= {}
87
+ resources[:requests][resource_type] = request.to_s
88
+
89
+ if limit != Float::INFINITY
90
+ resources[:limits] ||= {}
91
+ resources[:limits][resource_type] = limit.to_s
92
+ end
93
+ end
94
+ end
95
+
96
+ container[:resources] = resources
97
+ h = deployment.to_h
98
+ h[:spec][:template][:spec][:containers][0] = container
99
+ deployment.rebuild(h)
100
+ end
101
+
102
+ def _apply_probes(deployment)
103
+ return if @_probes.empty?
104
+ return unless @_probes[:url]
105
+
106
+ container = deployment.to_h[:spec][:template][:spec][:containers][0]
107
+ url = @_probes[:url]
108
+
109
+ if @_probes[:liveness]
110
+ delay, period = @_probes[:liveness].first
111
+ container[:livenessProbe] = {
112
+ httpGet: url,
113
+ initialDelaySeconds: delay,
114
+ periodSeconds: period,
115
+ timeoutSeconds: 5
116
+ }
117
+ end
118
+
119
+ if @_probes[:readiness]
120
+ delay, period = @_probes[:readiness].first
121
+ container[:readinessProbe] = {
122
+ httpGet: url,
123
+ initialDelaySeconds: delay,
124
+ periodSeconds: period,
125
+ timeoutSeconds: 5
126
+ }
127
+ end
128
+
129
+ h = deployment.to_h
130
+ h[:spec][:template][:spec][:containers][0] = container
131
+ deployment.rebuild(h)
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ test do
139
+ describe "DeploymentWithService" do
140
+ it "initializes without error" do
141
+ Kube::Cluster::Standard::DeploymentWithService
142
+ .new(
143
+ name: "pointless-ruby-container",
144
+ image: "ruby/ruby",
145
+ port: 3000,
146
+ )
147
+ .to_yaml
148
+ .is_a?(String)
149
+ .should == true
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,42 @@
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 EnvProcessing
10
+ # Convert an env hash into a Kubernetes env array.
11
+ #
12
+ # String/numeric values become plain env vars:
13
+ # "FOO" => "bar" => { name: "FOO", value: "bar" }
14
+ #
15
+ # ExternalSecret::TemplateRef values become secretKeyRef env vars
16
+ # and register the template entry on the ExternalSecret:
17
+ # "FOO" => secret.template("{{ .bar }}")
18
+ # => { name: "FOO", valueFrom: { secretKeyRef: { name: "secret-name", key: "FOO" } } }
19
+ #
20
+ def self.process(env)
21
+ return env if env.is_a?(Array)
22
+ return [] if env.nil?
23
+
24
+ env.map do |key, value|
25
+ key = key.to_s
26
+
27
+ if value.is_a?(ExternalSecret::TemplateRef)
28
+ value.secret.register_template!(key, value.template_value)
29
+ { name: key, valueFrom: { secretKeyRef: { name: value.secret.secret_name, key: key } } }
30
+ else
31
+ { name: key, value: value.to_s }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ test do
41
+ # no op
42
+ end
@@ -0,0 +1,34 @@
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 Secret < Kube::Cluster["Secret"]
10
+ def initialize(name:, **data, &block)
11
+ super() {
12
+ metadata.name = name
13
+ data.each { |k, v| stringData[k.to_s] = v }
14
+ instance_exec(&block) if block_given?
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ test do
23
+ describe "Secret" do
24
+ it "initializes without error" do
25
+ Kube::Cluster::Standard::Secret
26
+ .new(
27
+ name: "my-secret"
28
+ )
29
+ .to_yaml
30
+ .is_a?(String)
31
+ .should == true
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
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 Service < Kube::Cluster["Service"]
10
+ def initialize(name:, ports:, namespace: "default", **options, &block)
11
+ super() {
12
+ metadata.name = name
13
+ metadata.namespace = namespace
14
+ metadata.labels = { "app" => name }
15
+ spec.selector = { "app" => name }
16
+ spec.ports = ports.map do |port|
17
+ { name: "http-#{port}", port: port, targetPort: port, protocol: "TCP" }
18
+ end
19
+
20
+ instance_exec(&block) if block_given?
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ test do
29
+ describe "Service" do
30
+ it "initializes without error" do
31
+ Kube::Cluster::Standard::Service
32
+ .new(
33
+ name: "my-secret",
34
+ ports: [],
35
+ )
36
+ .to_yaml
37
+ .is_a?(String)
38
+ .should == true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,88 @@
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 VolumeProcessing
10
+ # Convert a volume_mounts hash into Kubernetes volumes and volumeMounts arrays.
11
+ #
12
+ # Hash values (mount path => source ref):
13
+ # ExternalSecret::KeyRef => secret volume with items, mount with subPath + readOnly
14
+ # ExternalSecret => secret volume, directory mount
15
+ # PersistentVolumeClaim => persistentVolumeClaim volume, plain mount
16
+ #
17
+ # Legacy: if input is an Array, it is returned as-is for backwards compat.
18
+ #
19
+ def self.process(input)
20
+ return { volumes: [], volume_mounts: input } if input.is_a?(Array)
21
+ return { volumes: [], volume_mounts: [] } if input.nil? || input.empty?
22
+
23
+ volumes = []
24
+ mounts = []
25
+
26
+ input.each do |mount_path, source|
27
+ case source
28
+ when ExternalSecret::KeyRef
29
+ name = source.secret.secret_name
30
+ key = source.key_name
31
+ volumes << {
32
+ name: name,
33
+ secret: {
34
+ secretName: name,
35
+ items: [{ key: key, path: key }]
36
+ }
37
+ }
38
+ mounts << {
39
+ name: name,
40
+ mountPath: mount_path,
41
+ subPath: key,
42
+ readOnly: true
43
+ }
44
+
45
+ when ExternalSecret
46
+ name = source.secret_name
47
+ volumes << { name: name, secret: { secretName: name } }
48
+ mounts << { name: name, mountPath: mount_path }
49
+
50
+ when PersistentVolumeClaim
51
+ name = source.to_h.dig(:metadata, :name)
52
+ volumes << { name: name, persistentVolumeClaim: { claimName: name } }
53
+ mounts << { name: name, mountPath: mount_path }
54
+
55
+ when ConfigMap::KeyRef
56
+ name = source.config_map.config_map_name
57
+ key = source.key_name
58
+ volumes << {
59
+ name: name,
60
+ configMap: {
61
+ name: name,
62
+ items: [{ key: key, path: key }]
63
+ }
64
+ }
65
+ mounts << {
66
+ name: name,
67
+ mountPath: mount_path,
68
+ subPath: key,
69
+ readOnly: true
70
+ }
71
+
72
+ when ConfigMap
73
+ name = source.to_h.dig(:metadata, :name)
74
+ volumes << { name: name, configMap: { name: name } }
75
+ mounts << { name: name, mountPath: mount_path, readOnly: true }
76
+ end
77
+ end
78
+
79
+ { volumes: volumes, volume_mounts: mounts }
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ test do
87
+ # no op
88
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kube
4
4
  module Cluster
5
- VERSION = "0.6.0"
5
+ VERSION = "0.7.0"
6
6
  end
7
7
  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.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan K
@@ -197,6 +197,11 @@ files:
197
197
  - lib/kube/cluster/script_command.rb
198
198
  - lib/kube/cluster/standard/cloud_native_pg.rb
199
199
  - lib/kube/cluster/standard/cloud_native_pg/helm.rb
200
+ - lib/kube/cluster/standard/deployment_with_service.rb
201
+ - lib/kube/cluster/standard/env_processing.rb
202
+ - lib/kube/cluster/standard/secret.rb
203
+ - lib/kube/cluster/standard/service.rb
204
+ - lib/kube/cluster/standard/volume_processing.rb
200
205
  - lib/kube/cluster/version.rb
201
206
  - lib/kube/cluster/version.rb.erb
202
207
  - lib/kube/errors.rb