kubernetes-deploy 0.31.1 → 1.0.0.pre.1
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 +7 -0
- data/.shopify-build/kubernetes-deploy.yml +7 -0
- data/1.0-Upgrade.md +109 -0
- data/CHANGELOG.md +16 -0
- data/README.md +1 -1
- data/lib/krane/cli/deploy_command.rb +11 -2
- data/lib/krane/cli/global_deploy_command.rb +10 -2
- data/lib/krane/cli/render_command.rb +13 -5
- data/lib/krane/cluster_resource_discovery.rb +36 -25
- data/lib/krane/deploy_task.rb +4 -0
- data/lib/krane/kubeclient_builder.rb +2 -2
- data/lib/krane/kubernetes_resource.rb +51 -2
- data/lib/krane/kubernetes_resource/daemon_set.rb +7 -3
- data/lib/krane/restart_task.rb +8 -4
- data/lib/krane/task_config.rb +1 -1
- data/lib/krane/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adeeeeb19772ea87237a9c1e3a9333ec3621227ef6fbb8f0106996d4919e860c
|
4
|
+
data.tar.gz: 1959eeadd28a63461b1c044918ec0209d9fbfe4d5aadeb51183b97f3889507c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a82ba6d6de049f378811a2c9aab6e2ffad869ee1c44f2e417a38bb310471cd404880fddf20a4e9eef40de45173a24640c2a18ec5ff8e08d15a5e8141f4be8ee
|
7
|
+
data.tar.gz: 5e79e0ac53ee91514d8d514f84688322dcc6d4b661c9f80380e87a35f2317838ed60fbc9b91c56d66566adb8b9a31239fb6ce10fb8896ed1f2f62a9daf9df385
|
@@ -9,6 +9,13 @@ steps:
|
|
9
9
|
- bundle exec rubocop
|
10
10
|
dependencies:
|
11
11
|
- bundler
|
12
|
+
- label: 'Run Test Suite (:kubernetes: 1.16-latest)'
|
13
|
+
command: bin/ci
|
14
|
+
agents:
|
15
|
+
queue: k8s-ci
|
16
|
+
env:
|
17
|
+
LOGGING_LEVEL: "4"
|
18
|
+
KUBERNETES_VERSION: v1.16-latest
|
12
19
|
- label: 'Run Test Suite (:kubernetes: 1.15-latest)'
|
13
20
|
command: bin/ci
|
14
21
|
agents:
|
data/1.0-Upgrade.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# kubernetes-deploy 0.31.1 -> krane 1.0.0 migration guide
|
2
|
+
|
3
|
+
**THIS MIGRATION GUIDE IS A WORK IN PROGRESS. THINGS CAN STILL CHANGE BEFORE 1.0.0**
|
4
|
+
|
5
|
+
`kubernetes-deploy` was renamed `krane` when version 1.0.0 was released. Version 1.0.0 introduced [new features and breaking changes](CHANGELOG.md). This guide will help you transition to version 1.0.0 as smoothly as possible.
|
6
|
+
|
7
|
+
**TL;DR**:
|
8
|
+
* The command-line interface was redesigned; alongside the name change there are breaking changes in several flags.
|
9
|
+
* There are breaking changes in the public API (such as the renaming of the `KubernetesDeploy` namespace to `Krane`, and the change in default values for different arguments of the public interface).
|
10
|
+
* StatsD metrics will now be generated with the `krane` prefix.
|
11
|
+
* `krane deploy` now considers all namespaced resources eligible for pruning, including
|
12
|
+
custom resources. See [blacklist](https://github.com/Shopify/kubernetes-deploy/blob/master/lib/krane/cluster_resource_discovery.rb#L20) for exceptions.
|
13
|
+
* `kubernetes-deploy` (now `krane deploy`) / `DeployTask` can no longer deploy global (non-namespaced) resources. A new command called `krane global-deploy` and a related class called `GlobalDeployTask` were added to replace that feature.
|
14
|
+
* If you attempt to install two gems that have conflicting executables, `gem install` will warn you but the most recently installed one will win.
|
15
|
+
|
16
|
+
## Public API changes
|
17
|
+
|
18
|
+
The only breaking change in the public API (so far) is the renaming of the `KubernetesDeploy` namespace to `Krane`. Otherwise, the APIs of the major public classes (`DeployTask`, `RenderTask`, `RunnerTask`, and `RestartTask`) have not changed between 0.31.1 and 1.0.0. If you're curious about this API, check the comment-based docs on these classes or the [rendered documentation at RubyGems.org](https://www.rubydoc.info/gems/kubernetes-deploy/1.0.0/KubernetesDeploy/DeployTask).
|
19
|
+
|
20
|
+
## Command-line interface changes
|
21
|
+
|
22
|
+
Old command | New command
|
23
|
+
--- | ---
|
24
|
+
`kubernetes-deploy` | `krane deploy`
|
25
|
+
`kubernetes-deploy -v` | `krane version`
|
26
|
+
`kubernetes-render` | `krane render`
|
27
|
+
`kubernetes-run` | `krane run`
|
28
|
+
`kubernetes-restart` | `krane restart`
|
29
|
+
`[kubernetes-deploy with global resources in templates]` | `krane global-deploy`
|
30
|
+
|
31
|
+
### Flag changes
|
32
|
+
|
33
|
+
The following tables provide a mapping of the flags previously supported in `kubernetes-deploy` and their new version in `krane` (if applicable).
|
34
|
+
|
35
|
+
Important: you can't repeat flags. If you need to provide multiple arguments for a flag, use a space-separated list (e.g. `-f file1.yml file2.yml`) unless specified otherwise.
|
36
|
+
|
37
|
+
#### krane deploy
|
38
|
+
|
39
|
+
Old flag | New flag | Comments
|
40
|
+
--- | --- | ---
|
41
|
+
--bindings=BINDINGS | --bindings=BINDINGS |
|
42
|
+
--skip-wait | --verify-result=true |
|
43
|
+
--allow-protected-ns | --protected-namespaces=default,kube-system,kube-public | Added the ability to specify which namespaces are protected
|
44
|
+
--no-prune | --prune=true |
|
45
|
+
--template-dir | -f, --filename | Makes all krane commands accept this argument, which is now required for the deploy task
|
46
|
+
--verbose-log-prefix | --verbose-log-prefix |
|
47
|
+
--max-watch-seconds=seconds | --global-timeout=300s | Changed flag name and default value to be a duration (expressed using strings like "300s" or "1h")
|
48
|
+
--selector | --selector |
|
49
|
+
-h, --help | -h, --help |
|
50
|
+
-v, --version | [none] | Replaced with `krane version`
|
51
|
+
$ENVIRONMENT | [none] | Dropped in favour of `-f`
|
52
|
+
$REVISION | --current-sha | The environment variable REVISION was dropped in favour of an explicit flag
|
53
|
+
[none] | --render-erb | **Important:** the new CLI doesn't render ERB by default
|
54
|
+
[none] | --stdin | Allow template filenames given from stdin stream
|
55
|
+
|
56
|
+
#### krane restart
|
57
|
+
|
58
|
+
Old flag | New flag | Comments
|
59
|
+
--- | --- | ---
|
60
|
+
--deployments=LIST | --deployments=LIST |
|
61
|
+
--max-watch-seconds=seconds | --global-timeout=300s | Changed flag name and default value to be a duration (expressed using strings like "300s" or "1h")
|
62
|
+
[none] | --verify-result=true | Defines whether it should wait for results or exit immediately after validation
|
63
|
+
|
64
|
+
#### krane run
|
65
|
+
|
66
|
+
Old flag | New flag | Comments
|
67
|
+
--- | --- | ---
|
68
|
+
--skip-wait | --verify-result=true |
|
69
|
+
--max-watch-seconds=seconds | --global-timeout=300s | Changed flag name and default value to be a duration (expressed using strings like "300s" or "1h")
|
70
|
+
--entrypoint | --command | Changed flag name to make its purpose clearer
|
71
|
+
--template | --template | Changed to be required
|
72
|
+
[it is positional now] | --arguments | Optional flag, as `command` or the template might already specify the required arguments
|
73
|
+
--env-vars=ENV_VARS | --env-vars=ENV_VARS |
|
74
|
+
|
75
|
+
#### krane render
|
76
|
+
|
77
|
+
Old flag | New flag | Comments
|
78
|
+
--- | --- | ---
|
79
|
+
--bindings=BINDINGS | --bindings=BINDINGS |
|
80
|
+
--template-dir | -f, --filename | Changed to be more aligned with `kubectl apply` and other krane tasks
|
81
|
+
$REVISION | --current-sha | The environment variable REVISION was dropped in favour of an explicit flag
|
82
|
+
[none] | --stdin | Allow template filenames given from stdin stream
|
83
|
+
|
84
|
+
## Running `kubernetes-deploy` and `krane` side by side
|
85
|
+
|
86
|
+
If you attempt to install two gems that have conflicting executables (as is the case here), `gem install` will warn you but the most recently installed one will win. This means that you can run both `kubernetes-deploy` 0.31.1 and `krane` 1.0.0 side by side by doing:
|
87
|
+
|
88
|
+
```bash
|
89
|
+
gem install kubernetes-deploy -v 0.31.1
|
90
|
+
gem install -f krane -v 1.0.0
|
91
|
+
```
|
92
|
+
|
93
|
+
This can help you incrementally port scripts that use the old CLI to the new one.
|
94
|
+
|
95
|
+
## New task: `krane global-deploy`
|
96
|
+
|
97
|
+
`krane global-deploy` (accessible through the Ruby API as `Krane::GlobalDeployTask`) can deploy global (non-namespaced) resources such as `PersistentVolume`, `Namespace`, and `CustomResourceDefinition`. Its interface is very similar to `krane deploy`. Example usage:
|
98
|
+
|
99
|
+
```bash
|
100
|
+
$ cat my-template.yml
|
101
|
+
apiVersion: storage.k8s.io/v1
|
102
|
+
kind: StorageClass
|
103
|
+
metadata:
|
104
|
+
name: testing-storage-class
|
105
|
+
labels:
|
106
|
+
app: krane
|
107
|
+
provisioner: kubernetes.io/no-provisioner
|
108
|
+
$ krane global-deploy my-k8s-context -f my-template.yml --selector app=krane
|
109
|
+
```
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,22 @@
|
|
3
3
|
*Important!*
|
4
4
|
- The next release will be 1.0.0, which means that master will contain breaking changes.
|
5
5
|
|
6
|
+
## 1.0.0.pre.1
|
7
|
+
|
8
|
+
*Important!*
|
9
|
+
|
10
|
+
- This is the final release of KubernetesDeploy. Version 1.0.0 will be released
|
11
|
+
under the name `Krane`. We've added a migration guide to help make it easier to migrate.
|
12
|
+
([#607](https://github.com/Shopify/kubernetes-deploy/pull/607))
|
13
|
+
|
14
|
+
*Enhancements*
|
15
|
+
- (beta) `krane deploy` will now consider all namespaced resources eligible for pruning
|
16
|
+
and does not respect the `krane.shopify.io/prunable` annotation. This adds 5 additional
|
17
|
+
types: Endpoints, Event, LimitRange, ReplicationController, and Lease.
|
18
|
+
([#616](https://github.com/Shopify/kubernetes-deploy/pull/616)
|
19
|
+
|
20
|
+
- (beta) Added the `--stdin` flag to `krane deploy|global-deploy|render` to read resources from stdin. ([#630](https://github.com/Shopify/kubernetes-deploy/pull/630))
|
21
|
+
|
6
22
|
## 0.31.1
|
7
23
|
|
8
24
|
*Bug Fixes*
|
data/README.md
CHANGED
@@ -524,7 +524,7 @@ The following command will restart all pods in the `web` and `jobs` deployments:
|
|
524
524
|
Add the annotation `shipit.shopify.io/restart` to all the deployments you want to target, like this:
|
525
525
|
|
526
526
|
```yaml
|
527
|
-
apiVersion: apps/
|
527
|
+
apiVersion: apps/v1
|
528
528
|
kind: Deployment
|
529
529
|
metadata:
|
530
530
|
name: web
|
@@ -14,8 +14,10 @@ module Krane
|
|
14
14
|
desc: "Expose additional variables to ERB templates (format: k1=v1 k2=v2, JSON string or file "\
|
15
15
|
"(JSON or YAML) path prefixed by '@')" },
|
16
16
|
"filenames" => { type: :array, banner: 'config/deploy/production config/deploy/my-extra-resource.yml',
|
17
|
-
aliases: :f, required:
|
17
|
+
aliases: :f, required: false, default: [],
|
18
18
|
desc: "Directories and files that contains the configuration to apply" },
|
19
|
+
"stdin" => { type: :boolean, default: false,
|
20
|
+
desc: "Read resources from stdin" },
|
19
21
|
"global-timeout" => { type: :string, banner: "duration", default: DEFAULT_DEPLOY_TIMEOUT,
|
20
22
|
desc: "Max duration to monitor workloads correctly deployed" },
|
21
23
|
"protected-namespaces" => { type: :array, banner: "namespace1 namespace2 namespaceN",
|
@@ -54,7 +56,14 @@ module Krane
|
|
54
56
|
protected_namespaces = []
|
55
57
|
end
|
56
58
|
|
57
|
-
|
59
|
+
# never mutate options directly
|
60
|
+
filenames = options[:filenames].dup
|
61
|
+
filenames << "-" if options[:stdin]
|
62
|
+
if filenames.empty?
|
63
|
+
raise Thor::RequiredArgumentMissingError, 'At least one of --filenames or --stdin must be set'
|
64
|
+
end
|
65
|
+
|
66
|
+
::Krane::OptionsHelper.with_processed_template_paths(filenames,
|
58
67
|
require_explicit_path: true) do |paths|
|
59
68
|
deploy = ::Krane::DeployTask.new(
|
60
69
|
namespace: namespace,
|
@@ -6,8 +6,9 @@ module Krane
|
|
6
6
|
DEFAULT_DEPLOY_TIMEOUT = '300s'
|
7
7
|
OPTIONS = {
|
8
8
|
"filenames" => { type: :array, banner: 'config/deploy/production config/deploy/my-extra-resource.yml',
|
9
|
-
aliases: :f, required:
|
9
|
+
aliases: :f, required: false, default: [],
|
10
10
|
desc: "Directories and files that contains the configuration to apply" },
|
11
|
+
"stdin" => { type: :boolean, default: false, desc: "Read resources from stdin" },
|
11
12
|
"global-timeout" => { type: :string, banner: "duration", default: DEFAULT_DEPLOY_TIMEOUT,
|
12
13
|
desc: "Max duration to monitor workloads correctly deployed" },
|
13
14
|
"verify-result" => { type: :boolean, default: true,
|
@@ -27,7 +28,14 @@ module Krane
|
|
27
28
|
|
28
29
|
selector = ::Krane::LabelSelector.parse(options[:selector])
|
29
30
|
|
30
|
-
|
31
|
+
# never mutate options directly
|
32
|
+
filenames = options[:filenames].dup
|
33
|
+
filenames << "-" if options[:stdin]
|
34
|
+
if filenames.empty?
|
35
|
+
raise Thor::RequiredArgumentMissingError, 'At least one of --filenames or --stdin must be set'
|
36
|
+
end
|
37
|
+
|
38
|
+
::Krane::OptionsHelper.with_processed_template_paths(filenames,
|
31
39
|
require_explicit_path: true) do |paths|
|
32
40
|
deploy = ::Krane::GlobalDeployTask.new(
|
33
41
|
context: context,
|
@@ -4,10 +4,11 @@ module Krane
|
|
4
4
|
module CLI
|
5
5
|
class RenderCommand
|
6
6
|
OPTIONS = {
|
7
|
-
bindings
|
8
|
-
filenames
|
9
|
-
|
10
|
-
|
7
|
+
"bindings" => { type: :array, banner: "foo=bar abc=def", desc: 'Bindings for erb' },
|
8
|
+
"filenames" => { type: :array, banner: 'config/deploy/production config/deploy/my-extra-resource.yml',
|
9
|
+
required: false, default: [], aliases: 'f', desc: 'Directories and files to render' },
|
10
|
+
"stdin" => { type: :boolean, desc: "Read resources from stdin", default: false },
|
11
|
+
"current-sha" => { type: :string, banner: "SHA", desc: "Expose SHA `current_sha` in ERB bindings" },
|
11
12
|
}
|
12
13
|
|
13
14
|
def self.from_options(options)
|
@@ -18,7 +19,14 @@ module Krane
|
|
18
19
|
bindings_parser = ::Krane::BindingsParser.new
|
19
20
|
options[:bindings]&.each { |b| bindings_parser.add(b) }
|
20
21
|
|
21
|
-
|
22
|
+
# never mutate options directly
|
23
|
+
filenames = options[:filenames].dup
|
24
|
+
filenames << "-" if options[:stdin]
|
25
|
+
if filenames.empty?
|
26
|
+
raise Thor::RequiredArgumentMissingError, 'At least one of --filenames or --stdin must be set'
|
27
|
+
end
|
28
|
+
|
29
|
+
::Krane::OptionsHelper.with_processed_template_paths(filenames) do |paths|
|
22
30
|
runner = ::Krane::RenderTask.new(
|
23
31
|
current_sha: options['current-sha'],
|
24
32
|
template_paths: paths,
|
@@ -16,41 +16,19 @@ module Krane
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def global_resource_kinds
|
20
|
-
@globals ||= fetch_resources(namespaced: false).map { |g| g["kind"] }
|
21
|
-
end
|
22
|
-
|
23
19
|
def prunable_resources(namespaced:)
|
24
|
-
black_list = %w(Namespace Node)
|
20
|
+
black_list = %w(Namespace Node ControllerRevision)
|
25
21
|
api_versions = fetch_api_versions
|
26
22
|
|
27
23
|
fetch_resources(namespaced: namespaced).map do |resource|
|
28
24
|
next unless resource['verbs'].one? { |v| v == "delete" }
|
29
25
|
next if black_list.include?(resource['kind'])
|
30
|
-
|
26
|
+
group_versions = api_versions[resource['apigroup'].to_s]
|
27
|
+
version = version_for_kind(group_versions, resource['kind'])
|
31
28
|
[resource['apigroup'], version, resource['kind']].compact.join("/")
|
32
29
|
end.compact
|
33
30
|
end
|
34
31
|
|
35
|
-
private
|
36
|
-
|
37
|
-
# kubectl api-versions returns a list of group/version strings e.g. autoscaling/v2beta2
|
38
|
-
# A kind may not exist in all versions of the group.
|
39
|
-
def fetch_api_versions
|
40
|
-
raw, _, st = kubectl.run("api-versions", attempts: 5, use_namespace: false)
|
41
|
-
# The "core" group is represented by an empty string
|
42
|
-
versions = { "" => %w(v1) }
|
43
|
-
if st.success?
|
44
|
-
rows = raw.split("\n")
|
45
|
-
rows.each do |group_version|
|
46
|
-
group, version = group_version.split("/")
|
47
|
-
versions[group] ||= []
|
48
|
-
versions[group] << version
|
49
|
-
end
|
50
|
-
end
|
51
|
-
versions
|
52
|
-
end
|
53
|
-
|
54
32
|
# kubectl api-resources -o wide returns 5 columns
|
55
33
|
# NAME SHORTNAMES APIGROUP NAMESPACED KIND VERBS
|
56
34
|
# SHORTNAMES and APIGROUP may be blank
|
@@ -85,6 +63,39 @@ module Krane
|
|
85
63
|
end
|
86
64
|
end
|
87
65
|
|
66
|
+
private
|
67
|
+
|
68
|
+
# kubectl api-versions returns a list of group/version strings e.g. autoscaling/v2beta2
|
69
|
+
# A kind may not exist in all versions of the group.
|
70
|
+
def fetch_api_versions
|
71
|
+
raw, _, st = kubectl.run("api-versions", attempts: 5, use_namespace: false)
|
72
|
+
# The "core" group is represented by an empty string
|
73
|
+
versions = { "" => %w(v1) }
|
74
|
+
if st.success?
|
75
|
+
rows = raw.split("\n")
|
76
|
+
rows.each do |group_version|
|
77
|
+
group, version = group_version.split("/")
|
78
|
+
versions[group] ||= []
|
79
|
+
versions[group] << version
|
80
|
+
end
|
81
|
+
end
|
82
|
+
versions
|
83
|
+
end
|
84
|
+
|
85
|
+
def version_for_kind(versions, kind)
|
86
|
+
# Override list for kinds that don't appear in the lastest version of a group
|
87
|
+
version_override = { "CronJob" => "v1beta1", "VolumeAttachment" => "v1beta1",
|
88
|
+
"CSIDriver" => "v1beta1", "Ingress" => "v1beta1", "CSINode" => "v1beta1" }
|
89
|
+
|
90
|
+
pattern = /v(?<major>\d+)(?<pre>alpha|beta)?(?<minor>\d+)?/
|
91
|
+
latest = versions.sort_by do |version|
|
92
|
+
match = version.match(pattern)
|
93
|
+
pre = { "alpha" => 0, "beta" => 1, nil => 2 }.fetch(match[:pre])
|
94
|
+
[match[:major].to_i, pre, match[:minor].to_i]
|
95
|
+
end.last
|
96
|
+
version_override.fetch(kind, latest)
|
97
|
+
end
|
98
|
+
|
88
99
|
def fetch_crds
|
89
100
|
raw_json, _, st = kubectl.run("get", "CustomResourceDefinition", output: "json", attempts: 5,
|
90
101
|
use_namespace: false)
|
data/lib/krane/deploy_task.rb
CHANGED
@@ -8,5 +8,9 @@ module Krane
|
|
8
8
|
raise "Use Krane::DeployGlobalTask to deploy global resources" if args[:allow_globals]
|
9
9
|
super(args.merge(allow_globals: false))
|
10
10
|
end
|
11
|
+
|
12
|
+
def prune_whitelist
|
13
|
+
cluster_resource_discoverer.prunable_resources(namespaced: true)
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
@@ -388,7 +388,12 @@ module Krane
|
|
388
388
|
.lastTimestamp
|
389
389
|
.reason
|
390
390
|
.message
|
391
|
+
.eventTime
|
392
|
+
.deprecatedCount
|
393
|
+
.deprecatedLastTimestamp
|
394
|
+
.series
|
391
395
|
)
|
396
|
+
FIELD_EMPTY_VALUE = '<no value>'
|
392
397
|
|
393
398
|
def self.go_template_for(kind, name)
|
394
399
|
and_conditions = [
|
@@ -409,17 +414,61 @@ module Krane
|
|
409
414
|
def self.extract_all_from_go_template_blob(blob)
|
410
415
|
blob.split(EVENT_SEPARATOR).map do |event_blob|
|
411
416
|
pieces = event_blob.split(FIELD_SEPARATOR, FIELDS.length)
|
417
|
+
count = extract_event_count(pieces)
|
418
|
+
timestamp = extract_event_timestamp(pieces)
|
419
|
+
|
412
420
|
new(
|
413
421
|
subject_kind: pieces[FIELDS.index(".involvedObject.kind")],
|
414
422
|
subject_name: pieces[FIELDS.index(".involvedObject.name")],
|
415
|
-
count:
|
416
|
-
last_timestamp:
|
423
|
+
count: count,
|
424
|
+
last_timestamp: timestamp,
|
417
425
|
reason: pieces[FIELDS.index(".reason")],
|
418
426
|
message: pieces[FIELDS.index(".message")]
|
419
427
|
)
|
420
428
|
end
|
421
429
|
end
|
422
430
|
|
431
|
+
def self.extract_event_count(pieces)
|
432
|
+
series = pieces[FIELDS.index(".series")]
|
433
|
+
count = pieces[FIELDS.index(".count")]
|
434
|
+
deprecated_count = pieces[FIELDS.index(".deprecatedCount")]
|
435
|
+
|
436
|
+
# Find the right event count according to Kubernetes API and kubectl version
|
437
|
+
if count.present? && count != FIELD_EMPTY_VALUE
|
438
|
+
count # This is the default field, so let's try to use it first
|
439
|
+
elsif series.present? && series != FIELD_EMPTY_VALUE
|
440
|
+
# kubectl 1.16 uses Events/v1, which has the .series/.count field
|
441
|
+
count_regex = /count:(?<value>\S+?(?=\s))/
|
442
|
+
count_regex.match(series)['value']
|
443
|
+
elsif deprecated_count.present? && deprecated_count != FIELD_EMPTY_VALUE
|
444
|
+
# kubectl < 1.16 uses events.k8s.io/v1beta1, which has .deprecatedCount
|
445
|
+
deprecated_count
|
446
|
+
else
|
447
|
+
"1" # Fallback to 1 when all count fields are null
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
def self.extract_event_timestamp(pieces)
|
452
|
+
series = pieces[FIELDS.index(".series")]
|
453
|
+
last_timestamp = pieces[FIELDS.index(".lastTimestamp")]
|
454
|
+
deprecated_timestamp = pieces[FIELDS.index(".deprecatedLastTimestamp")]
|
455
|
+
|
456
|
+
# Find the right event timestamp according to Kubernetes API and kubectl version
|
457
|
+
if last_timestamp.present? && last_timestamp != FIELD_EMPTY_VALUE
|
458
|
+
last_timestamp # kubernetes 1.16 also exposes .last_timestamp field, so let's support it
|
459
|
+
elsif series.present? && series != FIELD_EMPTY_VALUE
|
460
|
+
# kubectl 1.16 uses Events/v1, which has the .series/.lastObservedTime field
|
461
|
+
timestamp_regex = /lastObservedTime:(?<value>\S+?(?=\]))/
|
462
|
+
timestamp_regex.match(series)['value']
|
463
|
+
elsif deprecated_timestamp.present? && deprecated_timestamp != FIELD_EMPTY_VALUE
|
464
|
+
# kubectl < 1.16 uses events.k8s.io/v1beta1, which has .deprecatedLastTimestamp
|
465
|
+
deprecated_timestamp
|
466
|
+
else
|
467
|
+
pieces[FIELDS.index(".eventTime")] # Fallback to eventTime when other timestamp fields are null
|
468
|
+
end
|
469
|
+
end
|
470
|
+
private_class_method :extract_event_timestamp, :extract_event_count
|
471
|
+
|
423
472
|
def initialize(subject_kind:, last_timestamp:, reason:, message:, count:, subject_name:)
|
424
473
|
@subject_kind = subject_kind
|
425
474
|
@subject_name = subject_name
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require
|
2
|
+
require "krane/kubernetes_resource/pod_set_base"
|
3
3
|
module Krane
|
4
4
|
class DaemonSet < PodSetBase
|
5
5
|
TIMEOUT = 5.minutes
|
@@ -78,9 +78,13 @@ module Krane
|
|
78
78
|
|
79
79
|
def parent_of_pod?(pod_data)
|
80
80
|
return false unless pod_data.dig("metadata", "ownerReferences")
|
81
|
+
|
82
|
+
template_generation = @instance_data.dig("spec", "templateGeneration") ||
|
83
|
+
@instance_data.dig("metadata", "annotations", "deprecated.daemonset.template.generation")
|
84
|
+
return false unless template_generation.present?
|
85
|
+
|
81
86
|
pod_data["metadata"]["ownerReferences"].any? { |ref| ref["uid"] == @instance_data["metadata"]["uid"] } &&
|
82
|
-
pod_data["metadata"]["labels"]["pod-template-generation"].to_i ==
|
83
|
-
@instance_data["spec"]["templateGeneration"].to_i
|
87
|
+
pod_data["metadata"]["labels"]["pod-template-generation"].to_i == template_generation.to_i
|
84
88
|
end
|
85
89
|
end
|
86
90
|
end
|
data/lib/krane/restart_task.rb
CHANGED
@@ -97,13 +97,13 @@ module Krane
|
|
97
97
|
if deployment_names.nil?
|
98
98
|
deployments = if selector.nil?
|
99
99
|
@logger.info("Configured to restart all deployments with the `#{ANNOTATION}` annotation")
|
100
|
-
|
100
|
+
apps_v1_kubeclient.get_deployments(namespace: @namespace)
|
101
101
|
else
|
102
102
|
selector_string = selector.to_s
|
103
103
|
@logger.info(
|
104
104
|
"Configured to restart all deployments with the `#{ANNOTATION}` annotation and #{selector_string} selector"
|
105
105
|
)
|
106
|
-
|
106
|
+
apps_v1_kubeclient.get_deployments(namespace: @namespace, label_selector: selector_string)
|
107
107
|
end
|
108
108
|
deployments.select! { |d| d.metadata.annotations[ANNOTATION] }
|
109
109
|
|
@@ -137,7 +137,7 @@ module Krane
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def patch_deployment_with_restart(record)
|
140
|
-
|
140
|
+
apps_v1_kubeclient.patch_deployment(
|
141
141
|
record.metadata.name,
|
142
142
|
build_patch_payload(record),
|
143
143
|
@namespace
|
@@ -159,7 +159,7 @@ module Krane
|
|
159
159
|
list.map do |name|
|
160
160
|
record = nil
|
161
161
|
begin
|
162
|
-
record =
|
162
|
+
record = apps_v1_kubeclient.get_deployment(name, @namespace)
|
163
163
|
rescue Kubeclient::ResourceNotFoundError
|
164
164
|
raise FatalRestartError, "Deployment `#{name}` not found in namespace `#{@namespace}`"
|
165
165
|
end
|
@@ -205,6 +205,10 @@ module Krane
|
|
205
205
|
end
|
206
206
|
end
|
207
207
|
|
208
|
+
def apps_v1_kubeclient
|
209
|
+
@apps_v1_kubeclient ||= kubeclient_builder.build_apps_v1_kubeclient(@context)
|
210
|
+
end
|
211
|
+
|
208
212
|
def kubeclient
|
209
213
|
@kubeclient ||= kubeclient_builder.build_v1_kubeclient(@context)
|
210
214
|
end
|
data/lib/krane/task_config.rb
CHANGED
@@ -15,7 +15,7 @@ module Krane
|
|
15
15
|
def global_kinds
|
16
16
|
@global_kinds ||= begin
|
17
17
|
cluster_resource_discoverer = ClusterResourceDiscovery.new(task_config: self)
|
18
|
-
cluster_resource_discoverer.
|
18
|
+
cluster_resource_discoverer.fetch_resources(namespaced: false).map { |g| g["kind"] }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/krane/version.rb
CHANGED
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: 1.0.0.pre.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: 2019-11-
|
12
|
+
date: 2019-11-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -259,6 +259,7 @@ files:
|
|
259
259
|
- ".rubocop.yml"
|
260
260
|
- ".shopify-build/VERSION"
|
261
261
|
- ".shopify-build/kubernetes-deploy.yml"
|
262
|
+
- 1.0-Upgrade.md
|
262
263
|
- CHANGELOG.md
|
263
264
|
- CODE_OF_CONDUCT.md
|
264
265
|
- CONTRIBUTING.md
|
@@ -377,9 +378,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
377
378
|
version: 2.4.0
|
378
379
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
379
380
|
requirements:
|
380
|
-
- - "
|
381
|
+
- - ">"
|
381
382
|
- !ruby/object:Gem::Version
|
382
|
-
version:
|
383
|
+
version: 1.3.1
|
383
384
|
requirements: []
|
384
385
|
rubygems_version: 3.0.3
|
385
386
|
signing_key:
|