kubernetes-deploy 0.8.0 → 0.8.1

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: aef7562f456f0a5ad138410f5110fd34ac2231fe
4
- data.tar.gz: e421c6d5a6cded2f76ffbb88a677946f54017269
3
+ metadata.gz: 0a6a0a8232035518d42b8dd709c236df5ee436bb
4
+ data.tar.gz: b1e8c26dc53fe92a2e22bec894badc46c2e292f4
5
5
  SHA512:
6
- metadata.gz: b48a5e45f3b8ce91a2d7cff2aa243e052b5bb89836463931993682fa58ceef4878738e19f1dae01cb80019a885eb5d8dfe30cd8b529927f09024e092f296a19e
7
- data.tar.gz: 02ae5cc6c72a61bd0fd4b65667bac7dd17c4e6f049252722cb8263d8b9c31240834ff47277355912a87be9be3e49fd1cf13a85d301ca253c0d6bf90e78778a1d
6
+ metadata.gz: d94033e6774153f24ddbee8fa6e560636ba091cbc3e5a6ac24cab07dc2ac0ed2132d1ce6d5a5a60529e2d309e2589bf42e24c55893a7b48aa034d042afdfcb74
7
+ data.tar.gz: ef4456ba9e4303a70af71dbf36f63c5a4a4b24c31fa556b34f968dcc59e543c51fe937e4a084b85c4fb659033e8711125d98e637909fa92e89259fbc5a426367
data/README.md CHANGED
@@ -1,46 +1,143 @@
1
- # Kubernetes::Deploy
1
+ # kubernetes-deploy [![Build status](https://badge.buildkite.com/0f2d4956d49fbc795f9c17b0a741a6aa9ea532738e5f872ac8.svg?branch=master)](https://buildkite.com/shopify/kubernetes-deploy-gem)
2
2
 
