kubes 0.4.7 → 0.5.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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/docs/_docs/config/reference.md +1 -0
  4. data/docs/_docs/config/skip.md +1 -1
  5. data/docs/_docs/dsl/multiple-resources.md +3 -3
  6. data/docs/_docs/dsl/resources/job.md +62 -0
  7. data/docs/_docs/extra-env/dsl.md +2 -2
  8. data/docs/_docs/extra-env/yaml.md +1 -1
  9. data/docs/_docs/generators.md +41 -0
  10. data/docs/_docs/helpers.md +2 -2
  11. data/docs/_docs/helpers/google/service-account.md +8 -0
  12. data/docs/_docs/intro.md +3 -1
  13. data/docs/_docs/intro/docker-image.md +66 -0
  14. data/docs/_docs/layering/merge.md +1 -1
  15. data/docs/_docs/learn/dsl/delete.md +10 -2
  16. data/docs/_docs/learn/dsl/review-project.md +2 -2
  17. data/docs/_docs/learn/yaml/delete.md +10 -2
  18. data/docs/_docs/learn/yaml/review-project.md +2 -2
  19. data/docs/_docs/patterns/clock-web-worker.md +3 -3
  20. data/docs/_docs/patterns/migrations.md +1 -1
  21. data/docs/_docs/yaml.md +2 -2
  22. data/docs/_includes/commands.html +2 -2
  23. data/docs/_includes/sidebar.html +2 -0
  24. data/docs/_reference/kubes-delete.md +1 -1
  25. data/docs/_reference/kubes-exec.md +17 -1
  26. data/docs/_reference/kubes-init.md +2 -2
  27. data/docs/_reference/kubes-logs.md +2 -1
  28. data/docs/_reference/kubes-new.md +58 -0
  29. data/docs/_reference/kubes-prune.md +22 -0
  30. data/docs/reference.md +2 -0
  31. data/lib/kubes.rb +1 -0
  32. data/lib/kubes/cli.rb +9 -1
  33. data/lib/kubes/cli/build.rb +6 -0
  34. data/lib/kubes/cli/compile.rb +7 -0
  35. data/lib/kubes/cli/deploy.rb +1 -6
  36. data/lib/kubes/cli/exec.rb +5 -1
  37. data/lib/kubes/cli/help/exec.md +15 -0
  38. data/lib/kubes/cli/help/new.md +30 -0
  39. data/lib/kubes/cli/init.rb +1 -1
  40. data/lib/kubes/cli/new.rb +97 -0
  41. data/lib/kubes/cli/sequence.rb +1 -0
  42. data/lib/kubes/command.rb +7 -0
  43. data/lib/kubes/compiler.rb +19 -21
  44. data/lib/kubes/compiler/dsl/syntax/job.rb +217 -0
  45. data/lib/kubes/compiler/shared/helpers.rb +11 -2
  46. data/lib/kubes/compiler/shared/helpers/deprecated.rb +37 -0
  47. data/lib/kubes/config.rb +1 -1
  48. data/lib/kubes/core.rb +6 -0
  49. data/lib/kubes/docker/strategy/image_name.rb +1 -1
  50. data/lib/kubes/kubectl/batch.rb +0 -33
  51. data/lib/kubes/kubectl/ordering.rb +42 -0
  52. data/lib/kubes/version.rb +1 -1
  53. data/lib/templates/base/.kubes/config.rb.tt +1 -1
  54. data/lib/templates/base/.kubes/config/env/dev.rb +1 -1
  55. data/lib/templates/base/.kubes/config/env/prod.rb +1 -1
  56. data/lib/templates/dsl/.kubes/resources/web/deployment.rb +1 -1
  57. data/lib/templates/new/dsl/backend_config.rb +10 -0
  58. data/lib/templates/new/dsl/config_map.rb +5 -0
  59. data/lib/templates/new/dsl/daemon_set.rb +11 -0
  60. data/lib/templates/new/dsl/deployment.rb +4 -0
  61. data/lib/templates/new/dsl/ingress.rb +3 -0
  62. data/lib/templates/new/dsl/job.rb +2 -0
  63. data/lib/templates/new/dsl/managed_certificate.rb +2 -0
  64. data/lib/templates/new/dsl/namespace.rb +2 -0
  65. data/lib/templates/new/dsl/network_policy.rb +7 -0
  66. data/lib/templates/new/dsl/pod.rb +6 -0
  67. data/lib/templates/new/dsl/role.rb +4 -0
  68. data/lib/templates/new/dsl/role_binding.rb +7 -0
  69. data/lib/templates/new/dsl/secret.rb +5 -0
  70. data/lib/templates/new/dsl/service.rb +2 -0
  71. data/lib/templates/new/dsl/service_account.rb +1 -0
  72. data/lib/templates/new/yaml/backend_config.yaml +10 -0
  73. data/lib/templates/new/yaml/config_map.yaml +9 -0
  74. data/lib/templates/new/yaml/daemon_set.yaml +11 -0
  75. data/lib/templates/new/yaml/deployment.yaml +20 -0
  76. data/lib/templates/new/yaml/ingress.yaml +12 -0
  77. data/lib/templates/new/yaml/job.yaml +19 -0
  78. data/lib/templates/new/yaml/managed_certificate.yaml +7 -0
  79. data/lib/templates/new/yaml/namespace.yaml +6 -0
  80. data/lib/templates/new/yaml/network_policy.yaml +20 -0
  81. data/lib/templates/new/yaml/pod.yaml +11 -0
  82. data/lib/templates/new/yaml/role.yaml +13 -0
  83. data/lib/templates/new/yaml/role_binding.yaml +11 -0
  84. data/lib/templates/new/yaml/secret.yaml +9 -0
  85. data/lib/templates/new/yaml/service.yaml +14 -0
  86. data/lib/templates/new/yaml/service_account.yaml +4 -0
  87. data/lib/templates/yaml/.kubes/resources/base/all.yaml.tt +2 -0
  88. data/lib/templates/yaml/.kubes/resources/web/deployment.yaml.tt +1 -1
  89. data/spec/kubes/cli/prune_spec.rb +1 -0
  90. data/spec/kubes/compiler_spec.rb +5 -1
  91. metadata +41 -2
