kubes 0.5.0 → 0.6.3

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 (125) 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 +54 -8
  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 +16 -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 +18 -88
  21. data/docs/_docs/helpers/aws/ssm.md +20 -38
  22. data/docs/_docs/helpers/google/advanced.md +10 -0
  23. data/docs/_docs/helpers/google/advanced/secrets.md +78 -0
  24. data/docs/_docs/helpers/google/gke.md +89 -0
  25. data/docs/_docs/helpers/google/secrets.md +18 -27
  26. data/docs/_docs/intro.md +2 -11
  27. data/docs/_docs/intro/how-kubes-works.md +7 -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/variables.md +23 -0
  32. data/docs/_docs/variables/advanced.md +62 -0
  33. data/docs/_docs/variables/basic.md +137 -0
  34. data/docs/_docs/vs.md +10 -0
  35. data/docs/_docs/vs/custom.md +109 -0
  36. data/docs/_docs/vs/helm.md +243 -0
  37. data/docs/_docs/vs/kustomize.md +167 -0
  38. data/docs/_includes/intro/features.md +11 -0
  39. data/docs/_includes/layering/layers.md +2 -4
  40. data/docs/_includes/sidebar.html +39 -0
  41. data/docs/_includes/vs/article.md +1 -0
  42. data/docs/_includes/vs/kubes/layering.md +10 -0
  43. data/docs/_includes/vs/kubes/structure.md +24 -0
  44. data/docs/_reference/kubes-new-help.md +15 -0
  45. data/docs/_reference/kubes-new-helper.md +25 -0
  46. data/docs/_reference/kubes-new-resource.md +56 -0
  47. data/docs/_reference/kubes-new-variable.md +20 -0
  48. data/docs/_reference/kubes-new.md +6 -38
  49. data/kubes.gemspec +2 -2
  50. data/lib/kubes.rb +4 -3
  51. data/lib/kubes/auth.rb +13 -1
  52. data/lib/kubes/auth/base.rb +21 -0
  53. data/lib/kubes/auth/ecr.rb +1 -15
  54. data/lib/kubes/auth/gcr.rb +24 -0
  55. data/lib/kubes/cli/apply.rb +0 -1
  56. data/lib/kubes/cli/help/new/helper.md +4 -0
  57. data/lib/kubes/cli/help/{new.md → new/resource.md} +3 -3
  58. data/lib/kubes/cli/new.rb +12 -94
  59. data/lib/kubes/cli/new/helper.rb +24 -0
  60. data/lib/kubes/cli/new/resource.rb +97 -0
  61. data/lib/kubes/cli/new/variable.rb +16 -0
  62. data/lib/kubes/cli/prune.rb +4 -2
  63. data/lib/kubes/command.rb +1 -1
  64. data/lib/kubes/compiler/decorator/base.rb +1 -1
  65. data/lib/kubes/compiler/dsl/core/base.rb +6 -9
  66. data/lib/kubes/compiler/layering.rb +21 -7
  67. data/lib/kubes/compiler/shared/custom_variables.rb +38 -0
  68. data/lib/kubes/compiler/shared/plugin_helpers.rb +14 -0
  69. data/lib/kubes/compiler/strategy.rb +7 -6
  70. data/lib/kubes/compiler/strategy/base.rb +59 -2
  71. data/lib/kubes/compiler/strategy/dsl.rb +0 -29
  72. data/lib/kubes/compiler/strategy/erb.rb +10 -22
  73. data/lib/kubes/compiler/util/normalize.rb +6 -3
  74. data/lib/kubes/compiler/util/yaml_dump.rb +4 -4
  75. data/lib/kubes/config.rb +14 -0
  76. data/lib/kubes/hooks/builder.rb +20 -5
  77. data/lib/kubes/hooks/concern.rb +1 -1
  78. data/lib/kubes/kubectl/batch.rb +7 -0
  79. data/lib/kubes/plugin.rb +14 -0
  80. data/lib/kubes/util/sh.rb +1 -1
  81. data/lib/kubes/version.rb +1 -1
  82. data/lib/templates/new/helper/file.rb +2 -0
  83. data/lib/templates/new/{dsl → resource/dsl}/backend_config.rb +0 -0
  84. data/lib/templates/new/{dsl → resource/dsl}/config_map.rb +0 -0
  85. data/lib/templates/new/{dsl → resource/dsl}/daemon_set.rb +0 -0
  86. data/lib/templates/new/{dsl → resource/dsl}/deployment.rb +0 -0
  87. data/lib/templates/new/{dsl → resource/dsl}/ingress.rb +0 -0
  88. data/lib/templates/new/{dsl → resource/dsl}/job.rb +0 -0
  89. data/lib/templates/new/{dsl → resource/dsl}/managed_certificate.rb +0 -0
  90. data/lib/templates/new/{dsl → resource/dsl}/namespace.rb +0 -0
  91. data/lib/templates/new/{dsl → resource/dsl}/network_policy.rb +0 -0
  92. data/lib/templates/new/{dsl → resource/dsl}/pod.rb +0 -0
  93. data/lib/templates/new/{dsl → resource/dsl}/role.rb +0 -0
  94. data/lib/templates/new/{dsl → resource/dsl}/role_binding.rb +0 -0
  95. data/lib/templates/new/{dsl → resource/dsl}/secret.rb +0 -0
  96. data/lib/templates/new/{dsl → resource/dsl}/service.rb +0 -0
  97. data/lib/templates/new/{dsl → resource/dsl}/service_account.rb +0 -0
  98. data/lib/templates/new/{yaml → resource/yaml}/backend_config.yaml +0 -0
  99. data/lib/templates/new/{yaml → resource/yaml}/config_map.yaml +0 -0
  100. data/lib/templates/new/{yaml → resource/yaml}/daemon_set.yaml +0 -0
  101. data/lib/templates/new/{yaml → resource/yaml}/deployment.yaml +0 -1
  102. data/lib/templates/new/{yaml → resource/yaml}/ingress.yaml +0 -0
  103. data/lib/templates/new/{yaml → resource/yaml}/job.yaml +0 -0
  104. data/lib/templates/new/{yaml → resource/yaml}/managed_certificate.yaml +0 -0
  105. data/lib/templates/new/{yaml → resource/yaml}/namespace.yaml +0 -0
  106. data/lib/templates/new/{yaml → resource/yaml}/network_policy.yaml +0 -0
  107. data/lib/templates/new/{yaml → resource/yaml}/pod.yaml +0 -0
  108. data/lib/templates/new/{yaml → resource/yaml}/role.yaml +0 -0
  109. data/lib/templates/new/{yaml → resource/yaml}/role_binding.yaml +0 -0
  110. data/lib/templates/new/{yaml → resource/yaml}/secret.yaml +0 -0
  111. data/lib/templates/new/{yaml → resource/yaml}/service.yaml +0 -0
  112. data/lib/templates/new/{yaml → resource/yaml}/service_account.yaml +0 -0
  113. data/lib/templates/new/variable/file.rb +1 -0
  114. data/spec/fixtures/multiple-files/{deployment-1.rb → .kubes/resources/web/deployment-1.rb} +0 -0
  115. data/spec/fixtures/multiple-files/{deployment-2.rb → .kubes/resources/web/deployment-2.rb} +0 -0
  116. data/spec/fixtures/project/.kubes/resources/{deployment.rb → web/deployment.rb} +0 -0
  117. data/spec/fixtures/project/.kubes/resources/{foobar.rb → web/empty.rb} +0 -0
  118. data/spec/fixtures/project/.kubes/resources/{service.rb → web/service.rb} +1 -1
  119. data/spec/fixtures/syntax/{network_policy.rb → .kubes/resources/web/network_policy.rb} +0 -0
  120. data/spec/fixtures/syntax/{pod.rb → .kubes/resources/web/pod.rb} +0 -0
  121. data/spec/kubes/compiler/strategy/dsl_spec.rb +2 -2
  122. data/spec/kubes/compiler_spec.rb +1 -1
  123. data/spec/kubes/dsl/network_policy_spec.rb +1 -1
  124. data/spec/kubes/dsl/pod_spec.rb +1 -1
  125. metadata +95 -56
