krane 2.1.4 → 2.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -2
- data/CHANGELOG.md +32 -0
- data/dev.yml +1 -1
- data/krane.gemspec +3 -2
- data/lib/krane/cluster_resource_discovery.rb +52 -80
- data/lib/krane/container_logs.rb +1 -1
- data/lib/krane/deploy_task.rb +17 -7
- data/lib/krane/kubectl.rb +1 -1
- data/lib/krane/kubernetes_resource.rb +6 -1
- data/lib/krane/kubernetes_resource/mutating_webhook_configuration.rb +86 -0
- data/lib/krane/version.rb +1 -1
- metadata +20 -10
- data/screenshots/deploy-demo.gif +0 -0
- data/screenshots/migrate-logs.png +0 -0
- data/screenshots/missing-secret-fail.png +0 -0
- data/screenshots/success.png +0 -0
- data/screenshots/test-output.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6126a210b181939121f8639ea63915439fb4188f0a82220b8c6db53cf7aa4980
|
4
|
+
data.tar.gz: f1808e32d27cae24775e65fa6fbb0ddb47e99b6b0ca1a62456ec721d386b94d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fe412af18f0473f2fbb25b03ec34beee430f2d9483884af66e24220b4823059caf0b9b9974ba3bbc62481fe42bea8b86eda4efb341f335e259c631f85dfdbab
|
7
|
+
data.tar.gz: 8cb300e21c0608ad62b3caa3f82fc818e6de7cb11a2c8c8c63607b1b92335f6d0c198916f2b2fabd271646958e64db78a67d3251d492607d2d4301b5b0fe3e35
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,37 @@
|
|
1
1
|
## next
|
2
2
|
|
3
|
+
## 2.1.9
|
4
|
+
|
5
|
+
*Other*
|
6
|
+
|
7
|
+
- Don't package screenshots in the built gem to reduce size [#817](https://github.com/Shopify/krane/pull/817)
|
8
|
+
|
9
|
+
## 2.1.8
|
10
|
+
|
11
|
+
*Other*
|
12
|
+
|
13
|
+
- Change `statsd-instrument` dependency constraint to `< 4` [#815](https://github.com/Shopify/krane/pull/815)
|
14
|
+
|
15
|
+
## 2.1.7
|
16
|
+
|
17
|
+
*Enhancements*
|
18
|
+
- ENV["KRANE_LOG_LINE_LIMIT"] allows the number of container logs printed for failures to be configurable from the 25 line default [#803](https://github.com/Shopify/krane/pull/803).
|
19
|
+
|
20
|
+
*Other*
|
21
|
+
- Remove the overly tight timeout on cluster resource discovery, which was causing too many timeouts in high latency environments [#813](https://github.com/Shopify/krane/pull/813)
|
22
|
+
|
23
|
+
## 2.1.6
|
24
|
+
|
25
|
+
*Enhancements*
|
26
|
+
- Remove the need for a hard coded GVK overide list via improvements to cluster discovery [#778](https://github.com/Shopify/krane/pull/778)
|
27
|
+
|
28
|
+
*Bug Fixes*
|
29
|
+
- Remove resources that are targeted by side-effect-inducing mutating admission webhooks from the serverside dry run batch [#798](https://github.com/Shopify/krane/pull/798)
|
30
|
+
|
31
|
+
## 2.1.5
|
32
|
+
|
33
|
+
- Fix bug where the wrong dry-run flag is used for kubectl if client version is below 1.18 AND server version is 1.18+ [#793](https://github.com/Shopify/krane/pull/793).
|
34
|
+
|
3
35
|
## 2.1.4
|
4
36
|
|
5
37
|
*Enhancements*
|
data/dev.yml
CHANGED
data/krane.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.license = "MIT"
|
18
18
|
|
19
19
|
spec.files = %x(git ls-files -z).split("\x0").reject do |f|
|
20
|
-
f.match(%r{^(test|spec|features)/})
|
20
|
+
f.match(%r{^(test|spec|features|screenshots)/})
|
21
21
|
end
|
22
22
|
spec.bindir = "exe"
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_dependency("googleauth", "~> 0.8")
|
32
32
|
spec.add_dependency("ejson", "~> 1.0")
|
33
33
|
spec.add_dependency("colorize", "~> 0.8")
|
34
|
-
spec.add_dependency("statsd-instrument", ['>= 2.8', "<
|
34
|
+
spec.add_dependency("statsd-instrument", ['>= 2.8', "< 4"])
|
35
35
|
spec.add_dependency("oj", "~> 3.0")
|
36
36
|
spec.add_dependency("concurrent-ruby", "~> 1.1")
|
37
37
|
spec.add_dependency("jsonpath", "~> 0.9.6")
|
@@ -57,5 +57,6 @@ Gem::Specification.new do |spec|
|
|
57
57
|
spec.add_development_dependency("ruby-prof")
|
58
58
|
spec.add_development_dependency("ruby-prof-flamegraph")
|
59
59
|
spec.add_development_dependency("rubocop", "~> 0.89.1")
|
60
|
+
spec.add_development_dependency("rubocop-shopify", "~> 1.0.5")
|
60
61
|
spec.add_development_dependency("simplecov")
|
61
62
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'concurrent'
|
2
3
|
|
3
4
|
module Krane
|
4
5
|
class ClusterResourceDiscovery
|
@@ -7,6 +8,7 @@ module Krane
|
|
7
8
|
def initialize(task_config:, namespace_tags: [])
|
8
9
|
@task_config = task_config
|
9
10
|
@namespace_tags = namespace_tags
|
11
|
+
@api_path_cache = {}
|
10
12
|
end
|
11
13
|
|
12
14
|
def crds
|
@@ -18,104 +20,74 @@ module Krane
|
|
18
20
|
|
19
21
|
def prunable_resources(namespaced:)
|
20
22
|
black_list = %w(Namespace Node ControllerRevision)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
next if black_list.include?(resource['kind'])
|
26
|
-
gvk_string(api_versions, resource)
|
23
|
+
fetch_resources(namespaced: namespaced).map do |resource|
|
24
|
+
next unless resource["verbs"].one? { |v| v == "delete" }
|
25
|
+
next if black_list.include?(resource["kind"])
|
26
|
+
[resource["apigroup"], resource["version"], resource["kind"]].compact.join("/")
|
27
27
|
end.compact
|
28
28
|
end
|
29
29
|
|
30
|
-
# kubectl api-resources -o wide returns 5 columns
|
31
|
-
# NAME SHORTNAMES APIGROUP NAMESPACED KIND VERBS
|
32
|
-
# SHORTNAMES and APIGROUP may be blank
|
33
|
-
# VERBS is an array
|
34
|
-
# serviceaccounts sa <blank> true ServiceAccount [create delete deletecollection get list patch update watch]
|
35
30
|
def fetch_resources(namespaced: false)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
use_namespace: false)
|
40
|
-
if st.success?
|
41
|
-
rows = raw.split("\n")
|
42
|
-
header = rows[0]
|
43
|
-
resources = rows[1..-1]
|
44
|
-
full_width_field_names = header.downcase.scan(/[a-z]+[\W]*/)
|
45
|
-
cursor = 0
|
46
|
-
fields = full_width_field_names.each_with_object({}) do |name, hash|
|
47
|
-
start = cursor
|
48
|
-
cursor = start + name.length
|
49
|
-
# Last field should consume the remainder of the line
|
50
|
-
cursor = 0 if full_width_field_names.last == name.strip
|
51
|
-
hash[name.strip] = [start, cursor - 1]
|
52
|
-
end
|
53
|
-
resources.map do |resource|
|
54
|
-
resource = fields.map { |k, (s, e)| [k.strip, resource[s..e].strip] }.to_h
|
55
|
-
# Manually parse verbs: "[get list]" into %w(get list)
|
56
|
-
resource["verbs"] = resource["verbs"][1..-2].split
|
57
|
-
resource
|
58
|
-
end
|
59
|
-
else
|
60
|
-
raise FatalKubeAPIError, "Error retrieving api-resources: #{err}"
|
31
|
+
responses = Concurrent::Hash.new
|
32
|
+
Krane::Concurrency.split_across_threads(api_paths) do |path|
|
33
|
+
responses[path] = fetch_api_path(path)["resources"] || []
|
61
34
|
end
|
35
|
+
responses.flat_map do |path, resources|
|
36
|
+
resources.map { |r| resource_hash(path, namespaced, r) }
|
37
|
+
end.compact.uniq { |r| r["kind"] }
|
62
38
|
end
|
63
39
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
# A kind may not exist in all versions of the group.
|
68
|
-
def fetch_api_versions
|
69
|
-
raw, err, st = kubectl.run("api-versions", attempts: 5, use_namespace: false)
|
70
|
-
# The "core" group is represented by an empty string
|
71
|
-
versions = { "" => %w(v1) }
|
40
|
+
def fetch_mutating_webhook_configurations
|
41
|
+
command = %w(get mutatingwebhookconfigurations)
|
42
|
+
raw_json, err, st = kubectl.run(*command, output: "json", attempts: 5, use_namespace: false)
|
72
43
|
if st.success?
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
versions[group] ||= []
|
77
|
-
versions[group] << version
|
44
|
+
JSON.parse(raw_json)["items"].map do |definition|
|
45
|
+
Krane::MutatingWebhookConfiguration.new(namespace: namespace, context: context, logger: logger,
|
46
|
+
definition: definition, statsd_tags: @namespace_tags)
|
78
47
|
end
|
79
48
|
else
|
80
|
-
raise FatalKubeAPIError, "Error retrieving
|
49
|
+
raise FatalKubeAPIError, "Error retrieving mutatingwebhookconfigurations: #{err}"
|
81
50
|
end
|
82
|
-
versions
|
83
51
|
end
|
84
52
|
|
85
|
-
|
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",
|
89
|
-
"CSINode" => "v1beta1", "Job" => "v1",
|
90
|
-
"IngressClass" => "v1beta1", "FrontendConfig" => "v1beta1",
|
91
|
-
"ServiceNetworkEndpointGroup" => "v1beta1",
|
92
|
-
"EnvoyFilter" => "v1alpha3",
|
93
|
-
"TCPIngress" => "v1beta1" }
|
53
|
+
private
|
94
54
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
55
|
+
def api_paths
|
56
|
+
@api_path_cache["/"] ||= begin
|
57
|
+
raw_json, err, st = kubectl.run("get", "--raw", "/", attempts: 5, use_namespace: false)
|
58
|
+
paths = if st.success?
|
59
|
+
JSON.parse(raw_json)["paths"]
|
60
|
+
else
|
61
|
+
raise FatalKubeAPIError, "Error retrieving raw path /: #{err}"
|
62
|
+
end
|
63
|
+
paths.select { |path| %r{^\/api.*\/v.*$}.match(path) }
|
64
|
+
end
|
102
65
|
end
|
103
66
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
apigroup = 'core' if apigroup.empty?
|
114
|
-
apiversion = "#{apigroup}/#{version}"
|
67
|
+
def fetch_api_path(path)
|
68
|
+
@api_path_cache[path] ||= begin
|
69
|
+
raw_json, err, st = kubectl.run("get", "--raw", path, attempts: 2, use_namespace: false)
|
70
|
+
if st.success?
|
71
|
+
JSON.parse(raw_json)
|
72
|
+
else
|
73
|
+
logger.warn("Error retrieving api path: #{err}")
|
74
|
+
{}
|
75
|
+
end
|
115
76
|
end
|
77
|
+
end
|
116
78
|
|
117
|
-
|
118
|
-
|
79
|
+
def resource_hash(path, namespaced, blob)
|
80
|
+
return unless blob["namespaced"] == namespaced
|
81
|
+
# skip sub-resources
|
82
|
+
return if blob["name"].include?("/")
|
83
|
+
path_regex = %r{(/apis?/)(?<group>[^/]*)/?(?<version>v.+)}
|
84
|
+
match = path.match(path_regex)
|
85
|
+
{
|
86
|
+
"verbs" => blob["verbs"],
|
87
|
+
"kind" => blob["kind"],
|
88
|
+
"apigroup" => match[:group],
|
89
|
+
"version" => match[:version],
|
90
|
+
}
|
119
91
|
end
|
120
92
|
|
121
93
|
def fetch_crds
|
data/lib/krane/container_logs.rb
CHANGED
@@ -3,7 +3,7 @@ module Krane
|
|
3
3
|
class ContainerLogs
|
4
4
|
attr_reader :lines, :container_name
|
5
5
|
|
6
|
-
DEFAULT_LINE_LIMIT = 25
|
6
|
+
DEFAULT_LINE_LIMIT = Integer(ENV.fetch('KRANE_LOG_LINE_LIMIT', 25))
|
7
7
|
|
8
8
|
def initialize(parent_id:, container_name:, namespace:, context:, logger:)
|
9
9
|
@parent_id = parent_id
|
data/lib/krane/deploy_task.rb
CHANGED
@@ -30,6 +30,7 @@ require 'krane/kubernetes_resource'
|
|
30
30
|
custom_resource_definition
|
31
31
|
horizontal_pod_autoscaler
|
32
32
|
secret
|
33
|
+
mutating_webhook_configuration
|
33
34
|
).each do |subresource|
|
34
35
|
require "krane/kubernetes_resource/#{subresource}"
|
35
36
|
end
|
@@ -277,16 +278,25 @@ module Krane
|
|
277
278
|
end
|
278
279
|
measure_method(:validate_configuration)
|
279
280
|
|
281
|
+
def partition_dry_run_resources(resources)
|
282
|
+
individuals = []
|
283
|
+
mutating_webhook_configurations = cluster_resource_discoverer.fetch_mutating_webhook_configurations
|
284
|
+
mutating_webhook_configurations.each do |mutating_webhook_configuration|
|
285
|
+
mutating_webhook_configuration.webhooks.each do |webhook|
|
286
|
+
individuals = (individuals + resources.select { |resource| webhook.matches_resource?(resource) }).uniq
|
287
|
+
resources -= individuals
|
288
|
+
end
|
289
|
+
end
|
290
|
+
[resources, individuals]
|
291
|
+
end
|
292
|
+
|
280
293
|
def validate_resources(resources)
|
281
294
|
validate_globals(resources)
|
282
|
-
|
295
|
+
batchable_resources, individuals = partition_dry_run_resources(resources.dup)
|
296
|
+
batch_dry_run_success = kubectl.server_dry_run_enabled? && validate_dry_run(batchable_resources)
|
297
|
+
individuals += batchable_resources unless batch_dry_run_success
|
283
298
|
Krane::Concurrency.split_across_threads(resources) do |r|
|
284
|
-
|
285
|
-
if batch_dry_run_success
|
286
|
-
r.validate_definition(kubectl: nil, selector: @selector, dry_run: false)
|
287
|
-
else
|
288
|
-
r.validate_definition(kubectl: kubectl, selector: @selector, dry_run: true)
|
289
|
-
end
|
299
|
+
r.validate_definition(kubectl: kubectl, selector: @selector, dry_run: individuals.include?(r))
|
290
300
|
end
|
291
301
|
failed_resources = resources.select(&:validation_failed?)
|
292
302
|
if failed_resources.present?
|
data/lib/krane/kubectl.rb
CHANGED
@@ -226,6 +226,11 @@ module Krane
|
|
226
226
|
version ? grouping : "core"
|
227
227
|
end
|
228
228
|
|
229
|
+
def version
|
230
|
+
prefix, version = @definition.dig("apiVersion").split("/")
|
231
|
+
version || prefix
|
232
|
+
end
|
233
|
+
|
229
234
|
def kubectl_resource_type
|
230
235
|
type
|
231
236
|
end
|
@@ -560,7 +565,7 @@ module Krane
|
|
560
565
|
|
561
566
|
# Server side dry run is only supported on apply
|
562
567
|
def validate_with_server_side_dry_run(kubectl)
|
563
|
-
command = if kubectl.
|
568
|
+
command = if kubectl.client_version >= Gem::Version.new('1.18')
|
564
569
|
["apply", "-f", file_path, "--dry-run=server", "--output=name"]
|
565
570
|
else
|
566
571
|
["apply", "-f", file_path, "--server-dry-run", "--output=name"]
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Krane
|
4
|
+
class MutatingWebhookConfiguration < KubernetesResource
|
5
|
+
GLOBAL = true
|
6
|
+
|
7
|
+
class Webhook
|
8
|
+
EQUIVALENT = 'Equivalent'
|
9
|
+
EXACT = 'Exact'
|
10
|
+
|
11
|
+
class Rule
|
12
|
+
def initialize(definition)
|
13
|
+
@definition = definition
|
14
|
+
end
|
15
|
+
|
16
|
+
def matches_resource?(resource, accept_equivalent:)
|
17
|
+
groups.each do |group|
|
18
|
+
versions.each do |version|
|
19
|
+
resources.each do |kind|
|
20
|
+
return true if (resource.group == group || group == '*' || accept_equivalent) &&
|
21
|
+
(resource.version == version || version == '*' || accept_equivalent) &&
|
22
|
+
(resource.type.downcase == kind.downcase.singularize || kind == "*")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def groups
|
30
|
+
@definition.dig('apiGroups')
|
31
|
+
end
|
32
|
+
|
33
|
+
def versions
|
34
|
+
@definition.dig('apiVersions')
|
35
|
+
end
|
36
|
+
|
37
|
+
def resources
|
38
|
+
@definition.dig('resources')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(definition)
|
43
|
+
@definition = definition
|
44
|
+
end
|
45
|
+
|
46
|
+
def side_effects
|
47
|
+
@definition.dig('sideEffects')
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_side_effects?
|
51
|
+
!%w(None NoneOnDryRun).include?(side_effects)
|
52
|
+
end
|
53
|
+
|
54
|
+
def match_policy
|
55
|
+
@definition.dig('matchPolicy')
|
56
|
+
end
|
57
|
+
|
58
|
+
def matches_resource?(resource, skip_rule_if_side_effect_none: true)
|
59
|
+
return false if skip_rule_if_side_effect_none && !has_side_effects?
|
60
|
+
rules.any? do |rule|
|
61
|
+
rule.matches_resource?(resource, accept_equivalent: match_policy == EQUIVALENT)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def rules
|
66
|
+
@definition.fetch('rules', []).map { |rule| Rule.new(rule) }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize(namespace:, context:, definition:, logger:, statsd_tags:)
|
71
|
+
@webhooks = (definition.dig('webhooks') || []).map { |hook| Webhook.new(hook) }
|
72
|
+
super(namespace: namespace, context: context, definition: definition,
|
73
|
+
logger: logger, statsd_tags: statsd_tags)
|
74
|
+
end
|
75
|
+
|
76
|
+
TIMEOUT = 30.seconds
|
77
|
+
|
78
|
+
def deploy_succeeded?
|
79
|
+
exists?
|
80
|
+
end
|
81
|
+
|
82
|
+
def webhooks
|
83
|
+
@definition.fetch('webhooks', []).map { |webhook| Webhook.new(webhook) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/krane/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: krane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Verey
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-05-28 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -91,7 +91,7 @@ dependencies:
|
|
91
91
|
version: '2.8'
|
92
92
|
- - "<"
|
93
93
|
- !ruby/object:Gem::Version
|
94
|
-
version: '
|
94
|
+
version: '4'
|
95
95
|
type: :runtime
|
96
96
|
prerelease: false
|
97
97
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -101,7 +101,7 @@ dependencies:
|
|
101
101
|
version: '2.8'
|
102
102
|
- - "<"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '
|
104
|
+
version: '4'
|
105
105
|
- !ruby/object:Gem::Dependency
|
106
106
|
name: oj
|
107
107
|
requirement: !ruby/object:Gem::Requirement
|
@@ -374,6 +374,20 @@ dependencies:
|
|
374
374
|
- - "~>"
|
375
375
|
- !ruby/object:Gem::Version
|
376
376
|
version: 0.89.1
|
377
|
+
- !ruby/object:Gem::Dependency
|
378
|
+
name: rubocop-shopify
|
379
|
+
requirement: !ruby/object:Gem::Requirement
|
380
|
+
requirements:
|
381
|
+
- - "~>"
|
382
|
+
- !ruby/object:Gem::Version
|
383
|
+
version: 1.0.5
|
384
|
+
type: :development
|
385
|
+
prerelease: false
|
386
|
+
version_requirements: !ruby/object:Gem::Requirement
|
387
|
+
requirements:
|
388
|
+
- - "~>"
|
389
|
+
- !ruby/object:Gem::Version
|
390
|
+
version: 1.0.5
|
377
391
|
- !ruby/object:Gem::Dependency
|
378
392
|
name: simplecov
|
379
393
|
requirement: !ruby/object:Gem::Requirement
|
@@ -460,6 +474,7 @@ files:
|
|
460
474
|
- lib/krane/kubernetes_resource/horizontal_pod_autoscaler.rb
|
461
475
|
- lib/krane/kubernetes_resource/ingress.rb
|
462
476
|
- lib/krane/kubernetes_resource/job.rb
|
477
|
+
- lib/krane/kubernetes_resource/mutating_webhook_configuration.rb
|
463
478
|
- lib/krane/kubernetes_resource/network_policy.rb
|
464
479
|
- lib/krane/kubernetes_resource/persistent_volume_claim.rb
|
465
480
|
- lib/krane/kubernetes_resource/pod.rb
|
@@ -493,11 +508,6 @@ files:
|
|
493
508
|
- lib/krane/task_config_validator.rb
|
494
509
|
- lib/krane/template_sets.rb
|
495
510
|
- lib/krane/version.rb
|
496
|
-
- screenshots/deploy-demo.gif
|
497
|
-
- screenshots/migrate-logs.png
|
498
|
-
- screenshots/missing-secret-fail.png
|
499
|
-
- screenshots/success.png
|
500
|
-
- screenshots/test-output.png
|
501
511
|
homepage: https://github.com/Shopify/krane
|
502
512
|
licenses:
|
503
513
|
- MIT
|
@@ -518,7 +528,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
518
528
|
- !ruby/object:Gem::Version
|
519
529
|
version: '0'
|
520
530
|
requirements: []
|
521
|
-
rubygems_version: 3.
|
531
|
+
rubygems_version: 3.2.17
|
522
532
|
signing_key:
|
523
533
|
specification_version: 4
|
524
534
|
summary: A command line tool that helps you ship changes to a Kubernetes namespace
|
data/screenshots/deploy-demo.gif
DELETED
Binary file
|
Binary file
|
Binary file
|
data/screenshots/success.png
DELETED
Binary file
|
data/screenshots/test-output.png
DELETED
Binary file
|