kubernetes-deploy 0.15.2 → 0.16.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/.buildkite/pipeline.nightly.yml +0 -7
- data/.buildkite/pipeline.yml +6 -6
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/README.md +94 -7
- data/Rakefile +20 -2
- data/bin/ci +2 -0
- data/bin/setup +2 -2
- data/bin/test +42 -5
- data/dev.yml +1 -1
- data/lib/kubernetes-deploy.rb +1 -1
- data/lib/kubernetes-deploy/deploy_task.rb +8 -27
- data/lib/kubernetes-deploy/kubernetes_resource/daemon_set.rb +1 -0
- data/lib/kubernetes-deploy/renderer.rb +116 -0
- data/lib/kubernetes-deploy/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6184836f627f154591e094a5d5311614b1a35d71
|
4
|
+
data.tar.gz: e17050ecc7698c759e9669e0b52327ff67c038c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f43cef2d6cf0aa8454ae2c46f47a9095c65f9faf13c235a0cd29e74d23518cb5575bb927bfba084190af55d9db1e325259ce6bce9596a9218a29ee7b74bee721
|
7
|
+
data.tar.gz: bdbac63fceea6418db1e30dc12e115782c26ffb17ce04437ec5992d3c3695ad6fc8cca10e7ae33cd22c9f95f91789732b290627446dd3f52be89536fbaf42895
|
data/.buildkite/pipeline.yml
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
- name: 'Run Test Suite (:kubernetes: 1.
|
1
|
+
- name: 'Run Test Suite (:kubernetes: 1.9-latest)'
|
2
2
|
command: bin/ci
|
3
3
|
agents:
|
4
4
|
queue: minikube-ci
|
5
5
|
env:
|
6
6
|
LOGGING_LEVEL: 4
|
7
|
-
KUBERNETES_VERSION: v1.
|
8
|
-
- name: 'Run Test Suite (:kubernetes: 1.
|
7
|
+
KUBERNETES_VERSION: v1.9-latest
|
8
|
+
- name: 'Run Test Suite (:kubernetes: 1.8-latest)'
|
9
9
|
command: bin/ci
|
10
10
|
agents:
|
11
11
|
queue: minikube-ci
|
12
12
|
env:
|
13
13
|
LOGGING_LEVEL: 4
|
14
|
-
KUBERNETES_VERSION: v1.
|
15
|
-
- name: 'Run Test Suite (:kubernetes: 1.
|
14
|
+
KUBERNETES_VERSION: v1.8-latest
|
15
|
+
- name: 'Run Test Suite (:kubernetes: 1.7-latest)'
|
16
16
|
command: bin/ci
|
17
17
|
agents:
|
18
18
|
queue: minikube-ci
|
19
19
|
env:
|
20
20
|
LOGGING_LEVEL: 4
|
21
|
-
KUBERNETES_VERSION: v1.
|
21
|
+
KUBERNETES_VERSION: v1.7-latest
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
### 0.16.0
|
2
|
+
**Important:** This release changes the officially supported Kubernetes versions to v1.7 through v1.9. Other versions may continue to work, but we are no longer running our test suite against them.
|
3
|
+
|
4
|
+
*Features*
|
5
|
+
- Support partials to reduce duplication in yaml files ([#207](https://github.com/Shopify/kubernetes-deploy/pull/207))
|
6
|
+
|
7
|
+
*Bug Fixes*
|
8
|
+
- Handle podless deamon sets properly ([#242](https://github.com/Shopify/kubernetes-deploy/pull/242))
|
9
|
+
|
1
10
|
### 0.15.2
|
2
11
|
*Enhancements*
|
3
12
|
- Print warnings if kubernetes server version is not supported ([#237](https://github.com/Shopify/kubernetes-deploy/pull/237)).
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -68,17 +68,19 @@ This repo also includes related tools for [running tasks](#kubernetes-run) and [
|
|
68
68
|
## Prerequisites
|
69
69
|
|
70
70
|
* Ruby 2.3+
|
71
|
-
* Your cluster must be running Kubernetes v1.
|
71
|
+
* Your cluster must be running Kubernetes v1.7.0 or higher<sup>1</sup>
|
72
72
|
* Each app must have a deploy directory containing its Kubernetes templates (see [Templates](#templates))
|
73
73
|
* You must remove the` kubectl.kubernetes.io/last-applied-configuration` annotation from any resources in the namespace that are not included in your deploy directory. This annotation is added automatically when you create resources with `kubectl apply`. `kubernetes-deploy` will prune any resources that have this annotation and are not in the deploy directory.**
|
74
|
-
* Each app managed by `kubernetes-deploy` must have its own exclusive Kubernetes namespace
|
74
|
+
* Each app managed by `kubernetes-deploy` must have its own exclusive Kubernetes namespace.<sup>2</sup>
|
75
75
|
|
76
|
+
<sup>1</sup> We run integration tests against these Kubernetes versions. Kubernetes v1.6 was officially supported in gem versions < 0.16. Kubernetes v1.5 was officially supported in gem versions < 0.12.
|
77
|
+
|
78
|
+
<sup>2</sup> This requirement can be bypassed with the `--no-prune` option, but it is not recommended.
|
76
79
|
|
77
|
-
**This requirement can be bypassed with the `--no-prune` option, but it is not recommended.
|
78
80
|
|
79
81
|
## Installation
|
80
82
|
|
81
|
-
1. [Install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-via-curl) (requires v1.
|
83
|
+
1. [Install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-via-curl) (requires v1.7.0 or higher) and make sure it is available in your $PATH
|
82
84
|
2. Set up your [kubeconfig file](https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/) for access to your cluster(s).
|
83
85
|
3. `gem install kubernetes-deploy`
|
84
86
|
|
@@ -120,6 +122,92 @@ All templates must be YAML formatted. You can also use ERB. The following local
|
|
120
122
|
|
121
123
|
You can add additional variables using the `--bindings=BINDINGS` option. For example, `kubernetes-deploy my-app cluster1 --bindings=color=blue,size=large` will expose `color` and `size` in your templates.
|
122
124
|
|
125
|
+
#### Using partials
|
126
|
+
|
127
|
+
`kubernetes-deploy` supports composing templates from so called partials in order to reduce duplication in Kubernetes YAML files. Given a template directory `DIR`, partials are searched for in `DIR/partials`and in 'DIR/../partials', in that order. They can be embedded in other ERB templates using the helper method `partial`. For example, let's assume an application needs a number of different CronJob resources, one could place a template called `cron` in one of those directories and then use it in the main deployment.yaml.erb like so:
|
128
|
+
|
129
|
+
```yaml
|
130
|
+
<%= partial "cron", name: "cleanup", schedule: "0 0 * * *", args: %w(cleanup), cpu: "100m", memory: "100Mi" %>
|
131
|
+
<%= partial "cron", name: "send-mail", schedule: "0 0 * * *", args: %w(send-mails), cpu: "200m", memory: "256Mi" %>
|
132
|
+
```
|
133
|
+
|
134
|
+
Inside a partial, parameters can be accessed as normal variables, or via a hash called `locals`. Thus, the `cron` template could like this:
|
135
|
+
|
136
|
+
```yaml
|
137
|
+
---
|
138
|
+
apiVersion: batch/v1beta1
|
139
|
+
kind: CronJob
|
140
|
+
metadata:
|
141
|
+
name: cron-<%= name %>
|
142
|
+
spec:
|
143
|
+
schedule: <%= schedule %>
|
144
|
+
successfulJobsHistoryLimit: 3
|
145
|
+
failedJobsHistoryLimit: 3
|
146
|
+
concurrencyPolicy: Forbid
|
147
|
+
jobTemplate:
|
148
|
+
spec:
|
149
|
+
template:
|
150
|
+
spec:
|
151
|
+
containers:
|
152
|
+
- name: cron-<%= name %>
|
153
|
+
image: ...
|
154
|
+
args: <%= args %>
|
155
|
+
resources:
|
156
|
+
requests:
|
157
|
+
cpu: "<%= cpu %>"
|
158
|
+
memory: <%= memory %>
|
159
|
+
restartPolicy: OnFailure
|
160
|
+
```
|
161
|
+
|
162
|
+
Both `.yaml.erb` and `.yml.erb` file extensions are supported. Templates must refer to the bare filename (e.g. use `partial: 'cron'` to reference `cron.yaml.erb`).
|
163
|
+
|
164
|
+
##### Limitations when using partials
|
165
|
+
|
166
|
+
Partials can be included almost everywhere in ERB templates, with one notable exception: you cannot use a partial to define a subset of fields. For example, given a partial `p` defining two fields 'a' and 'b',
|
167
|
+
|
168
|
+
```yaml
|
169
|
+
a: 1
|
170
|
+
b: 2
|
171
|
+
```
|
172
|
+
|
173
|
+
you cannot do this:
|
174
|
+
|
175
|
+
```yaml
|
176
|
+
x: yz
|
177
|
+
<%= partial 'p' %>
|
178
|
+
```
|
179
|
+
|
180
|
+
hoping to get
|
181
|
+
|
182
|
+
```yaml
|
183
|
+
x: yz
|
184
|
+
a: 1
|
185
|
+
b: 2
|
186
|
+
```
|
187
|
+
|
188
|
+
but you can do:
|
189
|
+
|
190
|
+
```yaml
|
191
|
+
x:
|
192
|
+
<%= partial 'p' %>
|
193
|
+
```
|
194
|
+
|
195
|
+
or even
|
196
|
+
|
197
|
+
```yaml
|
198
|
+
x: <%= partial 'p' %>
|
199
|
+
```
|
200
|
+
|
201
|
+
which both will result in
|
202
|
+
|
203
|
+
```yaml
|
204
|
+
x:
|
205
|
+
a: 1
|
206
|
+
b: 2
|
207
|
+
```
|
208
|
+
|
209
|
+
This is a limitation of the current implementation.
|
210
|
+
|
123
211
|
|
124
212
|
### Customizing behaviour with annotations
|
125
213
|
- `kubernetes-deploy.shopify.io/timeout-override`: Override the tool's hard timeout for one specific resource. Both full ISO8601 durations and the time portion of ISO8601 durations are valid. Value must be between 1 second and 24 hours.
|
@@ -137,7 +225,6 @@ before the deployment is considered successful.
|
|
137
225
|
- Percent (e.g. 90%): The deploy is successful when the number of new pods that are ready is equal to
|
138
226
|
`spec.replicas` * Percent.
|
139
227
|
|
140
|
-
|
141
228
|
### Running tasks at the beginning of a deploy
|
142
229
|
|
143
230
|
To run a task in your cluster at the beginning of every deploy, simply include a `Pod` template in your deploy directory. `kubernetes-deploy` will first deploy any `ConfigMap` and `PersistentVolumeClaim` resources in your template set, followed by any such pods. If the command run by one of these pods fails (i.e. exits with a non-zero status), the overall deploy will fail at this step (no other resources will be deployed).
|
@@ -249,7 +336,7 @@ With this done, you can use the following command to restart all of them:
|
|
249
336
|
|
250
337
|
## Prerequisites
|
251
338
|
|
252
|
-
* You've already deployed a [`PodTemplate`](https://kubernetes.io/docs/api-reference/v1.
|
339
|
+
* You've already deployed a [`PodTemplate`](https://kubernetes.io/docs/api-reference/v1.9/#podtemplate-v1-core) object with field `template` containing a `Pod` specification that does not include the `apiVersion` or `kind` parameters. An example is provided in this repo in `test/fixtures/hello-cloud/template-runner.yml`.
|
253
340
|
* The `Pod` specification in that template has a container named `task-runner`.
|
254
341
|
|
255
342
|
Based on this specification `kubernetes-run` will create a new pod with the entrypoint of the `task-runner ` container overridden with the supplied arguments.
|
@@ -275,7 +362,7 @@ Based on this specification `kubernetes-run` will create a new pod with the entr
|
|
275
362
|
|
276
363
|
If you work for Shopify, just run `dev up`, but otherwise:
|
277
364
|
|
278
|
-
1. [Install kubectl version 1.
|
365
|
+
1. [Install kubectl version 1.7.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) and make sure it is in your path
|
279
366
|
2. [Install minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (required to run the test suite)
|
280
367
|
3. Check out the repo
|
281
368
|
4. Run `bin/setup` to install dependencies
|
data/Rakefile
CHANGED
@@ -2,10 +2,28 @@
|
|
2
2
|
require "bundler/gem_tasks"
|
3
3
|
require "rake/testtask"
|
4
4
|
|
5
|
-
|
5
|
+
desc "Run integration tests that can be run in parallel"
|
6
|
+
Rake::TestTask.new(:integration_test) do |t|
|
6
7
|
t.libs << "test"
|
7
8
|
t.libs << "lib"
|
8
|
-
t.test_files = FileList['test/**/*_test.rb']
|
9
|
+
t.test_files = FileList['test/integration/**/*_test.rb']
|
9
10
|
end
|
10
11
|
|
12
|
+
desc "Run integration tests that CANNOT be run in parallel"
|
13
|
+
Rake::TestTask.new(:serial_integration_test) do |t|
|
14
|
+
t.libs << "test"
|
15
|
+
t.libs << "lib"
|
16
|
+
t.test_files = FileList['test/integration-serial/**/*_test.rb']
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Run unit tests"
|
20
|
+
Rake::TestTask.new(:unit_test) do |t|
|
21
|
+
t.libs << "test"
|
22
|
+
t.libs << "lib"
|
23
|
+
t.test_files = FileList['test/unit/**/*_test.rb']
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Run all tests"
|
27
|
+
task test: %w(unit_test serial_integration_test integration_test)
|
28
|
+
|
11
29
|
task default: :test
|
data/bin/ci
CHANGED
data/bin/setup
CHANGED
@@ -9,8 +9,8 @@ if [ ! -x "$(which minikube)" ]; then
|
|
9
9
|
fi
|
10
10
|
|
11
11
|
if [ ! -x "$(which kubectl)" ]; then
|
12
|
-
echo -e "\n\033[0;33mPlease install kubectl version 1.
|
12
|
+
echo -e "\n\033[0;33mPlease install kubectl version 1.7.0 or higher:\nhttps://kubernetes.io/docs/user-guide/prereqs/\033[0m"
|
13
13
|
else
|
14
14
|
KUBECTL_VERSION=$(kubectl version --short --client | grep -oe "v[[:digit:]\.]\+")
|
15
|
-
echo -e "\n\033[0;32mKubectl version $KUBECTL_VERSION is already installed. This gem requires version v1.
|
15
|
+
echo -e "\n\033[0;32mKubectl version $KUBECTL_VERSION is already installed. This gem requires version v1.7.0 or greater.\033[0m"
|
16
16
|
fi
|
data/bin/test
CHANGED
@@ -1,7 +1,44 @@
|
|
1
1
|
#!/bin/bash
|
2
|
-
set -
|
2
|
+
set -uo pipefail
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
err=0
|
5
|
+
trap 'err=1' ERR
|
6
|
+
trap 'exit 1' SIGINT
|
7
|
+
|
8
|
+
function print_header() {
|
9
|
+
if [[ ${CI:="0"} == "1" ]]; then
|
10
|
+
printf "+++ :kubernetes: %s\n" "${1}"
|
11
|
+
else
|
12
|
+
printf "\n\n\033[0;35m⎈ %s\033[0m\n" "${1}"
|
13
|
+
fi
|
14
|
+
}
|
15
|
+
|
16
|
+
if [[ ${PARALLELISM:=0} -lt 1 ]]; then
|
17
|
+
if [[ $(uname) == "Darwin" ]]; then
|
18
|
+
num_cpus=$(sysctl -n hw.ncpu)
|
19
|
+
else
|
20
|
+
num_cpus=$(nproc --all)
|
21
|
+
fi
|
22
|
+
|
23
|
+
if [[ $num_cpus -le 2 ]]; then
|
24
|
+
PARALLELISM=1
|
25
|
+
else
|
26
|
+
(( PARALLELISM=num_cpus/2 ))
|
27
|
+
fi
|
28
|
+
fi
|
29
|
+
|
30
|
+
if [[ ${CI:="0"} == "1" ]]; then
|
31
|
+
echo "--- :ruby: Bundle Install"
|
32
|
+
bundle install --jobs 4
|
33
|
+
fi
|
34
|
+
|
35
|
+
print_header "Run Unit Tests"
|
36
|
+
bundle exec rake unit_test
|
37
|
+
|
38
|
+
print_header "Run Non-Parallel Integration Tests"
|
39
|
+
bundle exec rake serial_integration_test
|
40
|
+
|
41
|
+
print_header "Run Parallel Integration Tests (N=$PARALLELISM)"
|
42
|
+
PARALLELIZE_ME=1 N=$PARALLELISM bundle exec rake integration_test
|
43
|
+
|
44
|
+
test $err -eq 0
|
data/dev.yml
CHANGED
@@ -13,7 +13,7 @@ up:
|
|
13
13
|
commands:
|
14
14
|
reset-minikube: minikube delete && rm -rf ~/.minikube
|
15
15
|
test:
|
16
|
-
run:
|
16
|
+
run: bin/test
|
17
17
|
tophat:
|
18
18
|
run: PRINT_LOGS=1 bundle exec ruby -I test test/integration/kubernetes_deploy_test.rb -n/${1}/
|
19
19
|
desc: Tophat a change by running a test scenario with logging output enabled.
|
data/lib/kubernetes-deploy.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'open3'
|
3
|
-
require 'securerandom'
|
4
|
-
require 'erb'
|
5
3
|
require 'yaml'
|
6
4
|
require 'shellwords'
|
7
5
|
require 'tempfile'
|
@@ -36,6 +34,7 @@ require 'kubernetes-deploy/resource_watcher'
|
|
36
34
|
require 'kubernetes-deploy/kubectl'
|
37
35
|
require 'kubernetes-deploy/kubeclient_builder'
|
38
36
|
require 'kubernetes-deploy/ejson_secret_provisioner'
|
37
|
+
require 'kubernetes-deploy/renderer'
|
39
38
|
|
40
39
|
module KubernetesDeploy
|
41
40
|
class DeployTask
|
@@ -98,9 +97,12 @@ module KubernetesDeploy
|
|
98
97
|
@template_dir = File.expand_path(template_dir)
|
99
98
|
@logger = logger
|
100
99
|
@kubectl = kubectl_instance
|
101
|
-
@
|
102
|
-
|
103
|
-
|
100
|
+
@renderer = KubernetesDeploy::Renderer.new(
|
101
|
+
current_sha: @current_sha,
|
102
|
+
template_dir: @template_dir,
|
103
|
+
logger: @logger,
|
104
|
+
bindings: bindings,
|
105
|
+
)
|
104
106
|
end
|
105
107
|
|
106
108
|
def run(verify_result: true, allow_protected_ns: false, prune: true)
|
@@ -167,13 +169,6 @@ module KubernetesDeploy
|
|
167
169
|
success
|
168
170
|
end
|
169
171
|
|
170
|
-
def template_variables
|
171
|
-
{
|
172
|
-
'current_sha' => @current_sha,
|
173
|
-
'deployment_id' => @id,
|
174
|
-
}.merge(@bindings)
|
175
|
-
end
|
176
|
-
|
177
172
|
private
|
178
173
|
|
179
174
|
# Inspect the file referenced in the kubectl stderr
|
@@ -234,7 +229,7 @@ module KubernetesDeploy
|
|
234
229
|
|
235
230
|
def split_templates(filename)
|
236
231
|
file_content = File.read(File.join(@template_dir, filename))
|
237
|
-
rendered_content = render_template(filename, file_content)
|
232
|
+
rendered_content = @renderer.render_template(filename, file_content)
|
238
233
|
YAML.load_stream(rendered_content) do |doc|
|
239
234
|
yield doc unless doc.blank?
|
240
235
|
end
|
@@ -271,20 +266,6 @@ module KubernetesDeploy
|
|
271
266
|
" " + str.gsub("\n", "\n ")
|
272
267
|
end
|
273
268
|
|
274
|
-
def render_template(filename, raw_template)
|
275
|
-
return raw_template unless File.extname(filename) == ".erb"
|
276
|
-
|
277
|
-
erb_template = ERB.new(raw_template)
|
278
|
-
erb_binding = binding
|
279
|
-
template_variables.each do |var_name, value|
|
280
|
-
erb_binding.local_variable_set(var_name, value)
|
281
|
-
end
|
282
|
-
erb_template.result(erb_binding)
|
283
|
-
rescue NameError => e
|
284
|
-
@logger.summary.add_paragraph("Error from renderer:\n #{e.message.tr("\n", ' ')}")
|
285
|
-
raise FatalDeploymentError, "Template '#{filename}' cannot be rendered"
|
286
|
-
end
|
287
|
-
|
288
269
|
def validate_configuration(allow_protected_ns:, prune:)
|
289
270
|
errors = []
|
290
271
|
if ENV["KUBECONFIG"].blank?
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'securerandom'
|
5
|
+
require 'yaml'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module KubernetesDeploy
|
9
|
+
class Renderer
|
10
|
+
class InvalidPartialError < FatalDeploymentError
|
11
|
+
attr_reader :parents
|
12
|
+
def initialize(msg, parents = [])
|
13
|
+
@parents = parents
|
14
|
+
super(msg)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
class PartialNotFound < InvalidPartialError; end
|
18
|
+
|
19
|
+
def initialize(current_sha:, template_dir:, logger:, bindings: {})
|
20
|
+
@current_sha = current_sha
|
21
|
+
@template_dir = template_dir
|
22
|
+
@partials_dirs =
|
23
|
+
%w(partials ../partials).map { |d| File.expand_path(File.join(@template_dir, d)) }
|
24
|
+
@logger = logger
|
25
|
+
@bindings = bindings
|
26
|
+
# Max length of podname is only 63chars so try to save some room by truncating sha to 8 chars
|
27
|
+
@id = current_sha[0...8] + "-#{SecureRandom.hex(4)}" if current_sha
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_template(filename, raw_template)
|
31
|
+
return raw_template unless File.extname(filename) == ".erb"
|
32
|
+
|
33
|
+
erb_binding = TemplateContext.new(self).template_binding
|
34
|
+
bind_template_variables(erb_binding, template_variables)
|
35
|
+
|
36
|
+
ERB.new(raw_template, nil, '-').result(erb_binding)
|
37
|
+
rescue InvalidPartialError => err
|
38
|
+
all_parents = err.parents.dup.unshift(filename)
|
39
|
+
raise FatalDeploymentError, "#{err.message} (included from: #{all_parents.join(' -> ')})"
|
40
|
+
rescue StandardError => err
|
41
|
+
report_template_invalid(err.message, raw_template)
|
42
|
+
raise FatalDeploymentError, "Template '#{filename}' cannot be rendered"
|
43
|
+
end
|
44
|
+
|
45
|
+
def render_partial(partial, locals)
|
46
|
+
variables = template_variables.merge(locals)
|
47
|
+
erb_binding = TemplateContext.new(self).template_binding
|
48
|
+
bind_template_variables(erb_binding, variables)
|
49
|
+
erb_binding.local_variable_set("locals", locals)
|
50
|
+
|
51
|
+
partial_path = find_partial(partial)
|
52
|
+
template = File.read(partial_path)
|
53
|
+
expanded_template = ERB.new(template, nil, '-').result(erb_binding)
|
54
|
+
|
55
|
+
docs = Psych.parse_stream(expanded_template)
|
56
|
+
# If the partial contains multiple documents or has an explicit document header,
|
57
|
+
# we know it cannot validly be indented in the parent, so return it immediately.
|
58
|
+
return expanded_template unless docs.children.one? && docs.children.first.implicit
|
59
|
+
# Make sure indentation isn't a problem by producing a single line of parseable YAML.
|
60
|
+
# Note that JSON is a subset of YAML.
|
61
|
+
JSON.generate(docs.children.first.to_ruby)
|
62
|
+
rescue PartialNotFound => err
|
63
|
+
raise InvalidPartialError, err.message
|
64
|
+
rescue InvalidPartialError => err
|
65
|
+
raise InvalidPartialError.new(err.message, err.parents.dup.unshift(File.basename(partial_path)))
|
66
|
+
rescue StandardError => err
|
67
|
+
report_template_invalid(err.message, expanded_template)
|
68
|
+
raise InvalidPartialError, "Template '#{partial_path}' cannot be rendered"
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def template_variables
|
74
|
+
{
|
75
|
+
'current_sha' => @current_sha,
|
76
|
+
'deployment_id' => @id,
|
77
|
+
}.merge(@bindings)
|
78
|
+
end
|
79
|
+
|
80
|
+
def bind_template_variables(erb_binding, variables)
|
81
|
+
variables.each do |var_name, value|
|
82
|
+
erb_binding.local_variable_set(var_name, value)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_partial(name)
|
87
|
+
partial_names = [name + '.yaml.erb', name + '.yml.erb']
|
88
|
+
@partials_dirs.each do |dir|
|
89
|
+
partial_names.each do |partial_name|
|
90
|
+
partial_path = File.join(dir, partial_name)
|
91
|
+
return partial_path if File.exist?(partial_path)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
raise PartialNotFound, "Could not find partial '#{name}' in any of #{@partials_dirs.join(':')}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def report_template_invalid(message, content)
|
98
|
+
@logger.summary.add_paragraph("Error from renderer:\n #{message.tr("\n", ' ')}")
|
99
|
+
@logger.summary.add_paragraph("Rendered template content:\n#{content}")
|
100
|
+
end
|
101
|
+
|
102
|
+
class TemplateContext
|
103
|
+
def initialize(renderer)
|
104
|
+
@_renderer = renderer
|
105
|
+
end
|
106
|
+
|
107
|
+
def template_binding
|
108
|
+
binding
|
109
|
+
end
|
110
|
+
|
111
|
+
def partial(partial, locals = {})
|
112
|
+
@_renderer.render_partial(partial, locals)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
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.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Verey
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-02-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -258,6 +258,7 @@ files:
|
|
258
258
|
- lib/kubernetes-deploy/kubernetes_resource/stateful_set.rb
|
259
259
|
- lib/kubernetes-deploy/kubernetes_resource/statefulservice.rb
|
260
260
|
- lib/kubernetes-deploy/kubernetes_resource/topic.rb
|
261
|
+
- lib/kubernetes-deploy/renderer.rb
|
261
262
|
- lib/kubernetes-deploy/resource_watcher.rb
|
262
263
|
- lib/kubernetes-deploy/restart_task.rb
|
263
264
|
- lib/kubernetes-deploy/runner_task.rb
|