@@ -3,6 +3,7 @@ require 'thor'
3
3
  class Kubes::CLI
4
4
  class Sequence < Thor::Group
5
5
  include Thor::Actions
6
+ include Kubes::Logging
6
7
 
7
8
  private
8
9
  def logger
@@ -28,6 +28,8 @@ module Kubes
28
28
  class Command < Thor
29
29
  class << self
30
30
  def dispatch(m, args, options, config)
31
+ check_project!(args.first)
32
+
31
33
  # Allow calling for help via:
32
34
  # kubes command help
33
35
  # kubes command -h
@@ -54,6 +56,11 @@ module Kubes
54
56
  super
55
57
  end
56
58
 
59
+ def check_project!(command_name)
60
+ return if %w[init new].include?(command_name)
61
+ Kubes.check_project!
62
+ end
63
+
57
64
  # Override command_help to include the description at the top of the
58
65
  # long_description.
59
66
  def command_help(shell, command_name)
@@ -3,6 +3,7 @@ module Kubes
3
3
  include Kubes::Hooks::Concern
4
4
  include Kubes::Logging
5
5
  include Kubes::Util::Consider
6
+ include Kubes::Kubectl::Ordering
6
7
 
7
8
  def initialize(options={})
8
9
  @options = options
@@ -21,7 +22,9 @@ module Kubes
21
22
  end
22
23
  end
23
24
 
24
- puts "Compiled .kubes/resources files to .kubes/output" if show_compiled_message?
25
+ write_full
26
+
27
+ logger.info "Compiled .kubes/resources files to .kubes/output" if show_compiled_message?
25
28
  end
26
29
 
27
30
  def resources
@@ -34,24 +37,6 @@ module Kubes
34
37
  paths
35
38
  end
36
39
 
37
- # Only considering files 2 layers deep. So:
38
- #
39
- # Yes = web/deployment.yaml
40
- # No = web/deployment/dev.yaml
41
- #
42
- def process?(path)
43
- if Kubes.kustomize?
44
- File.file?(path)
45
- else
46
- consider?(path) && two_levels_deep?(path)
47
- end
48
- end
49
-
50
- def two_levels_deep?(path)
51
- rel_path = path.sub(%r{.*\.kubes/resources/},'')
52
- rel_path.split('/').size == 2
53
- end
54
-
55
40
  def write(result)
56
41
  result.decorate!(:post)
57
42
  filename, content = result.filename, result.content
@@ -64,12 +49,25 @@ module Kubes
64
49
  IO.write(dest, content)
65
50
  end
66
51
 
67
- pretty_dest = dest.sub("#{Kubes.root}/",'')
68
- logger.debug "Compiled #{pretty_dest}"
52
+ logger.debug "Compiled #{pretty(dest)}"
53
+ end
54
+
55
+ def write_full
56
+ full = sorted_files.inject([]) do |acc, file|
57
+ acc << IO.read(file)
58
+ end
59
+ content = full.join("\n")
60
+ path = "#{Kubes.root}/.kubes/output/full.yaml"
61
+ IO.write(path, content)
62
+ logger.debug "Compiled #{pretty(path)}"
69
63
  end
