kontena-mortar 0.2.0.pre5 → 0.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c6641d230a974893218c9c7cf7c72804a450d4a8faaafb2785f7660d034de0b
4
- data.tar.gz: 9f5b2f3a5b5ea42f5c99d9fff2dfa7856e2cba3b119a140f76d09114616f78ec
3
+ metadata.gz: cff0530a854b482030dadc4223cac97233b85b1a4e15625a0ec5483c641446b2
4
+ data.tar.gz: 5204676edc234f73e953068d2392ef8390898adcde8642c79579a182cd10efc2
5
5
  SHA512:
6
- metadata.gz: 7eb162fd4cb67521319721b4deeb5a7337e6771a3e6a1b17fd728369d2398c5b4f17477eaa0ba6e5618ebdc41ea7ec4bbf0723efedd46f24b90c223006062f1f
7
- data.tar.gz: 850d89b358166d680c09a6d5e1943dd5ef16c8ad52678ce85c140b2156c1d1db6814b20d720b5df101c24ab0484519841e0b8e3c521b849377c1047cb0982e0f
6
+ metadata.gz: 3ce686d74349ecdb2229e42d9effc248ceb72902ceaa71b3dbe570ae2789729e194c44336969a86429b34251b50bca07a617362b7eb730d89375b7364bcde3b6
7
+ data.tar.gz: 0bba3e81223eca4342f5e601b4ae82229cf14e44b0b18fe7acba17ca7ac9887a0e469e73afb7d58d5eaaec9f866d130519067dac84eec0c99763692b17acf630
data/.drone.yml CHANGED
@@ -4,6 +4,7 @@ pipeline:
4
4
  commands:
5
5
  - bundle install --path bundler
6
6
  - bundle exec rspec spec/ # && bundle exec rubocop --fail-level A -S --format c --parallel
7
+ - bundle exec rubocop lib/
7
8
  docker_latest:
8
9
  registry: quay.io
9
10
  image: plugins/docker
