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