70
64
 
71
65
  def show_compiled_message?
72
66
  !%w[g ge get].include?(ARGV.first)
73
67
  end
68
+
69
+ def pretty(path)
70
+ path.sub("#{Kubes.root}/",'')
71
+ end
74
72
  end
75
73
  end
@@ -0,0 +1,217 @@
1
+ module Kubes::Compiler::Dsl::Syntax
2
+ class Job < Resource
3
+ fields :container, # <Object>
4
+ "matchLabels:hash", # <map[string]string>
5
+ :sidecar, # <Object>
6
+ :sidecar_name, # <string>
7
+ :sidecar_image, # <string>
8
+ :templateMetadata, # <Object>
9
+ :templateSpec # <Object>
10
+
11
+ # kubectl explain job.spec
12
+ fields :activeDeadlineSeconds, # <integer>
13
+ :backoffLimit, # <integer>
14
+ :completions, # <integer>
15
+ :manualSelector, # <boolean>
16
+ :parallelism, # <integer>
17
+ :selector, # <Object>
18
+ :template, # <Object> -required-
19
+ :ttlSecondsAfterFinished # <integer>
20
+
21
+
22
+ # kubectl explain job.spec.template.spec
23
+ fields :activeDeadlineSeconds, # <integer>
24
+ :affinity, # <Object>
25
+ :automountServiceAccountToken, # <boolean>
26
+ :containers, # <[]Object> -required-
27
+ :dnsConfig, # <Object>
28
+ :dnsPolicy, # <string>
29
+ :enableServiceLinks, # <boolean>
30
+ :ephemeralContainers, # <[]Object>
31
+ :hostAliases, # <[]Object>
32
+ :hostIPC, # <boolean>
33
+ :hostNetwork, # <boolean>
34
+ :hostPID, # <boolean>
35
+ :hostname, # <string>
36
+ :imagePullSecrets, # <[]Object>
37
+ :initContainers, # <[]Object>
38
+ :nodeName, # <string>
39
+ :nodeSelector, # <map[string]string>
40
+ :overhead, # <map[string]string>
41
+ :preemptionPolicy, # <string>
42
+ :priority, # <integer>
43
+ :priorityClassName, # <string>
44
+ :readinessGates, # <[]Object>
45
+ :restartPolicy, # <string>
46
+ :runtimeClassName, # <string>
47
+ :schedulerName, # <string>
48
+ :securityContext, # <Object>
49
+ :serviceAccount, # <string>
50
+ :serviceAccountName, # <string>
51
+ :shareProcessNamespace, # <boolean>
52
+ :subdomain, # <string>
53
+ :terminationGracePeriodSeconds,# <integer>
54
+ :tolerations, # <[]Object>
55
+ :topologySpreadConstraints, # <[]Object>
56
+ :volumes # <[]Object>
57
+
58
+ # kubectl explain deployment.spec.template.spec.containers
59
+ fields :args, # <[]string>
60
+ :command, # <[]string>
61
+ :env, # <[]Object>
62
+ :envFrom, # <[]Object>
63
+ :image, # <string>
64
+ :imagePullPolicy, # <string>
65
+ :lifecycle, # <Object>
66
+ :livenessProbe, # <Object>
67
+ :containerName, # <string> -required- (originally called name)
68
+ :ports, # <[]Object>
69
+ :readinessProbe, # <Object>
70
+ :resources, # <Object>
71
+ :securityContext, # <Object>
72
+ :startupProbe, # <Object>
73
+ :stdin, # <boolean>
74
+ :stdinOnce, # <boolean>
75
+ :terminationMessagePath, # <string>
76
+ :terminationMessagePolicy, # <string>
77
+ :tty, # <boolean>
78
+ :volumeDevices, # <[]Object>
79
+ :volumeMounts, # <[]Object>
80
+ :workingDir # <string>
81
+
82
+ # kubectl explain deployment.spec.template.spec.containers.ports
83
+ fields :containerPort, # <integer> -required-
84
+ :hostIP, # <string>
85
+ :hostPort, # <integer>
86
+ :portName, # <string> (originally called name)
87
+ :protocol # <string>
88
+
89
+ def default_apiVersion
90
+ "batch/v1"
91
+ end
92
+
93
+ def default_spec
94
+ {
95
+ activeDeadlineSeconds: activeDeadlineSeconds,
96
+ backoffLimit: backoffLimit,
97
+ completions: completions,
98
+ manualSelector: manualSelector,
99
+ parallelism: parallelism,
100
+ selector: selector,
101
+ template: template,
102
+ ttlSecondsAfterFinished: ttlSecondsAfterFinished,
103
+ }
104
+ end
105
+
106
+ def default_matchLabels
107
+ labels
108
+ end
109
+
110
+ def default_template
111
+ {
112
+ metadata: templateMetadata,
113
+ spec: templateSpec,
114
+ }
115
+ end
116
+
117
+ def default_templateSpec
118
+ {
119
+ activeDeadlineSeconds: activeDeadlineSeconds,
120
+ affinity: affinity,
121
+ automountServiceAccountToken: automountServiceAccountToken,
122
+ containers: containers,
123
+ dnsConfig: dnsConfig,
124
+ dnsPolicy: dnsPolicy,
125
+ enableServiceLinks: enableServiceLinks,
126
+ ephemeralContainers: ephemeralContainers,
127
+ hostAliases: hostAliases,
128
+ hostIPC: hostIPC,
129
+ hostNetwork: hostNetwork,
130
+ hostPID: hostPID,
131
+ hostname: hostname,
132
+ imagePullSecrets: imagePullSecrets,
133
+ initContainers: initContainers,
134
+ nodeName: nodeName,
135
+ nodeSelector: nodeSelector,
136
+ overhead: overhead,
137
+ preemptionPolicy: preemptionPolicy,
138
+ priority: priority,
139
+ priorityClassName: priorityClassName,
140
+ readinessGates: readinessGates,
141
+ restartPolicy: restartPolicy,
142
+ runtimeClassName: runtimeClassName,
143
+ schedulerName: schedulerName,
144
+ securityContext: securityContext,
145
+ serviceAccount: serviceAccount,
146
+ serviceAccountName: serviceAccountName,
147
+ shareProcessNamespace: shareProcessNamespace,
148
+ subdomain: subdomain,
149
+ terminationGracePeriodSeconds: terminationGracePeriodSeconds,
150
+ tolerations: tolerations,
151
+ topologySpreadConstraints: topologySpreadConstraints,
152
+ volumes: volumes,
153
+ }
154
+ end
155
+
156
+ def default_templateMetadata
157
+ { labels: labels }
158
+ end
159
+
160
+ def default_containers
161
+ [container, sidecar].compact
162
+ end
163
+
164
+ def default_sidecar
165
+ {
166
+ name: sidecar_name,
167
+ image: sidecar_image,
168
+ }
169
+ end
170
+
171
+ def default_sidecar_name
172
+ "sidecar" if sidecar_image # othewise will create invalid sidecar field w/o image
173
+ end
174
+
175
+ def default_container
176
+ {
177
+ args: args,
178
+ command: command,
179
+ env: env,
180
+ envFrom: envFrom,
181
+ image: image,
182
+ imagePullPolicy: imagePullPolicy,
183
+ lifecycle: lifecycle,
184
+ livenessProbe: livenessProbe,
185
+ name: containerName || name,
186
+ ports: ports,
187
+ readinessProbe: readinessProbe,
188
+ resources: resources,
189
+ securityContext: securityContext,
190
+ startupProbe: startupProbe,
191
+ stdin: stdin,
192
+ stdinOnce: stdinOnce,
193
+ terminationMessagePath: terminationMessagePath,
194
+ terminationMessagePolicy: terminationMessagePolicy,
195
+ tty: tty,
196
+ volumeDevices: volumeDevices,
197
+ volumeMounts: volumeMounts,
198
+ workingDir: workingDir,
199
+ }
200
+ end
201
+
202
+ def default_ports
203
+ [
204
+ containerPort: containerPort,
205
+ hostIP: hostIP,
206
+ hostPort: hostPort,
207
+ name: portName,
208
+ protocol: protocol,
209
+ ]
210
+ end
211
+
212
+ # Override command instead of default_command since we want to change a String to an Array
213
+ def command_reader
214
+ @command.is_a?(String) ? @command.split(' ') : @command # else assume Array
215
+ end
216
+ end
217
+ end
@@ -5,12 +5,21 @@ module Kubes::Compiler::Shared
5
5
  extend Kubes::Compiler::Dsl::Core::Fields