@@ -0,0 +1,166 @@
1
+ # Relaxed.Ruby.Style
2
+ ## Version 2.2
3
+
4
+ Style/Alias:
5
+ Enabled: false
6
+ StyleGuide: http://relaxed.ruby.style/#stylealias
7
+
8
+ Style/AsciiComments:
9
+ Enabled: false
10
+ StyleGuide: http://relaxed.ruby.style/#styleasciicomments
11
+
12
+ Style/BeginBlock:
13
+ Enabled: false
14
+ StyleGuide: http://relaxed.ruby.style/#stylebeginblock
15
+
16
+ Style/BlockDelimiters:
17
+ Enabled: false
18
+ StyleGuide: http://relaxed.ruby.style/#styleblockdelimiters
19
+
20
+ Style/CommentAnnotation:
21
+ Enabled: false
22
+ StyleGuide: http://relaxed.ruby.style/#stylecommentannotation
23
+
24
+ Style/Documentation:
25
+ Enabled: false
26
+ StyleGuide: http://relaxed.ruby.style/#styledocumentation
27
+
28
+ Layout/DotPosition:
29
+ Enabled: false
30
+ StyleGuide: http://relaxed.ruby.style/#layoutdotposition
31
+
32
+ Style/DoubleNegation:
33
+ Enabled: false
34
+ StyleGuide: http://relaxed.ruby.style/#styledoublenegation
35
+
36
+ Style/EndBlock:
37
+ Enabled: false
38
+ StyleGuide: http://relaxed.ruby.style/#styleendblock
39
+
40
+ Style/FormatString:
41
+ Enabled: false
42
+ StyleGuide: http://relaxed.ruby.style/#styleformatstring
43
+
44
+ Style/IfUnlessModifier:
45
+ Enabled: false
46
+ StyleGuide: http://relaxed.ruby.style/#styleifunlessmodifier
47
+
48
+ Style/Lambda:
49
+ Enabled: false
50
+ StyleGuide: http://relaxed.ruby.style/#stylelambda
51
+
52
+ Style/ModuleFunction:
53
+ Enabled: false
54
+ StyleGuide: http://relaxed.ruby.style/#stylemodulefunction
55
+
56
+ Style/MultilineBlockChain:
57
+ Enabled: false
58
+ StyleGuide: http://relaxed.ruby.style/#stylemultilineblockchain
59
+
60
+ Style/NegatedIf:
61
+ Enabled: false
62
+ StyleGuide: http://relaxed.ruby.style/#stylenegatedif
63
+
64
+ Style/NegatedWhile:
65
+ Enabled: false
66
+ StyleGuide: http://relaxed.ruby.style/#stylenegatedwhile
67
+
68
+ Style/ParallelAssignment:
69
+ Enabled: false
70
+ StyleGuide: http://relaxed.ruby.style/#styleparallelassignment
71
+
72
+ Style/PercentLiteralDelimiters:
73
+ Enabled: false
74
+ StyleGuide: http://relaxed.ruby.style/#stylepercentliteraldelimiters
75
+
76
+ Style/PerlBackrefs:
77
+ Enabled: false
78
+ StyleGuide: http://relaxed.ruby.style/#styleperlbackrefs
79
+
80
+ Style/Semicolon:
81
+ Enabled: false
82
+ StyleGuide: http://relaxed.ruby.style/#stylesemicolon
83
+
84
+ Style/SignalException:
85
+ Enabled: false
86
+ StyleGuide: http://relaxed.ruby.style/#stylesignalexception
87
+
88
+ Style/SingleLineBlockParams:
89
+ Enabled: false
90
+ StyleGuide: http://relaxed.ruby.style/#stylesinglelineblockparams
91
+
92
+ Style/SingleLineMethods:
93
+ Enabled: false
94
+ StyleGuide: http://relaxed.ruby.style/#stylesinglelinemethods
95
+
96
+ Layout/SpaceBeforeBlockBraces:
97
+ Enabled: false
98
+ StyleGuide: http://relaxed.ruby.style/#layoutspacebeforeblockbraces
99
+
100
+ Layout/SpaceInsideParens:
101
+ Enabled: false
102
+ StyleGuide: http://relaxed.ruby.style/#layoutspaceinsideparens
103
+
104
+ Style/SpecialGlobalVars:
105
+ Enabled: false
106
+ StyleGuide: http://relaxed.ruby.style/#stylespecialglobalvars
107
+
108
+ Style/StringLiterals:
109
+ Enabled: false
110
+ StyleGuide: http://relaxed.ruby.style/#stylestringliterals
111
+
112
+ # Style/TrailingCommaInArguments:
113
+ # Enabled: false
114
+ # StyleGuide: http://relaxed.ruby.style/#styletrailingcommainarguments
115
+ #
116
+ # Style/TrailingCommaInArrayLiteral:
117
+ # Enabled: false
118
+ # StyleGuide: http://relaxed.ruby.style/#styletrailingcommainarrayliteral
119
+ #
120
+ # Style/TrailingCommaInHashLiteral:
121
+ # Enabled: false
122
+ # StyleGuide: http://relaxed.ruby.style/#styletrailingcommainhashliteral
123
+
124
+ Style/WhileUntilModifier:
125
+ Enabled: false
126
+ StyleGuide: http://relaxed.ruby.style/#stylewhileuntilmodifier
127
+
128
+ Style/WordArray:
129
+ Enabled: false
130
+ StyleGuide: http://relaxed.ruby.style/#stylewordarray
131
+
132
+ Lint/AmbiguousRegexpLiteral:
133
+ Enabled: false
134
+ StyleGuide: http://relaxed.ruby.style/#lintambiguousregexpliteral
135
+
136
+ Lint/AssignmentInCondition:
137
+ Enabled: false
138
+ StyleGuide: http://relaxed.ruby.style/#lintassignmentincondition
139
+
140
+ Metrics/AbcSize:
141
+ Enabled: false
142
+
143
+ Metrics/BlockNesting:
144
+ Enabled: false
145
+
146
+ Metrics/ClassLength:
147
+ Enabled: false
148
+
149
+ Metrics/ModuleLength:
150
+ Enabled: false
151
+
152
+ Metrics/CyclomaticComplexity:
153
+ Enabled: false
154
+
155
+ Metrics/LineLength:
156
+ Enabled: false
157
+
158
+ Metrics/MethodLength:
159
+ Enabled: false
160
+
161
+ Metrics/ParameterLists:
162
+ Enabled: false
163
+
164
+ Metrics/PerceivedComplexity:
165
+ Enabled: false
166
+
@@ -0,0 +1,57 @@
1
+ inherit_from: .rubocop.relaxed.yml
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - spec/**/*
6
+ - Gemfile
7
+ - "*.gemspec"
8
+ - bundler/**/*
9
+ TargetRubyVersion: 2.4
10
+
11
+ Style/PercentLiteralDelimiters:
12
+ PreferredDelimiters:
13
+ default: ()
14
+ '%i': '()'
15
+ '%I': '()'
16
+ '%r': '{}'
17
+ '%w': '()'
18
+ '%W': '()'
19
+
20
+ Style/FormatString:
21
+ EnforcedStyle: percent
22
+
23
+ Style/FrozenStringLiteralComment:
24
+ EnforcedStyle: always
25
+
26
+ Style/WordArray:
27
+ Enabled: true
28
+ MinSize: 3
29
+
30
+ Style/SymbolArray:
31
+ Enabled: true
32
+ MinSize: 3
33
+
34
+ Gemspec/OrderedDependencies:
35
+ Enabled: false
36
+
37
+ Style/PerlBackrefs:
38
+ Enabled: true
39
+
40
+ Layout/SpaceInsideParens:
41
+ Enabled: true
42
+
43
+ Style/SpecialGlobalVars:
44
+ Enabled: true
45
+
46
+ Style/Alias:
47
+ Enabled: true
48
+
49
+ Style/BeginBlock:
50
+ Enabled: true
51
+
52
+ Naming/UncommunicativeMethodParamName:
53
+ AllowedNames:
54
+ - cn
55
+
56
+ Metrics/BlockLength:
57
+ Enabled: false
@@ -1,16 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kontena-mortar (0.2.0.pre5)
4
+ kontena-mortar (0.2.0.rc1)
5
5
  clamp (~> 1.3)
