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 +4 -4
- data/.drone.yml +1 -0
- data/.rubocop.relaxed.yml +166 -0
- data/.rubocop.yml +57 -0
- data/Gemfile.lock +22 -4
- data/README.md +16 -6
- data/Rakefile +3 -1
- data/kontena-mortar.gemspec +5 -1
- data/lib/extensions/recursive_open_struct/each.rb +5 -3
- data/lib/mortar.rb +5 -1
- data/lib/mortar/command.rb +3 -1
- data/lib/mortar/fire_command.rb +5 -3
- data/lib/mortar/install_completions_command.rb +74 -0
- data/lib/mortar/mixins/client_helper.rb +10 -6
- data/lib/mortar/mixins/resource_helper.rb +10 -14
- data/lib/mortar/mixins/tty_helper.rb +3 -1
- data/lib/mortar/root_command.rb +6 -2
- data/lib/mortar/version.rb +3 -1
- data/lib/mortar/yaml_file.rb +2 -17
- data/lib/mortar/yank_command.rb +4 -3
- data/opt/bash-completion.sh +41 -0
- metadata +25 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cff0530a854b482030dadc4223cac97233b85b1a4e15625a0ec5483c641446b2
|
4
|
+
data.tar.gz: 5204676edc234f73e953068d2392ef8390898adcde8642c79579a182cd10efc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ce686d74349ecdb2229e42d9effc248ceb72902ceaa71b3dbe570ae2789729e194c44336969a86429b34251b50bca07a617362b7eb730d89375b7364bcde3b6
|
7
|
+
data.tar.gz: 0bba3e81223eca4342f5e601b4ae82229cf14e44b0b18fe7acba17ca7ac9887a0e469e73afb7d58d5eaaec9f866d130519067dac84eec0c99763692b17acf630
|
data/.drone.yml
CHANGED
@@ -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
|
+
|
data/.rubocop.yml
ADDED
@@ -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
|
data/Gemfile.lock
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
kontena-mortar (0.2.0.
|
4
|
+
kontena-mortar (0.2.0.rc1)
|
5
5
|
clamp (~> 1.3)
|
6
6
|
deep_merge (~> 1.2)
|
7
|
-
k8s-client (~> 0.4.
|
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
|
-
|
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.
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
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
data/kontena-mortar.gemspec
CHANGED
@@ -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.
|
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
|
5
|
-
|
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
|
data/lib/mortar.rb
CHANGED
@@ -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
|
data/lib/mortar/command.rb
CHANGED
data/lib/mortar/fire_command.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
12
|
+
K8s::Client.new(K8s::Transport.config(build_kubeconfig_from_env))
|
9
13
|
elsif ENV['KUBECONFIG']
|
10
|
-
|
14
|
+
K8s::Client.config(K8s::Config.load_file(ENV['KUBECONFIG']))
|
11
15
|
elsif File.exist?(File.join(Dir.home, '.kube', 'config'))
|
12
|
-
|
16
|
+
K8s::Client.config(K8s::Config.load_file(File.join(Dir.home, '.kube', 'config')))
|
13
17
|
else
|
14
|
-
|
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
|
-
|
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
|
-
|
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?(
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
data/lib/mortar/root_command.rb
CHANGED
@@ -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
|
data/lib/mortar/version.rb
CHANGED
data/lib/mortar/yaml_file.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/mortar/yank_command.rb
CHANGED
@@ -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
|
-
|
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.
|
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-
|
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.
|
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.
|
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
|