6
6
  fields "name"
7
7
 
8
- def built_image
8
+ def docker_image
9
9
  return @options[:image] if @options[:image] # override
10
+ return Kubes.config.image if Kubes.config.image
11
+ built_image_helper
12
+ end
13
+
14
+ def built_image
15
+ Deprecated.new.built_image
16
+ built_image_helper
17
+ end
10
18
 
19
+ def built_image_helper
11
20
  path = Kubes.config.state.docker_image_path
12
21
  unless File.exist?(path)
13
- raise "Missing file with docker image built by kubes: #{path}. Try first running: kubes docker build"
22
+ raise Kubes::MissingDockerImage.new("Missing file with docker image built by kubes: #{path}. Try first running: kubes docker build")
14
23
  end
15
24
  IO.read(path)
16
25
  end
@@ -0,0 +1,37 @@
1
+ module Kubes::Compiler::Shared::Helpers
2
+ class Deprecated
3
+ def built_image
4
+ puts "DEPRECATED: built_image is deprecated, use docker_image helper instead.".color(:yellow)
5
+ print_source
6
+ end
7
+
8
+ def error_info
9
+ error_info = caller.find { |l| l.include?('.kubes/resources') }
10
+ path, line_number, _ = error_info.split(':')
11
+ {path: path, line_number: line_number}
12
+ end
13
+
14
+ def print_source
15
+ info = error_info
16
+ path = info[:path]
17
+ line_number = info[:line_number].to_i
18
+
19
+ pretty_path = path.sub("#{Kubes.root}/",'')
20
+ puts "Here's the line in #{pretty_path} that calls built_image:\n\n"
21
+
22
+ contents = IO.read(path)
23
+ content_lines = contents.split("\n")
24
+ context = 5 # lines of context
25
+ top, bottom = [line_number-context-1, 0].max, line_number+context-1
26
+ lpad = content_lines.size.to_s.size
27
+ content_lines[top..bottom].each_with_index do |line_content, index|
28
+ current_line = top+index+1
29
+ if current_line == line_number
30
+ printf("%#{lpad}d %s\n".color(:red), current_line, line_content)
31
+ else
32
+ printf("%#{lpad}d %s\n", current_line, line_content)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -32,7 +32,7 @@ module Kubes
32
32
 
