kubernetes-deploy 0.6.2 → 0.6.3
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
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 315b39149d1da2c636e590c936d537c2cf99efd1
|
4
|
+
data.tar.gz: 2a6a00d4408877852e7e50ac11648a5598fcdf57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0847ad6ae5468233e7223a1947a06e3f19552bf6e32d6aba0c2aa2470d5118c4e4a7f3d0957326efe9dcebaf4086e81c513bde9ad220761b76407379a22b795
|
7
|
+
data.tar.gz: 72d92f343209f183cbae64f4dc59413d17bd7883a8182e4a8f8352cb9629d89b7f6b114bb1356a278a4dd9d198040def3ec680735bbe8be39a4b36c921c71e55
|
data/.rubocop.yml
CHANGED
@@ -3,6 +3,7 @@ require 'json'
|
|
3
3
|
require 'base64'
|
4
4
|
require 'open3'
|
5
5
|
require 'kubernetes-deploy/logger'
|
6
|
+
require 'kubernetes-deploy/kubectl'
|
6
7
|
|
7
8
|
module KubernetesDeploy
|
8
9
|
class EjsonSecretError < FatalDeploymentError
|
@@ -17,10 +18,13 @@ module KubernetesDeploy
|
|
17
18
|
EJSON_SECRETS_FILE = "secrets.ejson"
|
18
19
|
EJSON_KEYS_SECRET = "ejson-keys"
|
19
20
|
|
20
|
-
def initialize(namespace:,
|
21
|
+
def initialize(namespace:, context:, template_dir:)
|
21
22
|
@namespace = namespace
|
23
|
+
@context = context
|
22
24
|
@ejson_file = "#{template_dir}/#{EJSON_SECRETS_FILE}"
|
23
|
-
|
25
|
+
|
26
|
+
raise FatalDeploymentError, "Cannot create secrets without a namespace" if @namespace.blank?
|
27
|
+
raise FatalDeploymentError, "Cannot create secrets without a context" if @context.blank?
|
24
28
|
end
|
25
29
|
|
26
30
|
def secret_changes_required?
|
@@ -52,25 +56,27 @@ module KubernetesDeploy
|
|
52
56
|
|
53
57
|
def prune_managed_secrets
|
54
58
|
ejson_secret_names = encrypted_ejson.fetch(MANAGED_SECRET_EJSON_KEY, {}).keys
|
55
|
-
live_secrets =
|
59
|
+
live_secrets = run_kubectl_json("get", "secrets")
|
56
60
|
|
57
61
|
live_secrets.each do |secret|
|
58
|
-
secret_name = secret
|
62
|
+
secret_name = secret["metadata"]["name"]
|
59
63
|
next unless secret_managed?(secret)
|
60
64
|
next if ejson_secret_names.include?(secret_name)
|
61
65
|
|
62
66
|
KubernetesDeploy.logger.info("Pruning secret #{secret_name}")
|
63
|
-
|
67
|
+
out, err, st = run_kubectl("delete", "secret", secret_name)
|
68
|
+
KubernetesDeploy.logger.debug(out)
|
69
|
+
raise EjsonSecretError, err unless st.success?
|
64
70
|
end
|
65
71
|
end
|
66
72
|
|
67
73
|
def managed_secrets_exist?
|
68
|
-
all_secrets =
|
74
|
+
all_secrets = run_kubectl_json("get", "secrets")
|
69
75
|
all_secrets.any? { |secret| secret_managed?(secret) }
|
70
76
|
end
|
71
77
|
|
72
78
|
def secret_managed?(secret)
|
73
|
-
secret
|
79
|
+
secret["metadata"].fetch("annotations", {}).key?(MANAGEMENT_ANNOTATION)
|
74
80
|
end
|
75
81
|
|
76
82
|
def encrypted_ejson
|
@@ -96,31 +102,47 @@ module KubernetesDeploy
|
|
96
102
|
end
|
97
103
|
|
98
104
|
def create_or_update_secret(secret_name, secret_type, data)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
105
|
+
msg = secret_exists?(secret_name) ? "Updating secret #{secret_name}" : "Creating secret #{secret_name}"
|
106
|
+
KubernetesDeploy.logger.info(msg)
|
107
|
+
|
108
|
+
secret_yaml = generate_secret_yaml(secret_name, secret_type, data)
|
109
|
+
file = Tempfile.new(secret_name)
|
110
|
+
file.write(secret_yaml)
|
111
|
+
file.close
|
112
|
+
|
113
|
+
out, err, st = run_kubectl("apply", "--filename=#{file.path}")
|
114
|
+
KubernetesDeploy.logger.debug(out)
|
115
|
+
raise EjsonSecretError, err unless st.success?
|
116
|
+
ensure
|
117
|
+
file.unlink if file
|
118
|
+
end
|
119
|
+
|
120
|
+
def generate_secret_yaml(secret_name, secret_type, data)
|
121
|
+
unless data.is_a?(Hash) && data.values.all? { |v| v.is_a?(String) } # Secret data is map[string]string
|
122
|
+
raise EjsonSecretError, "Data for secret #{secret_name} was invalid. Only key-value pairs are permitted."
|
123
|
+
end
|
124
|
+
encoded_data = data.each_with_object({}) do |(key, value), encoded|
|
125
|
+
encoded[key] = Base64.encode64(value)
|
112
126
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
127
|
+
|
128
|
+
secret = {
|
129
|
+
'kind' => 'Secret',
|
130
|
+
'apiVersion' => 'v1',
|
131
|
+
'type' => secret_type,
|
132
|
+
'metadata' => {
|
133
|
+
"name" => secret_name,
|
134
|
+
"labels" => { "name" => secret_name },
|
135
|
+
"namespace" => @namespace,
|
136
|
+
"annotations" => { MANAGEMENT_ANNOTATION => "true" }
|
137
|
+
},
|
138
|
+
"data" => encoded_data
|
139
|
+
}
|
140
|
+
secret.to_yaml
|
116
141
|
end
|
117
142
|
|
118
|
-
def secret_exists?(
|
119
|
-
|
120
|
-
|
121
|
-
rescue KubeException => error
|
122
|
-
raise unless error.error_code == 404
|
123
|
-
false
|
143
|
+
def secret_exists?(secret_name)
|
144
|
+
_out, _err, st = run_kubectl("get", "secret", secret_name)
|
145
|
+
st.success?
|
124
146
|
end
|
125
147
|
|
126
148
|
def load_ejson_from_file
|
@@ -152,17 +174,26 @@ module KubernetesDeploy
|
|
152
174
|
|
153
175
|
def fetch_private_key_from_secret
|
154
176
|
KubernetesDeploy.logger.info("Fetching ejson private key from secret #{EJSON_KEYS_SECRET}")
|
155
|
-
|
177
|
+
|
178
|
+
secret = run_kubectl_json("get", "secret", EJSON_KEYS_SECRET)
|
156
179
|
encoded_private_key = secret["data"][public_key]
|
157
180
|
unless encoded_private_key
|
158
181
|
raise EjsonSecretError, "Private key for #{public_key} not found in #{EJSON_KEYS_SECRET} secret"
|
159
182
|
end
|
160
183
|
|
161
184
|
Base64.decode64(encoded_private_key)
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
185
|
+
end
|
186
|
+
|
187
|
+
def run_kubectl_json(*args)
|
188
|
+
args += ["--output=json"]
|
189
|
+
out, err, st = run_kubectl(*args)
|
190
|
+
raise EjsonSecretError, err unless st.success?
|
191
|
+
result = JSON.parse(out)
|
192
|
+
result.fetch('items', result)
|
193
|
+
end
|
194
|
+
|
195
|
+
def run_kubectl(*args)
|
196
|
+
Kubectl.run_kubectl(*args, namespace: @namespace, context: @context)
|
166
197
|
end
|
167
198
|
end
|
168
199
|
end
|
@@ -113,11 +113,7 @@ MSG
|
|
113
113
|
phase_heading("Checking initial resource statuses")
|
114
114
|
resources.each(&:sync)
|
115
115
|
|
116
|
-
ejson = EjsonSecretProvisioner.new(
|
117
|
-
namespace: @namespace,
|
118
|
-
template_dir: @template_dir,
|
119
|
-
client: build_v1_kubeclient(@context)
|
120
|
-
)
|
116
|
+
ejson = EjsonSecretProvisioner.new(namespace: @namespace, context: @context, template_dir: @template_dir)
|
121
117
|
if ejson.secret_changes_required?
|
122
118
|
phase_heading("Deploying kubernetes secrets from #{EjsonSecretProvisioner::EJSON_SECRETS_FILE}")
|
123
119
|
ejson.run
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kubernetes-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kir Shatrov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-05-
|
13
|
+
date: 2017-05-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|