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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/kube/cluster/standard/cloud_native_pg/helm.rb +27 -21
- data/lib/kube/cluster/standard/deployment_with_service.rb +152 -0
- data/lib/kube/cluster/standard/env_processing.rb +42 -0
- data/lib/kube/cluster/standard/secret.rb +34 -0
- data/lib/kube/cluster/standard/service.rb +41 -0
- data/lib/kube/cluster/standard/volume_processing.rb +88 -0
- data/lib/kube/cluster/version.rb +1 -1
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f1c23db70574ae658780a8fcdcaefa84a23b917f206cce85749c84739ccd8c1
|
|
4
|
+
data.tar.gz: bd673c8ab74f4a2c6c046d27e40994cd7a819ad6e552b5a98e14fc1974f52bcc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 49d328773bd999a1270386fec416f6a4afa0aa88d8fe6fe51e42af84e134154ac80b0220426c7be1b45e534ab2c164dc5ff22a9c0208f2d623c67aaba1be621e
|
|
7
|
+
data.tar.gz: fe000f50ed0f0b55a2b4efedc4fbedbf0bfcbf61039b64dd8584384cd0cf317d31e8b8db2d1bb79ae1b46dffcd6165ce27835d57cd5a9b86fbabdf976675dd21
|
data/Gemfile.lock
CHANGED
|
@@ -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 = "
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
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.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
|