kubernetes-deploy 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
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
|