6
6
  deep_merge (~> 1.2)
7
- k8s-client (~> 0.4.1)
7
+ k8s-client (~> 0.4.2)
8
8
  pastel (~> 0.7.2)
9
9
  rouge (~> 3.2)
10
10
 
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
+ ast (2.4.0)
14
15
  clamp (1.3.0)
15
16
  concurrent-ruby (1.0.5)
16
17
  deep_merge (1.2.1)
@@ -44,15 +45,21 @@ GEM
44
45
  excon (0.62.0)
45
46
  hashdiff (0.3.7)
46
47
  ice_nine (0.11.2)
47
- k8s-client (0.4.1)
48
+ jaro_winkler (1.5.1)
49
+ k8s-client (0.4.2)
48
50
  deep_merge (~> 1.2.1)
49
51
  dry-struct (~> 0.5.0)
50
52
  excon (~> 0.62.0)
51
53
  hashdiff (~> 0.3.7)
52
54
  recursive-open-struct (~> 1.1.0)
55
+ parallel (1.12.1)
56
+ parser (2.5.1.2)
57
+ ast (~> 2.4.0)
53
58
  pastel (0.7.2)
54
59
  equatable (~> 0.5.0)
55
60
  tty-color (~> 0.4.0)
61
+ powerpack (0.1.2)
62
+ rainbow (3.0.0)
56
63
  rake (10.5.0)
57
64
  recursive-open-struct (1.1.0)
58
65
  rouge (3.2.1)
@@ -69,7 +76,17 @@ GEM
69
76
  diff-lcs (>= 1.2.0, < 2.0)
70
77
  rspec-support (~> 3.8.0)
71
78
  rspec-support (3.8.0)
