kubes 0.5.1 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.gcloudignore +22 -0
  3. data/.gitignore +1 -1
  4. data/CHANGELOG.md +22 -0
  5. data/Dockerfile +6 -6
  6. data/Dockerfile.alpine +20 -0
  7. data/README.md +53 -7
  8. data/docker/install/docker.sh +8 -0
  9. data/docker/install/gcloud.sh +18 -0
  10. data/docker/install/kubectl.sh +4 -0
  11. data/docs/_docs/config/hooks/kubes.md +1 -0
  12. data/docs/_docs/config/reference.md +1 -0
  13. data/docs/_docs/dsl/multiple-resources.md +3 -1
  14. data/docs/_docs/dsl/resources/secret.md +19 -2
  15. data/docs/_docs/generators.md +4 -4
  16. data/docs/_docs/helpers.md +4 -2
  17. data/docs/_docs/helpers/aws/advanced.md +10 -0
  18. data/docs/_docs/helpers/aws/advanced/secrets.md +131 -0
  19. data/docs/_docs/helpers/aws/advanced/ssm.md +78 -0
  20. data/docs/_docs/helpers/aws/secrets.md +25 -83
  21. data/docs/_docs/helpers/aws/ssm.md +20 -38
  22. data/docs/_docs/helpers/custom.md +1 -0
  23. data/docs/_docs/helpers/google/advanced.md +10 -0
  24. data/docs/_docs/helpers/google/advanced/secrets.md +78 -0
  25. data/docs/_docs/helpers/google/gke.md +92 -0
  26. data/docs/_docs/helpers/google/secrets.md +30 -27
  27. data/docs/_docs/intro.md +2 -11
  28. data/docs/_docs/layering.md +2 -0
  29. data/docs/_docs/layering/mix.md +99 -0
  30. data/docs/_docs/patterns/multiple-envs.md +55 -0
  31. data/docs/_docs/plugins.md +12 -0
  32. data/docs/_docs/plugins/aws.md +17 -0
  33. data/docs/_docs/plugins/google.md +18 -0
  34. data/docs/_docs/variables.md +12 -0
  35. data/docs/_docs/variables/advanced.md +64 -0
  36. data/docs/_docs/variables/basic.md +139 -0
  37. data/docs/_docs/vs.md +10 -0
  38. data/docs/_docs/vs/custom.md +109 -0
  39. data/docs/_docs/vs/helm.md +243 -0
  40. data/docs/_docs/vs/kustomize.md +167 -0
  41. data/docs/_includes/helpers/generator.md +13 -0
  42. data/docs/_includes/intro/features.md +11 -0
  43. data/docs/_includes/layering/layers.md +11 -15
  44. data/docs/_includes/plugins/gke-config.md +6 -0
  45. data/docs/_includes/sidebar.html +45 -0
  46. data/docs/_includes/variables/generator.md +12 -0
  47. data/docs/_includes/vs/article.md +1 -0
  48. data/docs/_includes/vs/kubes/layering.md +10 -0
  49. data/docs/_includes/vs/kubes/structure.md +24 -0
  50. data/docs/_reference/kubes-new-help.md +15 -0
  51. data/docs/_reference/kubes-new-helper.md +25 -0
  52. data/docs/_reference/kubes-new-resource.md +56 -0
  53. data/docs/_reference/kubes-new-variable.md +20 -0
  54. data/docs/_reference/kubes-new.md +6 -38
  55. data/kubes.gemspec +2 -2
  56. data/lib/kubes.rb +4 -3
  57. data/lib/kubes/auth.rb +13 -1
  58. data/lib/kubes/auth/base.rb +21 -0
  59. data/lib/kubes/auth/ecr.rb +1 -15
  60. data/lib/kubes/auth/gcr.rb +24 -0
  61. data/lib/kubes/cli/apply.rb +0 -1
  62. data/lib/kubes/cli/help/new/helper.md +4 -0
  63. data/lib/kubes/cli/help/{new.md → new/resource.md} +3 -3
  64. data/lib/kubes/cli/new.rb +12 -94
  65. data/lib/kubes/cli/new/helper.rb +24 -0
  66. data/lib/kubes/cli/new/resource.rb +97 -0
  67. data/lib/kubes/cli/new/variable.rb +16 -0
  68. data/lib/kubes/cli/prune.rb +4 -2
  69. data/lib/kubes/command.rb +1 -1
  70. data/lib/kubes/compiler/decorator/base.rb +1 -1
  71. data/lib/kubes/compiler/dsl/core/base.rb +6 -9
  72. data/lib/kubes/compiler/layering.rb +21 -7
  73. data/lib/kubes/compiler/shared/custom_variables.rb +38 -0
  74. data/lib/kubes/compiler/shared/plugin_helpers.rb +14 -0
  75. data/lib/kubes/compiler/strategy.rb +7 -6
  76. data/lib/kubes/compiler/strategy/base.rb +59 -2
  77. data/lib/kubes/compiler/strategy/dsl.rb +0 -29
  78. data/lib/kubes/compiler/strategy/erb.rb +10 -22
  79. data/lib/kubes/compiler/util/normalize.rb +6 -3
  80. data/lib/kubes/compiler/util/yaml_dump.rb +4 -4
  81. data/lib/kubes/config.rb +14 -0
  82. data/lib/kubes/hooks/builder.rb +20 -5
  83. data/lib/kubes/hooks/concern.rb +1 -1
  84. data/lib/kubes/kubectl/batch.rb +7 -0
  85. data/lib/kubes/plugin.rb +14 -0
  86. data/lib/kubes/util/sh.rb +1 -1
  87. data/lib/kubes/version.rb +1 -1
  88. data/lib/templates/new/helper/file.rb +2 -0
  89. data/lib/templates/new/{dsl → resource/dsl}/backend_config.rb +0 -0
  90. data/lib/templates/new/{dsl → resource/dsl}/config_map.rb +0 -0
  91. data/lib/templates/new/{dsl → resource/dsl}/daemon_set.rb +0 -0
  92. data/lib/templates/new/{dsl → resource/dsl}/deployment.rb +0 -0
  93. data/lib/templates/new/{dsl → resource/dsl}/ingress.rb +0 -0
  94. data/lib/templates/new/{dsl → resource/dsl}/job.rb +0 -0
  95. data/lib/templates/new/{dsl → resource/dsl}/managed_certificate.rb +0 -0
  96. data/lib/templates/new/{dsl → resource/dsl}/namespace.rb +0 -0
  97. data/lib/templates/new/{dsl → resource/dsl}/network_policy.rb +0 -0
  98. data/lib/templates/new/{dsl → resource/dsl}/pod.rb +0 -0
  99. data/lib/templates/new/{dsl → resource/dsl}/role.rb +0 -0
  100. data/lib/templates/new/{dsl → resource/dsl}/role_binding.rb +0 -0
  101. data/lib/templates/new/{dsl → resource/dsl}/secret.rb +0 -0
  102. data/lib/templates/new/{dsl → resource/dsl}/service.rb +0 -0
  103. data/lib/templates/new/{dsl → resource/dsl}/service_account.rb +0 -0
  104. data/lib/templates/new/{yaml → resource/yaml}/backend_config.yaml +0 -0
  105. data/lib/templates/new/{yaml → resource/yaml}/config_map.yaml +0 -0
  106. data/lib/templates/new/{yaml → resource/yaml}/daemon_set.yaml +0 -0
  107. data/lib/templates/new/{yaml → resource/yaml}/deployment.yaml +0 -0
  108. data/lib/templates/new/{yaml → resource/yaml}/ingress.yaml +0 -0
  109. data/lib/templates/new/{yaml → resource/yaml}/job.yaml +0 -0
  110. data/lib/templates/new/{yaml → resource/yaml}/managed_certificate.yaml +0 -0
  111. data/lib/templates/new/{yaml → resource/yaml}/namespace.yaml +0 -0
  112. data/lib/templates/new/{yaml → resource/yaml}/network_policy.yaml +0 -0
  113. data/lib/templates/new/{yaml → resource/yaml}/pod.yaml +0 -0
  114. data/lib/templates/new/{yaml → resource/yaml}/role.yaml +0 -0
  115. data/lib/templates/new/{yaml → resource/yaml}/role_binding.yaml +0 -0
  116. data/lib/templates/new/{yaml → resource/yaml}/secret.yaml +0 -0
  117. data/lib/templates/new/{yaml → resource/yaml}/service.yaml +0 -0
  118. data/lib/templates/new/{yaml → resource/yaml}/service_account.yaml +0 -0
  119. data/lib/templates/new/variable/file.rb +1 -0
  120. data/spec/fixtures/multiple-files/{deployment-1.rb → .kubes/resources/web/deployment-1.rb} +0 -0
  121. data/spec/fixtures/multiple-files/{deployment-2.rb → .kubes/resources/web/deployment-2.rb} +0 -0
  122. data/spec/fixtures/project/.kubes/resources/{deployment.rb → web/deployment.rb} +0 -0
  123. data/spec/fixtures/project/.kubes/resources/{foobar.rb → web/empty.rb} +0 -0
  124. data/spec/fixtures/project/.kubes/resources/{service.rb → web/service.rb} +1 -1
  125. data/spec/fixtures/syntax/{network_policy.rb → .kubes/resources/web/network_policy.rb} +0 -0
  126. data/spec/fixtures/syntax/{pod.rb → .kubes/resources/web/pod.rb} +0 -0
  127. data/spec/kubes/compiler/strategy/dsl_spec.rb +2 -2
  128. data/spec/kubes/compiler_spec.rb +1 -1
  129. data/spec/kubes/dsl/network_policy_spec.rb +1 -1
  130. data/spec/kubes/dsl/pod_spec.rb +1 -1
  131. metadata +101 -56