@@ -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.0"
2
+ VERSION = "0.6.3"
3
3
  end
@@ -0,0 +1,2 @@
1
+ module <%= underscored_name.camelize %>
2
+ end
@@ -1,4 +1,3 @@
1
- test: 1
2
1
  apiVersion: apps/v1
3
2
  kind: Deployment
4
3
  metadata:
@@ -0,0 +1 @@
1
+ @example = "<%= Kubes.env %>-value"
@@ -1,3 +1,3 @@
1
1
  name "demo-web"
2
2
  port 80
3
- target_port 3000
3
+ targetPort 3000
@@ -3,7 +3,7 @@ describe Kubes::Compiler::Strategy::Dsl do
3
3
  let(:options) { {path: fixture(resource) } }
4
4
 
5
5
  context "standard" do
6
- let(:resource) { "project/.kubes/resources/deployment" }
6
+ let(:resource) { "project/.kubes/resources/web/deployment" }
7
7
  it "run" do
8
8
  result = dsl.run
9
9
  expect(dsl.dsl_class).to eq(Kubes::Compiler::Dsl::Syntax::Deployment)
@@ -25,7 +25,7 @@ describe Kubes::Compiler::Strategy::Dsl do
25
25
  end
26
26
 
27
27
  context "multiple files" do
28
- let(:resource) { "multiple-files/deployment-1" }
28
+ let(:resource) { "multiple-files/.kubes/resources/web/deployment-1" }
29
29
  it "run" do
30
30
  result = dsl.run
31
31
  expect(dsl.dsl_class).to eq(Kubes::Compiler::Dsl::Syntax::Deployment)