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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/CHANGELOG.md +16 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/README.md +1 -0
  6. data/exe/kubernetes-deploy +22 -6
  7. data/exe/kubernetes-render +7 -6
  8. data/exe/kubernetes-restart +3 -3
  9. data/exe/kubernetes-run +1 -3
  10. data/lib/kubernetes-deploy.rb +3 -27
  11. data/lib/kubernetes-deploy/common.rb +24 -0
  12. data/lib/kubernetes-deploy/deferred_summary_logging.rb +2 -0
  13. data/lib/kubernetes-deploy/deploy_task.rb +58 -65
  14. data/lib/kubernetes-deploy/duration_parser.rb +2 -0
  15. data/lib/kubernetes-deploy/ejson_secret_provisioner.rb +7 -14
  16. data/lib/kubernetes-deploy/errors.rb +0 -8
  17. data/lib/kubernetes-deploy/formatted_logger.rb +1 -0
  18. data/lib/kubernetes-deploy/kubeclient_builder.rb +2 -2
  19. data/lib/kubernetes-deploy/kubectl.rb +1 -0
  20. data/lib/kubernetes-deploy/kubernetes_resource.rb +3 -1
  21. data/lib/kubernetes-deploy/kubernetes_resource/custom_resource_definition.rb +0 -2
  22. data/lib/kubernetes-deploy/kubernetes_resource/deployment.rb +2 -0
  23. data/lib/kubernetes-deploy/kubernetes_resource/pod_set_base.rb +2 -0
  24. data/lib/kubernetes-deploy/kubernetes_resource/replica_set.rb +1 -0
  25. data/lib/kubernetes-deploy/kubernetes_resource/service.rb +21 -8
  26. data/lib/kubernetes-deploy/options_helper.rb +25 -12
  27. data/lib/kubernetes-deploy/render_task.rb +4 -4
  28. data/lib/kubernetes-deploy/resource_watcher.rb +4 -0
  29. data/lib/kubernetes-deploy/restart_task.rb +17 -13
  30. data/lib/kubernetes-deploy/runner_task.rb +9 -5
  31. data/lib/kubernetes-deploy/task_config.rb +16 -0
  32. data/lib/kubernetes-deploy/task_config_validator.rb +96 -0
  33. data/lib/kubernetes-deploy/template_sets.rb +135 -0
  34. data/lib/kubernetes-deploy/version.rb +1 -1
  35. metadata +7 -7
  36. data/lib/kubernetes-deploy/kubernetes_resource/memcached.rb +0 -43
  37. data/lib/kubernetes-deploy/kubernetes_resource/redis.rb +0 -56
  38. 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
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module KubernetesDeploy
3
- VERSION = "0.26.7"
3
+ VERSION = "0.27.0"
4
4
  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.26.7
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-07-11 00:00:00.000000000 Z
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/template_discovery.rb
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
- rubyforge_project:
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