@@ -0,0 +1,38 @@
1
+ module Kubes::Compiler::Shared
2
+ module CustomVariables
3
+ include DslEvaluator
4
+
5
+ # Load custom variables from project
6
+ @@custom_variables_loaded = false
7
+ def load_custom_variables
8
+ return if Kubes.kustomize?
9
+
10
+ ext = File.extname(@path)
11
+ role = @path.sub(%r{.*\.kubes/resources/},'').sub(ext,'').split('/').first # IE: web
12
+ kind = File.basename(@path).sub(ext,'') # IE: deployment
13
+ all = "all"
14
+ if @block_form
15
+ kind = kind.pluralize
16
+ all = all.pluralize
17
+ end
18
+
19
+ layers = [
20
+ "base.rb",
21
+ "#{Kubes.env}.rb",
22
+ "base/all.rb",
23
+ "base/all/#{Kubes.env}.rb",
24
+ "base/#{kind}.rb",
25
+ "base/#{kind}/base.rb",
26
+ "base/#{kind}/#{Kubes.env}.rb",
27
+ "#{role}/#{kind}.rb",
28
+ "#{role}/#{kind}/base.rb",
29
+ "#{role}/#{kind}/#{Kubes.env}.rb",
30
+ ]
31
+
32
+ layers.each do |layer|
33
+ path = "#{Kubes.root}/.kubes/variables/#{layer}"
34
+ evaluate_file(path)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ module Kubes::Compiler::Shared
2
+ module PluginHelpers
3
+ # Load plugin helper methods from project
4
+ @@plugin_helpers_loaded = false
5
+ def load_plugin_helpers
6
+ return if @@plugin_helpers_loaded
7
+ Kubes::Plugin.plugins.each do |klass|
8
+ helpers_class = "#{klass}::Helpers".constantize # IE: KubesAws::Helpers
9
+ self.class.send :include, helpers_class
10
+ end
11
+ @@plugin_helpers_loaded = true
12
+ end
13
+ end
14
+ end
@@ -16,12 +16,13 @@ class Kubes::Compiler
16
16
  end