79
+ rubocop (0.59.0)
80
+ jaro_winkler (~> 1.5.1)
81
+ parallel (~> 1.10)
82
+ parser (>= 2.5, != 2.5.1.1)
83
+ powerpack (~> 0.1)
84
+ rainbow (>= 2.2.2, < 4.0)
85
+ ruby-progressbar (~> 1.7)
86
+ unicode-display_width (~> 1.0, >= 1.0.1)
87
+ ruby-progressbar (1.10.0)
72
88
  tty-color (0.4.3)
89
+ unicode-display_width (1.4.0)
73
90
 
74
91
  PLATFORMS
75
92
  ruby
@@ -79,6 +96,7 @@ DEPENDENCIES
79
96
  kontena-mortar!
80
97
  rake (~> 10.0)
81
98
  rspec (~> 3.0)
99
+ rubocop (~> 0.57)
82
100
 
83
101
  BUNDLED WITH
84
- 1.16.3
102
+ 1.16.1
data/README.md CHANGED
@@ -14,11 +14,13 @@ While we were developing [Kontena Pharos](https://kontena.io/pharos) Kubernetes
14
14
 
15
15
  ## Installation
16
16
 
17
- Rubygems:
17
+ ### Rubygems:
18
18
 
19
19
  `$ gem install kontena-mortar`
20
20
 
21
- Docker:
21
+ To install bash/zsh auto-completions, use `mortar install-completions` after Mortar has been installed.
22
+
23
+ ### Docker:
22
24
 
23
25
  `$ docker pull quay.io/kontena/mortar:latest`
24
26
 
@@ -60,10 +62,16 @@ pipeline:
60
62
  image: quay.io/kontena/mortar:latest
61
63
  secrets: [ kube_token, kube_ca, kube_server ]
62
64
  commands:
63
- - mortar my-app k8s/
65
+ - mortar fire k8s/ my-app
64
66
 
65
67
  ```
66
68
 
69
+ ## Namespaces
70
+
71
+ **Namespace is mandatory to be set on the resources**
72
+
73
+ Currently Mortar will not add any default namespaces into the resources it shoots. Therefore it is mandatory for the user to set the namespaces in all namespaced resources shot with Mortar. See [this](https://github.com/kontena/mortar/issues/10) issue for details and track the fix.
74
+
67
75
  ## Shots
68
76
 
69
77
  Mortar manages a set of resources as a single unit, we call them *shots*. A shot can have as many resources as your application needs, there's no limit to that. Much like you'd do with `kubectl apply -f my_dir/`, but Mortar actually injects information into the resources it shoots into your Kubernetes cluster. This added information, labels and annotations, will be used later on by Mortar itself or can be used with `kubectl` too. This allows the management of many resources as a single application.
@@ -103,13 +111,15 @@ See example of overlays [here](/examples/overlays).
103
111
 
104
112
  Mortar also support templating for the resource definitons. The templating language used is [ERB](https://en.wikipedia.org/wiki/ERuby). It's pretty simple templating language but yet powerful enough for Kubernetes resource templating.
105
113
 
106
- Mortar automatically processes the resource definition as a template if the filename is either `.yml.erb` or `.yaml.erb`.
114
+ **Note:** Mortar will process the resource definitions as ERB even if the filename does not have the `.erb` extension. This means that Ruby code in an innocent looking `.yml` file will be evaluated using the current user's access privileges on the local machine. Running untrusted code is dangerous and so is deploying untrusted manifests, make sure you know what you're deploying.
115
+
116
+ ### Variables
107
117
 
108
118
  There are two ways to introduce variables into the templating.
109
119
 
110
120
  See examples at [examples/templates](examples/templates).
111
121
 
112
- ### Environment variables
122
+ #### Environment variables
113
123
 
114
124
  As for any process, environment variables are also available for Mortar during template processing.
115
125
 
@@ -129,7 +139,7 @@ spec:
129
139
  - containerPort: 80
130
140
  ```
131
141
 
132
- ### Variables via options
142
+ #### Variables via options
133
143
 
134
144
  Another option to use variables is via command-line options. Use `mortar --var foo=bar my-app resources/`.
135
145
 
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -23,12 +23,16 @@ Gem::Specification.new do |spec|
23
23
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ["lib"]
25
25
 
26
+ spec.post_install_message = "To install shell auto-completions, use:\n mortar install-completions"
27
+
26
28
  spec.add_runtime_dependency "clamp", "~> 1.3"
27
- spec.add_runtime_dependency "k8s-client", "~> 0.4.1"
29
+ spec.add_runtime_dependency "k8s-client", "~> 0.4.2"
28
30
  spec.add_runtime_dependency "rouge", "~> 3.2"
29
31
  spec.add_runtime_dependency "deep_merge", "~> 1.2"
30
32
  spec.add_runtime_dependency "pastel", "~> 0.7.2"
31
33
  spec.add_development_dependency "bundler", "~> 1.16"
32
34
  spec.add_development_dependency "rake", "~> 10.0"
33
35
  spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_development_dependency "rubocop", "~> 0.57"
34
37
  end
38
+
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Extensions
2
4
  module RecursiveOpenStruct
3
5
  module Each
4
- def each(&block)
5
- self.to_h.each { |k,v| yield k.to_s,v }
6
+ def each
7
+ to_h.each { |k, v| yield k.to_s, v }
6
8
  end
7
9
  end
8
10
  end
9
11
  end
10
12
 
11
13
  # Monkey-patch the above module into RecursiveOpenStruct
12
- RecursiveOpenStruct.include Extensions::RecursiveOpenStruct::Each
14
+ RecursiveOpenStruct.include Extensions::RecursiveOpenStruct::Each
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "clamp"
2
4
  require "deep_merge"
3
5
  require "mortar/version"
@@ -9,8 +11,10 @@ autoload :ERB, "erb"
9
11
  autoload :Rouge, "rouge"
10
12
  autoload :RecursiveOpenStruct, "recursive-open-struct"
11
13
  autoload :Pastel, "pastel"
14
+ autoload :Pathname, "pathname"
15
+ autoload :FileUtils, "fileutils"
12
16
 
13
17
  require "extensions/recursive_open_struct/each"
14
18
 
15
19
  module Mortar
16
- end
20
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "clamp"
2
4
 
3
5
  module Mortar
@@ -7,4 +9,4 @@ module Mortar
7
9
 
8
10
  option ["-d", "--debug"], :flag, "debug"
9
11
  end
10
- end
12
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "base64"
2
4
  require_relative "command"
3
5
  require_relative "yaml_file"
@@ -94,7 +96,7 @@ module Mortar
94
96
  def dotted_path_to_hash(hash)
95
97
  hash.map do |pkey, pvalue|
96
98
  pkey.to_s.split(".").reverse.inject(pvalue) do |value, key|
97
- {key.to_sym => value}
99
+ { key.to_sym => value }
98
100
  end
99
101
  end.inject(&:deep_merge)
100
102
  end
@@ -102,7 +104,7 @@ module Mortar
102
104
  # Stringifies all hash keys
103
105
  # @return [Hash]
104
106
  def stringify_hash(hash)
105
- JSON.load(JSON.dump(hash))
107
+ JSON.parse(JSON.dump(hash))
106
108
  end
107
109
  end
108
- end
110
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mortar
4
+ class InstallCompletionsCommand < Mortar::Command
5
+ include Mortar::TTYHelper
6
+
7
+ DEFAULT_PATHS = [
8
+ '/etc/bash_completion.d/mortar.bash',
9
+ '/usr/local/etc/bash_completion.d/mortar.bash',
10
+ '/usr/share/zsh/site-functions/_mortar',
11
+ '/usr/local/share/zsh/site-functions/_mortar',
12
+ '/usr/local/share/zsh-completions/_mortar',
13
+ File.join(Dir.home, '.bash_completion.d', 'mortar.bash')
14
+ ].freeze
15
+
16
+ COMPLETION_FILE_PATH = File.expand_path(
17
+ '../../opt/bash-completion.sh',
18
+ Pathname.new(__dir__).realpath
19
+ ).freeze
20
+
21
+ banner 'Installs bash/zsh auto completion script'
22
+
23
+ option '--remove', :flag, 'Remove completion script from known locations'
24
+
25
+ def execute
26
+ return uninstall if remove?
27
+
28
+ installed = []
29
+
30
+ DEFAULT_PATHS.each do |path|
31
+ next unless File.directory?(File.dirname(path))
32
+
33
+ begin
34
+ FileUtils.ln_sf(COMPLETION_FILE_PATH, path)
35
+ installed << path
36
+ rescue Errno::EACCES, Errno::EPERM
37
+ nil # To keep Mr. Rubocop happy
38
+ end
39
+ end
40
+
41
+ if installed.empty?
42
+ warn "Installation failed"
43
+ warn "Try with sudo or set up user bash completions in ~/.bash_completion to include files from ~/.bash_completion.d"
44
+ exit 1
45
+ else
46
+ puts "Completions installed to:"
47
+ installed.each do |path|
48
+ puts " - #{path}"
49
+ end
50
+ puts
51
+ puts "The completions will be reloaded when you start a new shell."
52
+ puts "To load now, use:"
53
+ puts pastel.cyan(" source \"#{COMPLETION_FILE_PATH}\"")
54
+ exit 0
55
+ end
56
+ end
57
+
58
+ def uninstall
59
+ failures = false
60
+ DEFAULT_PATHS.each do |path|
61
+ begin
62
+ if File.exist?(path)
63
+ File.unlink(path)
64
+ puts "Removed #{path}"
65
+ end
66
+ rescue Errno::EACCESS, Errno::EPERM
67
+ failures = true
68
+ warn "Failed to remove #{path} : permission denied"
69
+ end
70
+ end
71
+ exit 1 unless failures
72
+ end
73
+ end
74
+ end
@@ -1,17 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mortar
2
4
  module ClientHelper
3
5
  # @return [K8s::Client]
4
6
  def client
5
- return @client if @client
7
+ @client ||= create_client
8
+ end
6
9
 
10
+ def create_client
7
11
  if ENV['KUBE_TOKEN'] && ENV['KUBE_CA'] && ENV['KUBE_SERVER']
8
- @client = K8s::Client.new(K8s::Transport.config(build_kubeconfig_from_env))
12
+ K8s::Client.new(K8s::Transport.config(build_kubeconfig_from_env))
9
13
  elsif ENV['KUBECONFIG']
10
- @client = K8s::Client.config(K8s::Config.load_file(ENV['KUBECONFIG']))
14
+ K8s::Client.config(K8s::Config.load_file(ENV['KUBECONFIG']))
11
15
  elsif File.exist?(File.join(Dir.home, '.kube', 'config'))
12
- @client = K8s::Client.config(K8s::Config.load_file(File.join(Dir.home, '.kube', 'config')))
16
+ K8s::Client.config(K8s::Config.load_file(File.join(Dir.home, '.kube', 'config')))
13
17
  else
14
- @client = K8s::Client.in_cluster_config
18
+ K8s::Client.in_cluster_config
15
19
  end
16
20
  end
17
21
 
@@ -54,4 +58,4 @@ module Mortar
54
58
  signal_usage_error "KUBE_TOKEN env doesn't seem to be base64 encoded!"
55
59
  end
56
60
  end
57
- end
61
+ end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mortar
2
4
  module ResourceHelper
3
5
  # @param filename [String] file path
4
6
  # @return [Array<K8s::Resource>]
5
7
  def from_files(path)
6
8
  Dir.glob("#{path}/*.{yml,yaml,yml.erb,yaml.erb}").sort.map { |file|
7
- self.from_file(file)
9
+ from_file(file)
8
10
  }.flatten
9
11
  end
10
12
 
@@ -19,14 +21,7 @@ module Mortar
19
21
  end
20
22
 
21
23
  def load_resources(src)
22
- stat = File.stat(src)
23
- if stat.directory?
24
- resources = from_files(src)
25
- else
26
- resources = from_file(src)
27
- end
28
-
29
- resources
24
+ File.directory?(src) ? from_files(src) : from_file(src)
30
25
  end
31
26
 
32
27
  # Checks if the two resource refer to the same resource. Two resources refer to same only if following match:
@@ -37,10 +32,11 @@ module Mortar
37
32
  # @param a [K8s::Resource]
38
33
  # @param b [K8s::Resource]
39
34
  # @return [TrueClass]
40
- def same_resource?(a, b)
41
- return true if a.namespace == b.namespace && a.apiVersion == b.apiVersion && a.kind == b.kind && a.metadata[:name] == b.metadata[:name]
42
-
43
- false
35
+ def same_resource?(resource_a, resource_b)
36
+ resource_a.namespace == resource_b.namespace &&
37
+ resource_a.apiVersion == resource_b.apiVersion &&
38
+ resource_a.kind == resource_b.kind &&
39
+ resource_a.metadata[:name] == resource_b.metadata[:name]
44
40
  end
45
41
  end
46
- end
42
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mortar
2
4
  module TTYHelper
3
5
  # @return [Pastel]
@@ -5,4 +7,4 @@ module Mortar
5
7
  @pastel ||= Pastel.new
6
8
  end
7
9
  end
8
- end
10
+ end
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "clamp"
2
4
  require_relative "fire_command"
3
5
  require_relative "yank_command"
6
+ require_relative "install_completions_command"
4
7
 
5
8
  Clamp.allow_options_after_parameters = true
6
9
 
7
10
  module Mortar
8
11
  class RootCommand < Clamp::Command
9
-
10
12
  banner "mortar - Kubernetes manifest shooter"
11
13
 
12
14
  option ['-v', '--version'], :flag, "print mortar version" do
@@ -16,5 +18,7 @@ module Mortar
16
18
 
17
19
  subcommand "fire", "Fire a shot (of k8s manifests)", FireCommand
18
20
  subcommand "yank", "Yank a shot (of k8s manifests)", YankCommand
21
+
22
+ subcommand "install-completions", "Install shell autocompletions", InstallCompletionsCommand
19
23
  end
20
- end
24
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Mortar
2
- VERSION = "0.2.0.pre5"
4
+ VERSION = "0.2.0.rc1"
3
5
  end
@@ -21,8 +21,7 @@ module Mortar
21
21
 
22
22
  # @param input [String,IO] A IO/File object, a path to a file or string content
23
23
  # @param override_filename [String] use string as the filename for parse errors
24
- # @param force_erb [Boolean] force erb processing even if filename does not end in .yml or is unknown
25
- def initialize(input, override_filename: nil, force_erb: false)
24
+ def initialize(input, override_filename: nil)
26
25
  @filename = override_filename
27
26
  if input.respond_to?(:read)
28
27
  @content = input.read
@@ -31,7 +30,6 @@ module Mortar
31
30
  @filename ||= input.to_s
32
31
  @content = File.read(input)
33
32
  end
34
- @force_erb = force_erb
35
33
  end
36
34
 
37
35
  # @return [Array<Hash>]
@@ -40,6 +38,7 @@ module Mortar
40
38
  if result.is_a?(String)
41
39
  raise ParseError, "File #{"#{@filename} " if @filename}does not appear to be in YAML format"
42
40
  end
41
+
43
42
  result
44
43
  rescue Psych::SyntaxError => ex
45
44
  raise ParseError, ex.message
@@ -54,25 +53,11 @@ module Mortar
54
53
  end
55
54
 
56
55
  def read(variables = {})
57
- erb? ? erb_result(variables) : @content
58
- end
59
-
60
- def erb_result(variables = {})
61
56
  Namespace.new(variables).with_binding do |ns_binding|
62
57
  ERB.new(@content, nil, '%<>-').tap { |e| e.location = [@filename, nil] }.result(ns_binding)
63
58
  end
64
59
  rescue StandardError, ScriptError => ex
65
60
  raise ParseError, "#{ex.class.name} : #{ex.message} (#{ex.backtrace.first.gsub(/:in `with_binding'/, '')})"
66
61
  end
67
-
68
- private
69
-
70
- def erb?
71
- force_erb? || @filename&.end_with?('.erb')
72
- end
73
-
74
- def force_erb?
75
- @force_erb
76
- end
77
62
  end
78
63
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "command"
2
4
  require_relative "mixins/client_helper"
3
5
  require_relative "mixins/tty_helper"
@@ -19,8 +21,7 @@ module Mortar
19
21
  signal_error("confirmation did not match #{pastel.cyan(name)}.") unless $stdin.gets.chomp == name
20
22
  rescue Interrupt
21
23
  puts
22
- puts "Canceled"
23
- return
24
+ abort 'Canceled'
24
25
  end
25
26
  else
26
27
  signal_usage_error '--force required when running in a non-interactive mode'
@@ -37,4 +38,4 @@ module Mortar
37
38
  puts "yanked #{pastel.cyan(name)} successfully!" if $stdout.tty?
38
39
  end
39
40
  end
40
- end
41
+ end
@@ -0,0 +1,41 @@
1
+ if [[ -n ${ZSH_VERSION-} ]]; then
2
+ autoload -U +X bashcompinit && bashcompinit
3
+ fi
4
+
5
+ _mortar () {
6
+ local cur prev ret
7
+ COMPREPLY=()
8
+ cur="${COMP_WORDS[COMP_CWORD]}"
9
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
10
+
11
+ if [ "$COMP_CWORD" = "1" ]; then
12
+ if [[ ${cur} == -* ]] ; then
13
+ COMPREPLY=( $(compgen -W "--help --version" -- ${cur}) )
14
+ return
15
+ fi
16
+
17
+ COMPREPLY=( $(compgen -W "fire yank" -- ${cur}) )
18
+ return
19
+ else
20
+ case "${COMP_WORDS[1]}" in
21
+ fire)
22
+ if [[ ${cur} == -* ]] ; then
23
+ COMPREPLY=( $(compgen -W "--var --output --prune --overlay --force --debug --help" -- ${cur}) )
24
+ elif [ "$prev" = "--overlay" ]; then
25
+ if command -v compopt &> /dev/null; then
26
+ COMPREPLY=( $(compgen -d -S "/" -- "${COMP_WORDS[COMP_CWORD]}") )
27
+ compopt -o nospace
28
+ fi
29
+ fi
30
+ ;;
31
+ yank)
32
+ if [[ ${cur} == -* ]] ; then
33
+ COMPREPLY=( $(compgen -W "--force --debug --help" -- ${cur}) )
34
+ fi
35
+ ;;
36
+ esac
37
+ fi
38
+ }
39
+
40
+ complete -o default -F _mortar mortar
41
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kontena-mortar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre5
4
+ version: 0.2.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kontena, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-13 00:00:00.000000000 Z
11
+ date: 2018-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clamp
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.4.1
33
+ version: 0.4.2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.4.1
40
+ version: 0.4.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rouge
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.57'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.57'
125
139
  description: Kubernetes manifest shooter