3
- [![Build status](https://badge.buildkite.com/0f2d4956d49fbc795f9c17b0a741a6aa9ea532738e5f872ac8.svg?branch=master)](https://buildkite.com/shopify/kubernetes-deploy-gem)
3
+ `kubernetes-deploy` is a command line tool that helps you ship changes to a Kubernetes namespace and understand the result. At Shopify, we use it within our much-beloved, open-source [Shipit](https://github.com/Shopify/shipit-engine#kubernetes) deployment app.
4
4
 
5
- Deploy script used to manage a Kubernetes application's namespace with [Shipit](https://github.com/Shopify/shipit-engine).
5
+ Why not just use the standard `kubectl apply` mechanism to deploy? It is indeed a fantastic tool; `kubernetes-deploy` uses it under the hood! However, it leaves its users with some burning questions: _What just happened?_ _Did it work?_
6
6
 
7
- ## Installation
7
+ Especially in a CI/CD environment, we need a clear, actionable pass/fail result for each deploy. Providing this was the foundational goal of `kubernetes-deploy`, which has grown to support the following core features:
8
8
 
9
- Add this line to your application's Gemfile:
9
+ ​:eyes: Watches the changes you requested to make sure they roll out successfully.
10
10
 
11
- ```ruby
12
- gem 'kubernetes-deploy'
13
- ```
11
+ :interrobang: Provides debug information for changes that failed.
12
+
13
+ :1234: Predeploys certain types of resources (e.g. ConfigMap, PersistentVolumeClaim) to make sure the latest version will be available when resources that might consume them (e.g. Deployment) are deployed.
14
+
15
+ :closed_lock_with_key: [Creates Kubernetes secrets from encrypted EJSON](#deploying-kubernetes-secrets-from-ejson), which you can safely commit to your repository
16
+
17
+ ​:running: [Runs tasks at the beginning of the deploy](#deploy-time-tasks) using bare pods (example use case: Rails migrations)
18
+
19
+ This repo also includes related tools for [running tasks](#kubernetes-run) and [restarting deployments](#kubernetes-restart).
20
+
21
+ ![success](screenshots/success.png)
22
+
23
+
24
+
25
+ ![missing-secret-fail](screenshots/missing-secret-fail.png)
26
+
27
+
28
+
29
+ --------
30
+
31
+
32
+
33
+ ## Table of contents
34
+
35
+ **KUBERNETES-DEPLOY**
36
+ * [Prerequisites](#prerequisites)
37
+ * [Installation](#installation)
38
+ * [Usage](#usage)
39
+ * [Using templates and variables](#using-templates-and-variables)
40
+ * [Running tasks at the beginning of a deploy](#running-tasks-at-the-beginning-of-a-deploy)
41
+ * [Deploying Kubernetes secrets (from EJSON)](#deploying-kubernetes-secrets-from-ejson)
42
+
43
+ **KUBERNETES-RESTART**
44
+ * [Usage](#usage-1)
45
+
46
+ **KUBERNETES-RUN**
47
+ * [Prerequisites](#prerequisites-1)
48
+ * [Usage](#usage-2)
49
+
50
+ **DEVELOPMENT**
51
+ * [Setup](#setup)
52
+ * [Running the test suite locally](#running-the-test-suite-locally)
53
+ * [Releasing a new version (Shopify employees)](#releasing-a-new-version-shopify-employees)
54
+ * [CI (Shopify employees)](#ci-shopify-employees)
55
+ * [CI (External contributors)](#ci-external-contributors)
56
+
57
+ **CONTRIBUTING**
58
+ * [Contributing](#contributing)
59
+ * [License](#license)
60
+
61
+
62
+ ----------
63
+
64
+
65
+
66
+ ## Prerequisites
14
67
 
15
- And then execute:
68
+ * Your cluster must be running Kubernetes v1.6.0 or higher
69
+ * Each app must have a deploy directory containing its Kubernetes templates (see [Templates](#templates))
70
+ * 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.**
71
+ * Each app managed by `kubernetes-deploy` must have its own exclusive Kubernetes namespace.**
72
+
73
+
74
+ **This requirement can be bypassed with the `--no-prune` option, but it is not recommended.
75
+
76
+ ## Installation
77
+
78
+ 1. [Install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-via-curl) (requires v1.6.0 or higher) and make sure it is available in your $PATH
79
+ 2. Set up your [kubeconfig file](https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/) for access to your cluster(s).
80
+ 3. `gem install kubernetes-deploy`
16
81
 
17
- $ bundle
18
82
 
19
- Or install it yourself as:
20
83
 
21
- $ gem install kubernetes-deploy
22
84
 
23
85
  ## Usage
24
86
 
25
- `kubernetes-deploy <app's namespace> <kube context> --template-dir=DIR`
87
+ `kubernetes-deploy <app's namespace> <kube context>`
26
88
 
27
- Requirements:
89
+ *Environment variables:*
28
90
 
29
- - kubectl 1.6.0+ binary must be available in your path
30
- - `ENV['KUBECONFIG']` must point to a valid kubeconfig file that includes the context you want to deploy to
31
- - The target namespace must already exist in the target context
32
- - `ENV['GOOGLE_APPLICATION_CREDENTIALS']` must point to the credentials for an authenticated service account if your user's auth provider is GCP
33
- - `ENV['ENVIRONMENT']` must be set to use the default template path (`config/deploy/$ENVIRONMENT`) in the absence of the `--template-dir=DIR` option
91
+ - `$REVISION` **(required)**: the SHA of the commit you are deploying. Will be exposed to your ERB templates as `current_sha`.
92
+ - `$KUBECONFIG` **(required)**: points to a valid kubeconfig file that includes the context you want to deploy to
93
+ - `$ENVIRONMENT`: used to set the deploy directory to `config/deploy/$ENVIRONMENT`. You can use the `--template-dir=DIR` option instead if you prefer (**one or the other is required**).
94
+ - `$GOOGLE_APPLICATION_CREDENTIALS`: points to the credentials for an authenticated service account (required if your kubeconfig `user`'s auth provider is GCP)
34
95
 
35
- The tool also provides a task for restarting all of the pods in one or more deployments.
36
- It triggers the restart by touching the `RESTARTED_AT` environment variable in the deployment's podSpec.
37
- The rollout strategy defined for each deployment will be respected by the restart.
38
96
 
39
- The following command will restart all pods in the `web` and `jobs` deployments:
97
+ *Options:*
98
+
99
+ - `--bindings=BINDINGS`: Makes additional variables available to your ERB templates. For example, `kubernetes-deploy my-app cluster1 --bindings=color=blue,size=large` will expose `color` and `size`.
100
+ - `--verbose-log-prefix`: Prefixes each log line with `[#{context}][#{namespace}][#{severity}][#{datetime}]` instead of just `[#{severity}][#{datetime}]`. Useful if you're running multiple concurrent deploys in Shipit.
101
+ - `--allow-protected-ns`: Enables you to deploy to `default`, `kube-system` or `kube-public` if you really know what you're doing. Must be used with `--no-prune` (pruning a protected namespace cannot be enabled).
102
+ - `--no-prune`: Skips pruning of resources that are no longer in your Kubernetes template set. Not recommended, as it allows your namespace to accumulate cruft that is not reflected in your deploy directory.
103
+ - `--skip-wait`: Verifies the result of predeployed resources only. Declares success immediately after the bulk `kubectl apply` operation. Not recommended, as it skips a huge part of the value of this tool.
104
+
105
+
106
+
107
+
108
+
109
+ ### Using templates and variables
110
+
111
+ Each app's templates are expected to be stored in a single directory. If this is not the case, you can create a directory containing symlinks to the templates. The recommended location for app's deploy directory is `{app root}/config/deploy/{env}`, but this is completely configurable.
112
+
113
+ All templates must be YAML formatted. You can also use ERB. The following local variables will be available to your ERB templates by default:
114
+
115
+ * `current_sha`: The value of `$REVISION`
116
+ * `deployment_id`: A randomly generated identifier for the deploy. Useful for creating unique names for task-runner pods (e.g. a pod that runs rails migrations at the beginning of deploys).
117
+
118
+ 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.
119
+
120
+
121
+
122
+ ### Running tasks at the beginning of a deploy
123
+
124
+ 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).
125
+
126
+ *Requirements:*
127
+
128
+ * The pod's name should include `<%= deployment_id %>` to ensure that a unique name will be used on every deploy (the deploy will fail if a pod with the same name already exists).
129
+ * The pod's `spec.restartPolicy` must be set to `Never` so that it will be run exactly once. We'll fail the deploy if that run exits with a non-zero status.
130
+ * The pod's `spec.activeDeadlineSeconds` should be set to a reasonable value for the performed task (not required, but highly recommended)
131
+
132
+ A simple example can be found in the test fixtures: test/fixtures/hello-cloud/unmanaged-pod.yml.erb.
133
+
134
+ The logs of all pods run in this way will be printed inline.
135
+
136
+ ![migrate-logs](screenshots/migrate-logs.png)
40
137
 
41
- `kubernetes-restart <kube namespace> <kube context> --deployments=web,jobs`
42
138
 
43
- ### Deploying Kubernetes secrets
139
+
140
+ ### Deploying Kubernetes secrets (from EJSON)
44
141
 
45
142
  **Note: If you're a Shopify employee using our cloud platform, this setup has already been done for you. Please consult the CloudPlatform User Guide for usage instructions.**
46
143
 
@@ -91,59 +188,130 @@ Since their data is only base64 encoded, Kubernetes secrets should not be commit
91
188
  }
92
189
  ```
93
190
 
94
- ### Running one off tasks
95
191
 
96
- To trigger a one-off job such as a rake task _outside_ of a deploy, use the following command:
97
192
 
98
- `kubernetes-run <kube namespace> <kube context> <arguments> --entrypoint=/bin/bash`
193
+ # kubernetes-restart
194
+
195
+ `kubernetes-restart` is a tool for restarting all of the pods in one or more deployments. It triggers the restart by touching the `RESTARTED_AT` environment variable in the deployment's podSpec. The rollout strategy defined for each deployment will be respected by the restart.
196
+
197
+
198
+
199
+ ## Usage
200
+
201
+ The following command will restart all pods in the `web` and `jobs` deployments:
202
+
203
+ `kubernetes-restart <kube namespace> <kube context> --deployments=web,jobs`
204
+
205
+
99
206
 
100
- This command assumes that you've already deployed a `PodTemplate` named `task-runner-template`, which contains a full pod specification in its `data`. The pod specification in turn must have a container named `task-runner`. Based on this specification `kubernetes-run` will create a new pod with the entrypoint of the task-runner container overriden with the supplied arguments.
207
+ # kubernetes-run
101
208
 
102
- #### Creating a PodTemplate
209
+ `kubernetes-run` is a tool for triggering a one-off job, such as a rake task, _outside_ of a deploy.
103
210
 
104
- The [`PodTemplate`](https://kubernetes.io/docs/api-reference/v1.6/#podtemplate-v1-core) object should have a field `template` containing a `Pod` specification which does not include the `apiVersion` or `kind` parameters. An example is provided in this repo in `test/fixtures/hello-cloud/template-runner.yml`.
105
211
 
106
- #### Providing multiple different task-runner configurations
107
212
 
108
- If your application requires task runner templates you can specify which template to use by using the `--template` option. All templates are expected to provide a container called `task-runner`.
213
+ ## Prerequisites
109
214
 
110
- #### Specifying environment variables for the container
215
+ * You've already deployed a [`PodTemplate`](https://kubernetes.io/docs/api-reference/v1.6/#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`.
216
+ * The `Pod` specification in that template has a container named `task-runner`.
111
217
 
112
- If you also need to specify environment variables on top of the arguments, you can specify the `--env-vars` flag which accepts a comma separated list of environment variables like so: `--env-vars="ENV=VAL,ENV2=VAL"`
218
+ Based on this specification `kubernetes-run` will create a new pod with the entrypoint of the `task-runner ` container overridden with the supplied arguments.
113
219
 
114
220
 
115
- ## Development
116
221
 
117
- After checking out the repo, run `bin/setup` to install dependencies. You currently need to [manually install kubectl version 1.6.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) as well if you don't already have it.
222
+ ## Usage
223
+
224
+ `kubernetes-run <kube namespace> <kube context> <arguments> --entrypoint=/bin/bash`
225
+
226
+ *Options:*
227
+
228
+ * `--template=TEMPLATE`: Specifies the name of the PodTemplate to use (default is `task-runner-template` if this option is not set).
229
+ * `--env-vars=ENV_VARS`: Accepts a comma separated list of environment variables to be added to the pod template. For example, `--env-vars="ENV=VAL,ENV2=VAL2"` will make `ENV` and `ENV2` available to the container.
230
+
231
+
118
232
 
119
- To run the tests:
120
233
 
121
- * [Install minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation)
122
- * Start minikube (`minikube start [options]`)
123
- * Make sure you have a context named "minikube" in your kubeconfig. Minikube adds this context for you when you run `minikube start`; please do not rename it. You can check for it using `kubectl config get-contexts`.
124
- * Run `bundle exec rake test`
234
+
235
+ # Development
236
+
237
+ ## Setup
238
+
239
+ 1. [Install kubectl version 1.6.0 or higher](https://kubernetes.io/docs/user-guide/prereqs/) and make sure it is in your path
240
+ 2. [Install minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (required to run the test suite)
241
+ 3. Check out the repo
242
+ 4. Run `bin/setup` to install dependencies
125
243
 
126
244
  To install this gem onto your local machine, run `bundle exec rake install`.
127
245
 
128
- To release a new version:
129
246
 
130
- * Update the version number in `version.rb`
131
- * Tag the version with `git tag vx.y.z && git push --tags`
132
- * A Shopify employee can use the [Shipit Stack](https://shipit.shopify.io/shopify/kubernetes-deploy/rubygems) to build the `.gem` file and upload to [rubygems.org](https://rubygems.org/gems/kubernetes-deploy).
133
247
 
134
- ## CI
248
+ ## Running the test suite locally
249
+
250
+ 1. Start [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/#installation) (`minikube start [options]`)
251
+ 2. Make sure you have a context named "minikube" in your kubeconfig. Minikube adds this context for you when you run `minikube start`; please do not rename it. You can check for it using `kubectl config get-contexts`.
252
+ 3. Run `bundle exec rake test`
253
+
254
+
135
255
 
136
- Buildkite will build branches as you're working on them, but as soon as you create a PR it will stop building new commits from that branch because we disabled PR builds for security reasons.
137
- As a Shopify employee, you can manually trigger the PR build from the Buildkite UI (just specify the branch, SHA is not required):
256
+ To see the full-color output of a specific integration test, you can use `PRINT_LOGS=1 bundle exec ruby -I test test/integration/kubernetes_deploy_test.rb -n/test_name/`.
257
+
258
+
259
+
260
+ ![test-output](screenshots/test-output.png)
261
+
262
+
263
+
264
+ ## Releasing a new version (Shopify employees)
265
+
266
+ 1. Update the version number in `version.rb` and commit that change alone to master.
267
+ 2. Tag the version with `git tag vx.y.z && git push --tags`
268
+ 3. Use the [Shipit Stack](https://shipit.shopify.io/shopify/kubernetes-deploy/rubygems) to build the `.gem` file and upload to [rubygems.org](https://rubygems.org/gems/kubernetes-deploy).
269
+
270
+ If Shipit fails with `You need to create the v0.7.9 tag first.` even though you're sure you've already pushed that tag, go to `Settings` > `Resynchronize this stack` > `Clear git cache`.
271
+
272
+
273
+
274
+ ## CI (Shopify employees)
275
+
276
+ Buildkite will build branches as you're working on them, but as soon as you create a PR it will stop building new commits from that branch because we disabled PR builds for security reasons. You can manually trigger the PR build from the [Buildkite UI](https://buildkite.com/shopify/kubernetes-deploy-gem) (just specify the branch; SHA is not required).
138
277
 
139
278
  <img width="464" alt="screen shot 2017-02-21 at 10 55 33" src="https://cloud.githubusercontent.com/assets/522155/23172610/52771a3a-f824-11e6-8c8e-3d59c45e7ff8.png">
140
279
 
141
280
 
142
- ## Contributing
143
281
 
144
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/kubernetes-deploy.
282
+ ## CI (External contributors)
283
+
284
+ Please make sure you run the tests locally before submitting your PR (see [Running the test suite locally](#running-the-test-suite-locally)). A Shopify employee will trigger CI for you after reviewing your PR.
285
+
286
+
287
+
288
+ # Contributing
289
+
290
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/kubernetes-deploy.
291
+
292
+ Contributions to help us support additional resource types or increase the sophistication of our success heuristics for an existing type are especially encouraged! (See tips below)
293
+
294
+
295
+
296
+ ### Contributing a new resource type
297
+
298
+ The list of fully supported types is effectively the list of classes found in `lib/kubernetes-deploy/kubernetes_resource/`.
299
+
300
+ This gem uses subclasses of `KubernetesResource` to implement custom success/failure detection logic for each resource type. If no subclass exists for a type you're deploying, the gem simply assumes `kubectl apply` succeeded (and prints a warning about this assumption). We're always looking to support more types! Here are the basic steps for contributing a new one:
301
+
302
+ 1. Create a the file for your type in `lib/kubernetes-deploy/kubernetes_resource/`
303
+ 2. Create a new class that inherits from `KubernetesResource`. Minimally, it should implement the following methods:
304
+ * `sync` -- gather/update the data you'll need to determine `deploy_succeeded?` and `deploy_failed?`
305
+ * `deploy_succeeded?`
306
+ * `deploy_failed?`
307
+ * `exists?`
308
+ 3. Adjust the `TIMEOUT` constant to an appropriate value for this type.
309
+ 4. Add the a basic example of the type to the hello-cloud [fixture set](https://github.com/Shopify/kubernetes-deploy/tree/master/test/fixtures/hello-cloud) and appropriate assertions to `#assert_all_up` in [`hello_cloud.rb`](https://github.com/Shopify/kubernetes-deploy/blob/master/test/helpers/fixture_sets/hello_cloud.rb). This will get you coverage in several existing tests, such as `test_full_hello_cloud_set_deploy_succeeds`.
310
+ 5. Add tests for any edge cases you foresee.
311
+
312
+
145
313
 
146
314
 
147
- ## License
315
+ # License
148
316
 
149
317
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -2,7 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'kubernetes-deploy'
5
-
6
5
  require 'optparse'
7
6
 
8
7
  skip_wait = false
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency "googleauth", ">= 0.5"
26
26
  spec.add_dependency "ejson", "1.0.1"
27
27
  spec.add_dependency "colorize", "~> 0.8"
28
+ spec.add_dependency "statsd-instrument", "~> 2.1"
28
29
 
29
30
  spec.add_development_dependency "bundler"
30
31
  spec.add_development_dependency "rake", "~> 10.0"
@@ -13,6 +13,8 @@ require 'colorized_string'
13
13
  require 'kubernetes-deploy/errors'
14
14
  require 'kubernetes-deploy/formatted_logger'
15
15
  require 'kubernetes-deploy/runner'
16
+ require 'kubernetes-deploy/statsd'
16
17
 
17
18
  module KubernetesDeploy
19
+ KubernetesDeploy::StatsD.build
18
20
  end
@@ -54,6 +54,7 @@ module KubernetesDeploy
54
54
  @context = context
55
55
  @logger = logger
56
56
  @definition = definition
57
+ @statsd_report_done = false
57
58
  end
58
59
 
59
60
  def id
@@ -184,6 +185,24 @@ module KubernetesDeploy
184
185
  @kubectl ||= Kubectl.new(namespace: @namespace, context: @context, logger: @logger, log_failure_by_default: false)
185
186
  end
186
187
 
188
+ def report_status_to_statsd(watch_time)
189
+ unless @statsd_report_done
190
+ status = if deploy_failed?
191
+ "failure"
192
+ elsif deploy_timed_out?
193
+ "timeout"
194
+ elsif deploy_succeeded?
195
+ "success"
196
+ else
197
+ "unknown"
198
+ end
199
+ tags = %W(namespace:#{namespace} resource:#{id} type:#{type} sha:#{ENV['REVISION']} status:#{status})
200
+ ::StatsD.measure('resource.duration', watch_time * 1000, tags: tags)
201
+ ::StatsD.increment('resource.status', 1, tags: tags)
202
+ @statsd_report_done = true
203
+ end
204
+ end
205
+
187
206
  class Event
188
207
  EVENT_SEPARATOR = "ENDEVENT--BEGINEVENT"
189
208
  FIELD_SEPARATOR = "ENDFIELD--BEGINFIELD"
@@ -39,6 +39,8 @@ module KubernetesDeploy
39
39
  private
40
40
 
41
41
  def report_what_just_happened(resources, watch_time)
42
+ resources.each { |r| r.report_status_to_statsd(watch_time) }
43
+
42
44
  new_successes, new_failures = resources.partition(&:deploy_succeeded?)
43
45
  new_failures.each do |resource|
44
46
  if resource.deploy_failed?
@@ -79,6 +79,7 @@ module KubernetesDeploy
79
79
  end
80
80
 
81
81
  def run(verify_result: true, allow_protected_ns: false, prune: true)
82
+ start = Time.now.utc
82
83
  @logger.reset
83
84
 
84
85
  @logger.phase_heading("Initializing deploy")
@@ -104,7 +105,9 @@ module KubernetesDeploy
104
105
 
105
106
  if deploy_has_priority_resources?(resources)
106
107
  @logger.phase_heading("Predeploying priority resources")
107
- predeploy_priority_resources(resources)
108
+ ::StatsD.measure('duration.priority_resources', tags: statsd_tags) do
109
+ predeploy_priority_resources(resources)
110
+ end
108
111
  end
109
112
 
110
113
  @logger.phase_heading("Deploying all resources")
@@ -113,7 +116,9 @@ module KubernetesDeploy
113
116
  end
114
117
 
115
118
  if verify_result
116
- deploy_resources(resources, prune: prune, verify: true)
119
+ ::StatsD.measure('duration.normal_resources', tags: statsd_tags) do
120
+ deploy_resources(resources, prune: prune, verify: true)
121
+ end
117
122
  record_statuses(resources)
118
123
  success = resources.all?(&:deploy_succeeded?)
119
124
  else
@@ -131,6 +136,7 @@ module KubernetesDeploy
131
136
  success = false
132
137
  ensure
133
138
  @logger.print_summary(success)
139
+ ::StatsD.measure('duration.total', (Time.now.utc - start) * 1000.0, tags: statsd_tags)
134
140
  success
135
141
  end
136
142
 
@@ -433,5 +439,9 @@ module KubernetesDeploy
433
439
  def kubectl
434
440
  @kubectl ||= Kubectl.new(namespace: @namespace, context: @context, logger: @logger, log_failure_by_default: true)
435
441
  end
442
+
443
+ def statsd_tags
444
+ %W(namespace:#{@namespace} sha:#{@current_sha})
445
+ end
436
446
  end
437
447
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ require 'statsd-instrument'
3
+ require 'logger'
4
+
5
+ module KubernetesDeploy
6
+ class StatsD
7
+ def self.build
8
+ ::StatsD.default_sample_rate = 1.0
9
+ ::StatsD.prefix = "KubernetesDeploy"
10
+
11
+ if ENV['STATSD_DEV'].present?
12
+ ::StatsD.backend = ::StatsD::Instrument::Backends::LoggerBackend.new(Logger.new($stderr))
13
+ elsif ENV['STATSD_ADDR'].present?
14
+ statsd_impl = ENV['STATSD_IMPLEMENTATION'].empty? ? "datadog" : ENV['STATSD_IMPLEMENTATION']
15
+ ::StatsD.backend = ::StatsD::Instrument::Backends::UDPBackend.new(ENV['STATSD_ADDR'], statsd_impl)
16
+ else
17
+ ::StatsD.backend = ::StatsD::Instrument::Backends::NullBackend.new
18
+ end
19
+ ::StatsD.backend
20
+ end
21
+ end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module KubernetesDeploy
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.1"
3
3
  end
Binary file
Binary file
Binary file
Binary file
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.8.0
4
+ version: 0.8.1
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: 2017-07-06 00:00:00.000000000 Z
12
+ date: 2017-07-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -81,6 +81,20 @@ dependencies:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0.8'
84
+ - !ruby/object:Gem::Dependency
85
+ name: statsd-instrument
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '2.1'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '2.1'
84
98
  - !ruby/object:Gem::Dependency
85
99
  name: bundler
86
100
  requirement: !ruby/object:Gem::Requirement
@@ -212,7 +226,12 @@ files:
212
226
  - lib/kubernetes-deploy/restart_task.rb
213
227
  - lib/kubernetes-deploy/runner.rb
214
228
  - lib/kubernetes-deploy/runner_task.rb
229
+ - lib/kubernetes-deploy/statsd.rb
215
230
  - lib/kubernetes-deploy/version.rb
231
+ - screenshots/migrate-logs.png
232
+ - screenshots/missing-secret-fail.png
233
+ - screenshots/success.png
234
+ - screenshots/test-output.png
216
235
  homepage: https://github.com/Shopify/kubernetes-deploy
217
236
  licenses:
218
237
  - MIT