17
17
 
18
18
  def strategy_class
19
- ext = File.extname(@path)
20
- case ext
21
- when '.rb' then Dsl
22
- when '.yaml','.yml' then Erb
23
- else Pass
24
- end
19
+ ext = File.extname(@path).sub('.','').to_sym
20
+ map = {
21
+ rb: Dsl,
22
+ yaml: Erb,
23
+ yml: Erb,
24
+ }
25
+ map[ext]
25
26
  end
26
27
  end
27
28
  end
@@ -1,13 +1,70 @@
1
1
  class Kubes::Compiler::Strategy
2
2
  class Base
3
- include Kubes::Logging
3
+ include Kubes::Compiler::Layering
4
+ include Kubes::Compiler::Util::Normalize
4
5
  include Kubes::Compiler::Util::SaveFile
5
- include Kubes::Compiler::Shared::CustomHelpers
6
+ include Kubes::Logging
6
7
 
7
8
  def initialize(options={})
8
9
  @options = options
9
10
  @path = options[:path]
10
11
  @save_file = save_file(@path)
12
+ @data = @options[:data] || {}
13
+ end
14
+
15
+ def run
16
+ render_files(pre_layers)
17
+ render(@path) # main resource definition
18
+ render_files(post_layers)
19
+
20
+ Result.new(@save_file, @data)
21
+ end
22
+
23
+ def render_files(paths)
24
+ paths.each do |path|
25
+ next unless File.exist?(path) # layers may not exist
26
+ render(path)
27
+ end
28
+ end
29
+
30
+ # render and merge
31
+ def render(path)
32
+ result = render_strategy(path)
33
+ if result.is_a?(Kubes::Compiler::Dsl::Core::Blocks)
34
+ result = result.results
35
+ end
36
+ @data.deeper_merge!(result)
37
+ end
38
+
39
+ # Delegate to Dsl or Erb strategy again and pass @data down to allow rendering of a mix of yaml and rb files.
40
+ def render_strategy(path)
41
+ if path.include?('.rb')
42
+ dsl_class.new(@options.merge(path: path, data: @data)).run
43
+ else
44
+ Erb.new(@options.merge(data: @data)).render_result(path)
45
+ end
46
+ end
47
+
48
+ # Must be defined here in case coming from Kubes::Compiler::Strategy::Erb#render_strategy
49
+ def dsl_class
50
+ if block_form?
51
+ Kubes::Compiler::Dsl::Core::Blocks
52
+ else
53
+ syntax_class
54
+ end
55
+ end
56
+
57
+ def syntax_class
58
+ klass_name = normalize_kind(@save_file) # IE: @save_file: web/service.yaml
59
+ "Kubes::Compiler::Dsl::Syntax::#{klass_name}".constantize
60
+ rescue NameError
61
+ logger.debug "Using default resource for: #{klass_name}"
62
+ Kubes::Compiler::Dsl::Syntax::Resource # default
63
+ end
64
+
65
+ def block_form?
66
+ type = extract_type(@save_file)
67
+ type.pluralize == type
11
68
  end
