krane 2.1.4 → 2.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
|