kubernetes-deploy 0.26.7 → 0.27.0
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 +4 -0
- data/CHANGELOG.md +16 -0
- data/CONTRIBUTING.md +1 -1
- data/README.md +1 -0
- data/exe/kubernetes-deploy +22 -6
- data/exe/kubernetes-render +7 -6
- data/exe/kubernetes-restart +3 -3
- data/exe/kubernetes-run +1 -3
- data/lib/kubernetes-deploy.rb +3 -27
- data/lib/kubernetes-deploy/common.rb +24 -0
- data/lib/kubernetes-deploy/deferred_summary_logging.rb +2 -0
- data/lib/kubernetes-deploy/deploy_task.rb +58 -65
- data/lib/kubernetes-deploy/duration_parser.rb +2 -0
- data/lib/kubernetes-deploy/ejson_secret_provisioner.rb +7 -14
- data/lib/kubernetes-deploy/errors.rb +0 -8
- data/lib/kubernetes-deploy/formatted_logger.rb +1 -0
- data/lib/kubernetes-deploy/kubeclient_builder.rb +2 -2
- data/lib/kubernetes-deploy/kubectl.rb +1 -0
- data/lib/kubernetes-deploy/kubernetes_resource.rb +3 -1
- data/lib/kubernetes-deploy/kubernetes_resource/custom_resource_definition.rb +0 -2
- data/lib/kubernetes-deploy/kubernetes_resource/deployment.rb +2 -0
- data/lib/kubernetes-deploy/kubernetes_resource/pod_set_base.rb +2 -0
- data/lib/kubernetes-deploy/kubernetes_resource/replica_set.rb +1 -0
- data/lib/kubernetes-deploy/kubernetes_resource/service.rb +21 -8
- data/lib/kubernetes-deploy/options_helper.rb +25 -12
- data/lib/kubernetes-deploy/render_task.rb +4 -4
- data/lib/kubernetes-deploy/resource_watcher.rb +4 -0
- data/lib/kubernetes-deploy/restart_task.rb +17 -13
- data/lib/kubernetes-deploy/runner_task.rb +9 -5
- data/lib/kubernetes-deploy/task_config.rb +16 -0
- data/lib/kubernetes-deploy/task_config_validator.rb +96 -0
- data/lib/kubernetes-deploy/template_sets.rb +135 -0
- data/lib/kubernetes-deploy/version.rb +1 -1
- metadata +7 -7
- data/lib/kubernetes-deploy/kubernetes_resource/memcached.rb +0 -43
- data/lib/kubernetes-deploy/kubernetes_resource/redis.rb +0 -56
- data/lib/kubernetes-deploy/template_discovery.rb +0 -15
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KubernetesDeploy
|
4
|
+
class TemplateSets
|
5
|
+
VALID_TEMPLATES = %w(.yml.erb .yml .yaml .yaml.erb)
|
6
|
+
# private inner class
|
7
|
+
class TemplateSet
|
8
|
+
def initialize(template_dir:, file_whitelist: [], logger:)
|
9
|
+
@template_dir = template_dir
|
10
|
+
@files = file_whitelist
|
11
|
+
@logger = logger
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_resource_definitions(render_erb: false, current_sha: nil, bindings: nil)
|
15
|
+
if render_erb
|
16
|
+
@renderer = Renderer.new(
|
17
|
+
template_dir: @template_dir,
|
18
|
+
logger: @logger,
|
19
|
+
current_sha: current_sha,
|
20
|
+
bindings: bindings,
|
21
|
+
)
|
22
|
+
end
|
23
|
+
@files.each do |filename|
|
24
|
+
next if filename.end_with?(EjsonSecretProvisioner::EJSON_SECRETS_FILE)
|
25
|
+
templates(filename: filename) do |r_def|
|
26
|
+
yield r_def
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def ejson_secrets_file
|
32
|
+
@ejson_secrets_file ||= begin
|
33
|
+
secret_file = @files.find { |f| f == EjsonSecretProvisioner::EJSON_SECRETS_FILE }
|
34
|
+
File.join(@template_dir, secret_file) if secret_file
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate
|
39
|
+
errors = []
|
40
|
+
if Dir.entries(@template_dir).none? do |filename|
|
41
|
+
filename.end_with?(*TemplateSets::VALID_TEMPLATES) ||
|
42
|
+
filename.end_with?(EjsonSecretProvisioner::EJSON_SECRETS_FILE)
|
43
|
+
end
|
44
|
+
return errors << "Template directory #{@template_dir} does not contain any valid templates"
|
45
|
+
end
|
46
|
+
|
47
|
+
@files.each do |filename|
|
48
|
+
filename = File.join(@template_dir, filename)
|
49
|
+
if !File.exist?(filename)
|
50
|
+
errors << "File #{filename} does not exist"
|
51
|
+
elsif !filename.end_with?(*TemplateSets::VALID_TEMPLATES) &&
|
52
|
+
!filename.end_with?(EjsonSecretProvisioner::EJSON_SECRETS_FILE)
|
53
|
+
errors << "File #{filename} does not have valid suffix (supported suffixes: " \
|
54
|
+
"#{TemplateSets::VALID_TEMPLATES.join(', ')}, or #{EjsonSecretProvisioner::EJSON_SECRETS_FILE})"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
errors
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def templates(filename:)
|
63
|
+
file_content = File.read(File.join(@template_dir, filename))
|
64
|
+
rendered_content = @renderer ? @renderer.render_template(filename, file_content) : file_content
|
65
|
+
YAML.load_stream(rendered_content, "<rendered> #{filename}") do |doc|
|
66
|
+
next if doc.blank?
|
67
|
+
unless doc.is_a?(Hash)
|
68
|
+
raise InvalidTemplateError.new("Template is not a valid Kubernetes manifest",
|
69
|
+
filename: filename, content: doc)
|
70
|
+
end
|
71
|
+
yield doc
|
72
|
+
end
|
73
|
+
rescue InvalidTemplateError => err
|
74
|
+
err.filename ||= filename
|
75
|
+
raise err
|
76
|
+
rescue Psych::SyntaxError => err
|
77
|
+
raise InvalidTemplateError.new(err.message, filename: filename, content: rendered_content)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
private_constant :TemplateSet
|
81
|
+
|
82
|
+
class << self
|
83
|
+
def from_dirs_and_files(paths:, logger:)
|
84
|
+
resource_templates = {}
|
85
|
+
dir_paths, file_paths = paths.partition { |path| File.directory?(path) }
|
86
|
+
|
87
|
+
# Directory paths
|
88
|
+
dir_paths.each do |template_dir|
|
89
|
+
resource_templates[template_dir] = Dir.foreach(template_dir).select do |filename|
|
90
|
+
filename.end_with?(*VALID_TEMPLATES) || filename == EjsonSecretProvisioner::EJSON_SECRETS_FILE
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Filename paths
|
95
|
+
file_paths.each do |filename|
|
96
|
+
dir_name = File.dirname(filename)
|
97
|
+
resource_templates[dir_name] ||= []
|
98
|
+
resource_templates[dir_name] << File.basename(filename) unless resource_templates[dir_name].include?(filename)
|
99
|
+
end
|
100
|
+
|
101
|
+
template_sets = []
|
102
|
+
resource_templates.each do |template_dir, files|
|
103
|
+
template_sets << TemplateSet.new(template_dir: template_dir, file_whitelist: files, logger: logger)
|
104
|
+
end
|
105
|
+
TemplateSets.new(template_sets: template_sets)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def with_resource_definitions(render_erb: false, current_sha: nil, bindings: nil)
|
110
|
+
@template_sets.each do |template_set|
|
111
|
+
template_set.with_resource_definitions(
|
112
|
+
render_erb: render_erb,
|
113
|
+
current_sha: current_sha,
|
114
|
+
bindings: bindings
|
115
|
+
) do |r_def|
|
116
|
+
yield r_def
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def ejson_secrets_files
|
122
|
+
@template_sets.map(&:ejson_secrets_file).compact
|
123
|
+
end
|
124
|
+
|
125
|
+
def validate
|
126
|
+
@template_sets.flat_map(&:validate)
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def initialize(template_sets: [])
|
132
|
+
@template_sets = template_sets
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kubernetes-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.27.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katrina Verey
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-09-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -266,6 +266,7 @@ files:
|
|
266
266
|
- lib/kubernetes-deploy.rb
|
267
267
|
- lib/kubernetes-deploy/bindings_parser.rb
|
268
268
|
- lib/kubernetes-deploy/cluster_resource_discovery.rb
|
269
|
+
- lib/kubernetes-deploy/common.rb
|
269
270
|
- lib/kubernetes-deploy/concurrency.rb
|
270
271
|
- lib/kubernetes-deploy/container_logs.rb
|
271
272
|
- lib/kubernetes-deploy/deferred_summary_logging.rb
|
@@ -288,14 +289,12 @@ files:
|
|
288
289
|
- lib/kubernetes-deploy/kubernetes_resource/horizontal_pod_autoscaler.rb
|
289
290
|
- lib/kubernetes-deploy/kubernetes_resource/ingress.rb
|
290
291
|
- lib/kubernetes-deploy/kubernetes_resource/job.rb
|
291
|
-
- lib/kubernetes-deploy/kubernetes_resource/memcached.rb
|
292
292
|
- lib/kubernetes-deploy/kubernetes_resource/network_policy.rb
|
293
293
|
- lib/kubernetes-deploy/kubernetes_resource/persistent_volume_claim.rb
|
294
294
|
- lib/kubernetes-deploy/kubernetes_resource/pod.rb
|
295
295
|
- lib/kubernetes-deploy/kubernetes_resource/pod_disruption_budget.rb
|
296
296
|
- lib/kubernetes-deploy/kubernetes_resource/pod_set_base.rb
|
297
297
|
- lib/kubernetes-deploy/kubernetes_resource/pod_template.rb
|
298
|
-
- lib/kubernetes-deploy/kubernetes_resource/redis.rb
|
299
298
|
- lib/kubernetes-deploy/kubernetes_resource/replica_set.rb
|
300
299
|
- lib/kubernetes-deploy/kubernetes_resource/resource_quota.rb
|
301
300
|
- lib/kubernetes-deploy/kubernetes_resource/role.rb
|
@@ -318,7 +317,9 @@ files:
|
|
318
317
|
- lib/kubernetes-deploy/rollout_conditions.rb
|
319
318
|
- lib/kubernetes-deploy/runner_task.rb
|
320
319
|
- lib/kubernetes-deploy/statsd.rb
|
321
|
-
- lib/kubernetes-deploy/
|
320
|
+
- lib/kubernetes-deploy/task_config.rb
|
321
|
+
- lib/kubernetes-deploy/task_config_validator.rb
|
322
|
+
- lib/kubernetes-deploy/template_sets.rb
|
322
323
|
- lib/kubernetes-deploy/version.rb
|
323
324
|
- pull_request_template.md
|
324
325
|
- screenshots/deploy-demo.gif
|
@@ -346,8 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
346
347
|
- !ruby/object:Gem::Version
|
347
348
|
version: '0'
|
348
349
|
requirements: []
|
349
|
-
|
350
|
-
rubygems_version: 2.7.6
|
350
|
+
rubygems_version: 3.0.3
|
351
351
|
signing_key:
|
352
352
|
specification_version: 4
|
353
353
|
summary: Kubernetes deploy scripts
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module KubernetesDeploy
|
3
|
-
class Memcached < KubernetesResource
|
4
|
-
TIMEOUT = 5.minutes
|
5
|
-
CONFIGMAP_NAME = "memcached-url"
|
6
|
-
|
7
|
-
def sync(cache)
|
8
|
-
super
|
9
|
-
@deployment = cache.get_instance(Deployment.kind, "memcached-#{@name}")
|
10
|
-
@service = cache.get_instance(Service.kind, "memcached-#{@name}")
|
11
|
-
@configmap = cache.get_instance(ConfigMap.kind, CONFIGMAP_NAME)
|
12
|
-
end
|
13
|
-
|
14
|
-
def status
|
15
|
-
deploy_succeeded? ? "Provisioned" : "Unknown"
|
16
|
-
end
|
17
|
-
|
18
|
-
def deploy_succeeded?
|
19
|
-
deployment_ready? && service_ready? && configmap_ready?
|
20
|
-
end
|
21
|
-
|
22
|
-
def deploy_failed?
|
23
|
-
false
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def deployment_ready?
|
29
|
-
return false unless (status = @deployment["status"])
|
30
|
-
status.fetch("availableReplicas", -1) == status.fetch("replicas", 0)
|
31
|
-
end
|
32
|
-
|
33
|
-
def service_ready?
|
34
|
-
return false unless @service.present?
|
35
|
-
@service.dig("spec", "clusterIP").present?
|
36
|
-
end
|
37
|
-
|
38
|
-
def configmap_ready?
|
39
|
-
return false unless @configmap.present?
|
40
|
-
@configmap.dig("data", @name).present?
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module KubernetesDeploy
|
3
|
-
class Redis < KubernetesResource
|
4
|
-
TIMEOUT = 5.minutes
|
5
|
-
UUID_ANNOTATION = "redis.stable.shopify.io/owner_uid"
|
6
|
-
|
7
|
-
def sync(cache)
|
8
|
-
super
|
9
|
-
|
10
|
-
@deployment = cache.get_instance(Deployment.kind, name)
|
11
|
-
@deployment = cache.get_instance(Deployment.kind, deprecated_name) if @deployment.empty?
|
12
|
-
|
13
|
-
@service = cache.get_instance(Service.kind, name)
|
14
|
-
@service = cache.get_instance(Service.kind, deprecated_name) if @service.empty?
|
15
|
-
end
|
16
|
-
|
17
|
-
def status
|
18
|
-
deploy_succeeded? ? "Provisioned" : "Unknown"
|
19
|
-
end
|
20
|
-
|
21
|
-
def deploy_succeeded?
|
22
|
-
deployment_ready? && service_ready?
|
23
|
-
end
|
24
|
-
|
25
|
-
def deploy_failed?
|
26
|
-
false
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def deployment_ready?
|
32
|
-
return false unless (status = @deployment["status"])
|
33
|
-
# all redis pods are running
|
34
|
-
status.fetch("availableReplicas", -1) == status.fetch("replicas", 0)
|
35
|
-
end
|
36
|
-
|
37
|
-
def service_ready?
|
38
|
-
return false unless @service.present?
|
39
|
-
# the service has an assigned cluster IP and is therefore functioning
|
40
|
-
@service.dig("spec", "clusterIP").present?
|
41
|
-
end
|
42
|
-
|
43
|
-
def name
|
44
|
-
@definition.dig('metadata', 'name')
|
45
|
-
end
|
46
|
-
|
47
|
-
def deprecated_name
|
48
|
-
"redis-#{redis_resource_uuid}"
|
49
|
-
end
|
50
|
-
|
51
|
-
def redis_resource_uuid
|
52
|
-
return unless @instance_data.present?
|
53
|
-
@instance_data.dig("metadata", "uid")
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module KubernetesDeploy
|
4
|
-
class TemplateDiscovery
|
5
|
-
def initialize(template_dir)
|
6
|
-
@template_dir = template_dir
|
7
|
-
end
|
8
|
-
|
9
|
-
def templates
|
10
|
-
Dir.foreach(@template_dir).select do |filename|
|
11
|
-
filename.end_with?(".yml.erb", ".yml", ".yaml", ".yaml.erb")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|