12
69
  end
13
70
  end
@@ -1,33 +1,4 @@
1
1
  class Kubes::Compiler::Strategy
2
2
  class Dsl < Base
3
- include Kubes::Compiler::Util::Normalize
4
-
5
- def run
6
- load_custom_helpers
7
- dsl = dsl_class.new(@options) # Deployment, Service, etc
8
- data = dsl.run
9
- Result.new(@save_file, data)
10
- end
11
-
12
- def dsl_class
13
- if block_form?
14
- Kubes::Compiler::Dsl::Core::Blocks
15
- else
16
- syntax_class
17
- end
18
- end
19
-
20
- def syntax_class
21
- klass_name = normalize_kind(@save_file)
22
- "Kubes::Compiler::Dsl::Syntax::#{klass_name}".constantize
23
- rescue NameError
24
- logger.debug "Using default resource for: #{klass_name}"
25
- Kubes::Compiler::Dsl::Syntax::Resource # default
26
- end
27
-
28
- def block_form?
29
- type = extract_type(@save_file)
30
- type.pluralize == type
31
- end
32
3
  end
33
4
  end
@@ -4,31 +4,19 @@ class Kubes::Compiler::Strategy
4
4
  class Erb < Base
5
5
  extend Kubes::Compiler::Dsl::Core::Fields
6
6
  include Kubes::Compiler::Dsl::Core::Helpers
7
+ include Kubes::Compiler::Layering
7
8
  include Kubes::Compiler::Shared::CustomHelpers
9
+ include Kubes::Compiler::Shared::CustomVariables
8
10
  include Kubes::Compiler::Shared::Helpers