126
140
  email:
127
141
  - info@kontena.io
@@ -133,6 +147,8 @@ files:
133
147
  - ".drone.yml"
134
148
  - ".gitignore"
135
149
  - ".rspec"
150
+ - ".rubocop.relaxed.yml"
151
+ - ".rubocop.yml"
136
152
  - ".travis.yml"
137
153
  - Dockerfile
138
154
  - Gemfile
@@ -161,6 +177,7 @@ files:
161
177
  - lib/mortar.rb
162
178
  - lib/mortar/command.rb
163
179
  - lib/mortar/fire_command.rb
180
+ - lib/mortar/install_completions_command.rb
164
181
  - lib/mortar/mixins/client_helper.rb
165
182
  - lib/mortar/mixins/resource_helper.rb
166
183
  - lib/mortar/mixins/tty_helper.rb
@@ -168,11 +185,14 @@ files:
168
185
  - lib/mortar/version.rb
169
186
  - lib/mortar/yaml_file.rb
170
187
  - lib/mortar/yank_command.rb
188
+ - opt/bash-completion.sh
171
189
  homepage: https://github.com/kontena/mortar
172
190
  licenses:
173
191
  - Apache-2.0
174
192
  metadata: {}
175
- post_install_message:
193
+ post_install_message: |-
194
+ To install shell auto-completions, use:
195
+ mortar install-completions
176
196
  rdoc_options: []
177
197
  require_paths:
178
198
  - lib