33
33
  config.repo = nil # expected to be set by .kubes/config.rb
34
34
 
35
- config.logger = Logger.new($stdout)
35
+ config.logger = Logger.new($stderr)
36
36
  config.logger.level = ENV['KUBES_LOG_LEVEL'] || :info
37
37
 
38
38
  config.skip = []
@@ -28,5 +28,11 @@ module Kubes
28
28
  def kustomize?
29
29
  Kubectl::Kustomize.detect?
30
30
  end
31
+
32
+ def check_project!
33
+ return if File.exist?("#{Kubes.root}/.kubes/config.rb")
34
+ logger.error "ERROR: It doesnt look like this is a kubes project. Are you sure you are in a kubes project?".color(:red)
35
+ ENV['TS_TEST'] ? raise : exit(1)
36
+ end
31
37
  end
32
38
  end
@@ -30,7 +30,7 @@ module Kubes::Docker::Strategy
30
30
  return "tongueroo/demo-kubes:kubes-12345678" if ENV['TEST']
31
31
 
32
32
  unless File.exist?(image_state_path)
33
- puts "Unable to find #{image_state_path} which contains the last docker image name built with kubes build. Please run `kubes docker build` first."
33
+ logger.error "ERROR: Unable to find #{image_state_path} which contains the last docker image name built with kubes build. Please run `kubes docker build` first."
34
34
  exit 1
35
35
  end
36
36
  IO.read(image_state_path).strip
@@ -49,38 +49,5 @@ class Kubes::Kubectl
49
49
  end
50
50
  result
51
51
  end
52
-
53
- # kubes apply # {role: nil, resource: nil}
54
- # kubes apply clock # {role: "clock", resource: nil}
55
- # kubes apply clock deployment # {role: "clock", resource: "deployment"}
56
- def search_expr
57
- role, resource = @options[:role], @options[:resource]
58
- if role && resource
59
- "#{Kubes.root}/.kubes/output/#{role}/#{resource}.yaml"
60
- elsif role
61
- "#{Kubes.root}/.kubes/output/#{role}/*.yaml"
62
- else
63
- "#{Kubes.root}/.kubes/output/**/*.yaml"
64
- end
65
- end
66
-
67
- def files
68
- files = []
69
- Dir.glob(search_expr).each do |path|
70
- next unless process?(path)
71
- file = path.sub("#{Kubes.root}/", '')
72
- files << file
73
- end
74
- files
75
- end
76
-
77
- def process?(path)
78
- consider?(path) && two_levels_deep?(path)
79
- end
80
-
81
- def two_levels_deep?(path)
82
- rel_path = path.sub(%r{.*\.kubes/output/},'')
83
- rel_path.split('/').size == 2
84
- end
85
52
  end
86
53
  end