9
- include Kubes::Compiler::Layering
10
-
11
- def run
11
+ include Kubes::Compiler::Shared::PluginHelpers
12
+
13
+ def initialize(options={})
14
+ super
15
+ # For ERB scope is in this same Strategy::Erb class
16
+ # For DSL scope is within the each for the Resource classes. IE: kubes/compile/dsl/core/base.rb
17
+ load_plugin_helpers
18
+ load_custom_variables
12
19
  load_custom_helpers
13
- @data = {}
14
-
15
- render_files(pre_layers)
16
- render(@path) # main resource definition
17
- render_files(post_layers)
18
-
19
- Result.new(@save_file, @data)
20
- end
21
-
22
- def render_files(paths)
23
- paths.each do |path|
24
- render(path)
25
- end
26
- end
27
-
28
- # render and merge
29
- def render(path)
30
- result = render_result(path)
31
- @data.deeper_merge!(result)
32
20
  end
33
21
 
34
22
  def render_result(path)
@@ -1,11 +1,14 @@
1
1
  module Kubes::Compiler::Util
2
2
  module Normalize
3
3
  def normalize_kind(path)
4
- extract_type(path).underscore.camelize # Deployment, Service, Ingress, ManagedCertificate, etc
4
+ info = path.sub(%r{.*/.kubes/resources/}, '')
5
+ extract_type(info).underscore.camelize # Deployment, Service, Ingress, ManagedCertificate, etc
5
6
  end
6
7
 
7
- def extract_type(path)
8
- File.basename(path).sub('.yaml','').sub('.yml','').sub('.rb','').sub(/-.*/,'')
8
+ # info: web/service.yaml
9
+ def extract_type(info)
10
+ _, kind = info.split('/')
11
+ kind.sub('.yaml','').sub('.yml','').sub('.rb','').sub(/-.*/,'')
9
12
  end
10
13
  end
11
14
  end
@@ -4,12 +4,12 @@ require "yaml"
4
4
  module Kubes::Compiler::Util
5
5
  module YamlDump
6
6
  def yaml_dump(data)
7
- if data.is_a?(Kubes::Compiler::Dsl::Core::Blocks)
8
- items = data.results.map { |k,v| standardize_yaml(v) }
9
- items.map(&:to_yaml).join("")
10
- else
7
+ if data.key?("kind") # single resource in YAML
11
8
  data = standardize_yaml(data)
12
9
  data.to_yaml
10
+ else
11
+ items = data.map { |k,v| standardize_yaml(v) }
12
+ items.map(&:to_yaml).join("")
13
13
  end
14
14
  end
15
15
 
@@ -31,6 +31,7 @@ module Kubes
31
31
  config.kubectl.order.kinds = kind_order
32
32
 
33
33
  config.repo = nil # expected to be set by .kubes/config.rb
34
+ config.repo_auto_auth = true
34
35
 
35
36
  config.logger = Logger.new($stderr)
36
37
  config.logger.level = ENV['KUBES_LOG_LEVEL'] || :info
@@ -81,9 +82,22 @@ module Kubes
81
82
  yield(@config)
82
83
  end
83
84
 
85
+ # Load configs example:
86
+ #
87
+ # .kubes/config.rb
88
+ # .kubes/config/env/dev.rb
89
+ # .kubes/config/plugins/google.rb
90
+ # .kubes/config/plugins/google/dev.rb
91
+ #
84
92
  def load_configs
85
93
  evaluate_file(".kubes/config.rb")
86
94
  evaluate_file(".kubes/config/env/#{Kubes.env}.rb")
95
+ Kubes::Plugin.plugins.each do |klass|
96
+ # klass: IE: KubesAws, KubesGoogle
97
+ name = klass.to_s.underscore.sub('kubes_','') # kubes_google => google
98
+ evaluate_file(".kubes/config/plugins/#{name}.rb")
99
+ evaluate_file(".kubes/config/plugins/#{name}/#{Kubes.env}.rb")
100
+ end
87
101
  end
88
102
  end
89
103
  end
@@ -6,20 +6,36 @@ module Kubes::Hooks
6
6
  include Kubes::Logging
7
7
 
8
8
  attr_accessor :name
