kubernetes-deploy 0.26.7 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
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