9
- def initialize(dsl_file, options={})
10
- @dsl_file, @options = dsl_file, options # IE: .kubes/config/hooks/kubectl.rb
9
+ def initialize(file, options={})
10
+ @file, @options = file, options # IE: .kubes/config/hooks/kubectl.rb
11
+ @dsl_file = "#{Kubes.root}/.kubes/config/hooks/#{@file}"
11
12
  @output_file = options[:file] # IE: .kubes/output/web/service.yaml
12
13
  @name = options[:name].to_s
13
14
  @hooks = {before: {}, after: {}}
14
15
  end
15
16
 
16
17
  def build
17
- return @hooks unless File.exist?(@dsl_file)
18
18
  evaluate_file(@dsl_file)
19
+ evaluate_plugin_hooks
19
20
  @hooks.deep_stringify_keys!
20
21
  end
21
22
  memoize :build
22
23
 
24
+ def evaluate_plugin_hooks
25
+ Kubes::Plugin.plugins.each do |klass|
26
+ hooks_class = hooks_class(klass)
27
+ next unless hooks_class
28
+ plugin_hooks = hooks_class.new
29
+ path = "#{plugin_hooks.path}/#{@file}"
30
+ evaluate_file(path)
31
+ end
32
+ end
33
+
34
+ def hooks_class(klass)
35
+ "#{klass}::Hooks".constantize # IE: KubesGoogle::Hooks
36
+ rescue NameError
37
+ end
38
+
23
39
  def run_hooks
24
40
  build
25
41
  run_each_hook("before")
@@ -42,8 +58,7 @@ module Kubes::Hooks
42
58
  id = "#{command} #{type} #{@name}"
43
59
  on = " on: #{hook["on"]}" if hook["on"]
44
60
  label = " label: #{hook["label"]}" if hook["label"]
45
- logger.info "Running #{id} hook.#{on}#{label}"
46
- logger.debug "Hook options: #{hook}"
61
+ logger.info "Hook: Running #{id} hook.#{on}#{label}"
47
62
  Runner.new(hook).run
48
63
  end
49
64
 
@@ -2,7 +2,7 @@ module Kubes::Hooks
2
2
  module Concern
3
3
  # options example: {:name=>"apply", :file=>".kubes/output/web/service.yaml"}
4
4
  def run_hooks(file, options={}, &block)
5
- hooks = Kubes::Hooks::Builder.new("#{Kubes.root}/.kubes/config/hooks/#{file}", options)
5
+ hooks = Kubes::Hooks::Builder.new(file, options)
6
6
  hooks.build # build hooks
7
7
  hooks.run_hooks(&block)
8
8
  end
@@ -22,10 +22,17 @@ class Kubes::Kubectl
22
22
  Kubes::Kubectl.run(@name, @options.merge(file: file))
23
23
  end
24
24
  end
25
+ prune # important to call within run_hooks for case of GKE IP whitelisting
25
26
  end
26
27
  end
27
28
  end
28
29
 
30
+ def prune
31
+ return unless @name == "apply" # only run for apply
32
+ return unless Kubes.config.auto_prune # prune old secrets and config maps
33
+ Kubes::CLI::Prune.new(@options.merge(yes: true, quiet: true)).run
34
+ end
35
+
29
36
  def switch_context(&block)
30
37
  kubectl = Kubes.config.kubectl
31
38
  context = kubectl.context
@@ -0,0 +1,14 @@
1
+ module Kubes
2
+ module Plugin
3
+ @@plugins = []
4
+ def plugins
5
+ @@plugins
6
+ end
7
+
8
+ def register(klass)
9
+ @@plugins << klass
10
+ end
11
+
12
+ extend self
13
+ end
14
+ end
@@ -32,7 +32,7 @@ module Kubes::Util
32
32
 
33
33
  def sh_capture(command, options={})
34
34
  exit_on_fail = options[:exit_on_fail].nil? ? true : options[:exit_on_fail]
35
- logger.info "=> #{command}" if options[:show_command]
35
+ logger.debug "=> #{command}"
36
36
  out = `#{command}`.strip
37
37
  unless $?.success?
38
38
  logger.error "ERROR: running #{command}".color(:red)
@@ -1,3 +1,3 @@
1
1
  module Kubes
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.4"
3
3
  end
@@ -0,0 +1,2 @@
1
+ module <%= underscored_name.camelize %>
2
+ end