opswalrus 1.0.32 → 1.0.34
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/Gemfile.lock +5 -1
- data/README.md +3 -1
- data/lib/opswalrus/bootstrap.sh +1 -1
- data/lib/opswalrus/cli.rb +4 -4
- data/lib/opswalrus/host.rb +29 -1
- data/lib/opswalrus/operation_runner.rb +29 -4
- data/lib/opswalrus/ops_file_script_dsl.rb +27 -2
- data/lib/opswalrus/version.rb +1 -1
- data/lib/opswalrus/walrus_lang.rb +18 -6
- data/opswalrus.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab3f1e696e7425c7caf84aff75bc525f01d1e9d8a3f710ca16c22a1c33a17d7b
|
4
|
+
data.tar.gz: 5ee348372ba6f0ae7263277ed0a5e1e22164dbeb2c0efa2db273aefa7432007d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5fb03f7d54471d7148e9d96139a7e7f31d90aa9eaca9001f22084ccd5ab6ced80020b08f7bfdfe6aa64e74d56624e336383e06082c95d61b76f808b0167dffe
|
7
|
+
data.tar.gz: 6f8cfdbb284d986e2db323ed668dfd6546dd52dbad8ac838229d41e21a8d6b6db836df171178d297b19ffea0f88e8ce9a37edb2b6514d1ba4c38e8413c64414f
|
data/Dockerfile
CHANGED
@@ -16,7 +16,7 @@ COPY Gemfile Gemfile.lock opswalrus.gemspec ./
|
|
16
16
|
COPY lib/opswalrus/version.rb /opswalrus/lib/opswalrus/version.rb
|
17
17
|
|
18
18
|
# Install system dependencies
|
19
|
-
RUN apk add --no-cache --update build-base git docker openrc openssh-client-default \
|
19
|
+
RUN apk add --no-cache --update build-base git docker openrc openssh-client-default age \
|
20
20
|
&& rc-update add docker boot \
|
21
21
|
&& gem install bundler --version=2.4.3 \
|
22
22
|
&& bundle install
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
opswalrus (1.0.
|
4
|
+
opswalrus (1.0.34)
|
5
5
|
amazing_print (~> 1.5)
|
6
6
|
bcrypt_pbkdf (~> 1.1)
|
7
|
+
binding_of_caller (~> 1.0)
|
7
8
|
citrus (~> 3.0)
|
8
9
|
ed25519 (~> 1.3)
|
9
10
|
git (~> 1.18)
|
@@ -21,8 +22,11 @@ GEM
|
|
21
22
|
public_suffix (>= 2.0.2, < 6.0)
|
22
23
|
amazing_print (1.5.0)
|
23
24
|
bcrypt_pbkdf (1.1.0)
|
25
|
+
binding_of_caller (1.0.0)
|
26
|
+
debug_inspector (>= 0.0.1)
|
24
27
|
citrus (3.0.2)
|
25
28
|
concurrent-ruby (1.2.2)
|
29
|
+
debug_inspector (1.1.0)
|
26
30
|
diff-lcs (1.5.0)
|
27
31
|
ed25519 (1.3.0)
|
28
32
|
git (1.18.0)
|
data/README.md
CHANGED
@@ -19,8 +19,10 @@ You have two options:
|
|
19
19
|
|
20
20
|
## Docker install
|
21
21
|
|
22
|
+
The path to whatever directory you store your age identity files in should be used in place of `$HOME/.secrets/age` in the following shell alias:
|
23
|
+
|
22
24
|
```shell
|
23
|
-
❯ alias ops='docker run --rm -it -v $HOME/.ssh:/root/.ssh -v /var/run/docker.sock:/var/run/docker.sock -v ${PWD}/:/workdir ghcr.io/opswalrus/ops'
|
25
|
+
❯ alias ops='docker run --rm -it -v $HOME/.secrets/age:/root/.secrets -e OPSWALRUS_AGE_IDS="/root/.secrets/*.priv" -v $HOME/.ssh:/root/.ssh -v /var/run/docker.sock:/var/run/docker.sock -v ${PWD}/:/workdir ghcr.io/opswalrus/ops'
|
24
26
|
|
25
27
|
❯ ops version
|
26
28
|
1.0.13
|
data/lib/opswalrus/bootstrap.sh
CHANGED
@@ -14,7 +14,7 @@ GEM_CMD=$RTX_GEM
|
|
14
14
|
|
15
15
|
if [ -x $RTX ]; then
|
16
16
|
# rtx_init;
|
17
|
-
# eval "$(
|
17
|
+
# eval "$(rtx activate bash)"
|
18
18
|
# if brew is already installed, initialize this shell environment with brew
|
19
19
|
# if [ -x "$(command -v /home/linuxbrew/.linuxbrew/bin/brew)" ]; then
|
20
20
|
if $RUBY_CMD -e "major, minor, patch = RUBY_VERSION.split('.'); exit 1 unless major.to_i >= 3"; then
|
data/lib/opswalrus/cli.rb
CHANGED
@@ -72,7 +72,7 @@ module OpsWalrus
|
|
72
72
|
|
73
73
|
desc 'Edit hosts in inventory'
|
74
74
|
long_desc 'Edit the hosts in the inventory and their secrets'
|
75
|
-
#
|
75
|
+
# arg 'hosts_file', :optional
|
76
76
|
c.command :edit do |edit|
|
77
77
|
edit.action do |global_options, options, args|
|
78
78
|
file_path = global_options[:hosts].first || HostsFile::DEFAULT_FILE_NAME
|
@@ -87,7 +87,7 @@ module OpsWalrus
|
|
87
87
|
|
88
88
|
desc 'Encrypt secrets in inventory file'
|
89
89
|
long_desc 'Encrypt secrets in inventory file'
|
90
|
-
|
90
|
+
arg 'encrypted_host_file_path', :optional
|
91
91
|
c.command :encrypt do |encrypt|
|
92
92
|
encrypt.action do |global_options, options, args|
|
93
93
|
file_path = global_options[:hosts].first || HostsFile::DEFAULT_FILE_NAME
|
@@ -104,7 +104,7 @@ module OpsWalrus
|
|
104
104
|
|
105
105
|
desc 'Decrypt secrets in inventory file'
|
106
106
|
long_desc 'Decrypt secrets in inventory file'
|
107
|
-
|
107
|
+
arg 'decrypted_host_file_path', :optional
|
108
108
|
c.command :decrypt do |decrypt|
|
109
109
|
decrypt.action do |global_options, options, args|
|
110
110
|
file_path = global_options[:hosts].first || HostsFile::DEFAULT_FILE_NAME
|
@@ -154,7 +154,7 @@ module OpsWalrus
|
|
154
154
|
|
155
155
|
desc 'Run an operation from a package'
|
156
156
|
long_desc 'Run the specified operation found within the specified package'
|
157
|
-
|
157
|
+
arg 'args', :multiple
|
158
158
|
command :run do |c|
|
159
159
|
c.flag [:u, :user], desc: "Specify the user that the operation will run as"
|
160
160
|
c.switch :pass, desc: "Prompt for a sudo password"
|
data/lib/opswalrus/host.rb
CHANGED
@@ -124,12 +124,20 @@ module OpsWalrus
|
|
124
124
|
|
125
125
|
|
126
126
|
module HostDSL
|
127
|
+
# runs the given command
|
127
128
|
# returns the stdout from the command
|
128
129
|
def sh(desc_or_cmd = nil, cmd = nil, input: nil, &block)
|
129
130
|
out, err, status = *shell!(desc_or_cmd, cmd, block, input: input)
|
130
131
|
out
|
131
132
|
end
|
132
133
|
|
134
|
+
# runs the given command
|
135
|
+
# returns true if the exit status was success; false otherwise
|
136
|
+
def sh?(desc_or_cmd = nil, cmd = nil, input: nil, &block)
|
137
|
+
out, err, status = *shell!(desc_or_cmd, cmd, block, input: input)
|
138
|
+
status == 0
|
139
|
+
end
|
140
|
+
|
133
141
|
# returns the tuple: [stdout, stderr, exit_status]
|
134
142
|
def shell(desc_or_cmd = nil, cmd = nil, input: nil, &block)
|
135
143
|
shell!(desc_or_cmd, cmd, block, input: input)
|
@@ -146,7 +154,19 @@ module OpsWalrus
|
|
146
154
|
cmd = block.call if block
|
147
155
|
cmd ||= desc_or_cmd
|
148
156
|
|
149
|
-
cmd =
|
157
|
+
cmd = if cmd =~ /{{.*}}/
|
158
|
+
if block
|
159
|
+
WalrusLang.render(cmd, block.binding)
|
160
|
+
else
|
161
|
+
offset = 3 # 3, because 1 references the stack frame corresponding to the caller of WalrusLang.eval,
|
162
|
+
# 2 references the stack frame corresponding to the caller of shell!,
|
163
|
+
# and 3 references the stack frame corresponding to teh caller of either sh/sh?/shell
|
164
|
+
WalrusLang.eval(cmd, offset)
|
165
|
+
end
|
166
|
+
else
|
167
|
+
cmd
|
168
|
+
end
|
169
|
+
# cmd = WalrusLang.render(cmd, block.binding) if block && cmd =~ /{{.*}}/
|
150
170
|
|
151
171
|
#cmd = Shellwords.escape(cmd)
|
152
172
|
|
@@ -203,6 +223,14 @@ module OpsWalrus
|
|
203
223
|
shell!(cmd)
|
204
224
|
end
|
205
225
|
|
226
|
+
def desc(msg)
|
227
|
+
puts msg.mustache
|
228
|
+
end
|
229
|
+
|
230
|
+
def host_prop(name)
|
231
|
+
@props["name"]
|
232
|
+
end
|
233
|
+
|
206
234
|
end
|
207
235
|
|
208
236
|
class Host
|
@@ -37,22 +37,47 @@ module OpsWalrus
|
|
37
37
|
key, value = str_value.split(":", 2)
|
38
38
|
if pre_existing_value = memo[param_name]
|
39
39
|
memo[param_name] = if value # we're dealing with a Hash parameter value
|
40
|
-
pre_existing_value.merge(key => value)
|
40
|
+
pre_existing_value.merge(key => try_convert(value))
|
41
41
|
else # we're dealing with an Array parameter value or a scalar parameter value
|
42
42
|
array = pre_existing_value.is_a?(Array) ? pre_existing_value : [pre_existing_value]
|
43
|
-
array << str_value
|
43
|
+
array << try_convert(str_value)
|
44
44
|
end
|
45
45
|
else
|
46
46
|
memo[param_name] = if value # we're dealing with a Hash parameter value
|
47
|
-
{key => value}
|
47
|
+
{key => try_convert(value)}
|
48
48
|
else # we're dealing with an Array parameter value or a scalar parameter value
|
49
|
-
str_value
|
49
|
+
try_convert(str_value)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
memo
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
+
def try_convert(value)
|
57
|
+
case value.downcase
|
58
|
+
when 'true'
|
59
|
+
true
|
60
|
+
when 'false'
|
61
|
+
false
|
62
|
+
when /^[0-9]+$/
|
63
|
+
value.to_i
|
64
|
+
when /^[0-9]+\.[0-9]+$/
|
65
|
+
value.to_f
|
66
|
+
else
|
67
|
+
value
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# def try_convert(value)
|
72
|
+
# if value.is_a? String
|
73
|
+
# JSON.parse(value)
|
74
|
+
# else
|
75
|
+
# value
|
76
|
+
# end
|
77
|
+
# rescue JSON::ParserError => e
|
78
|
+
# value
|
79
|
+
# end
|
80
|
+
|
56
81
|
# runtime_kv_args is an Array(String) of the form: ["arg1:val1", "arg1:val2", ...]
|
57
82
|
# params_json_hash is a Hash representation of a JSON string
|
58
83
|
def run(runtime_kv_args, params_json_hash: nil)
|
@@ -162,7 +162,7 @@ module OpsWalrus
|
|
162
162
|
|
163
163
|
def exit(exit_status, message = nil)
|
164
164
|
if message
|
165
|
-
puts message
|
165
|
+
puts message.mustache(3)
|
166
166
|
end
|
167
167
|
result = if exit_status == 0
|
168
168
|
Invocation::Success.new(nil)
|
@@ -207,12 +207,24 @@ module OpsWalrus
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
+
def desc(msg)
|
211
|
+
puts msg.mustache
|
212
|
+
end
|
213
|
+
|
214
|
+
# runs the given command
|
210
215
|
# returns the stdout from the command
|
211
216
|
def sh(desc_or_cmd = nil, cmd = nil, input: nil, &block)
|
212
217
|
out, err, status = *shell!(desc_or_cmd, cmd, block, input: input)
|
213
218
|
out
|
214
219
|
end
|
215
220
|
|
221
|
+
# runs the given command
|
222
|
+
# returns true if the exit status was success; false otherwise
|
223
|
+
def sh?(desc_or_cmd = nil, cmd = nil, input: nil, &block)
|
224
|
+
out, err, status = *shell!(desc_or_cmd, cmd, block, input: input)
|
225
|
+
status == 0
|
226
|
+
end
|
227
|
+
|
216
228
|
# returns the tuple: [stdout, stderr, exit_status]
|
217
229
|
def shell(desc_or_cmd = nil, cmd = nil, input: nil, &block)
|
218
230
|
shell!(desc_or_cmd, cmd, block, input: input)
|
@@ -229,7 +241,20 @@ module OpsWalrus
|
|
229
241
|
cmd = block.call if block
|
230
242
|
cmd ||= desc_or_cmd
|
231
243
|
|
232
|
-
cmd =
|
244
|
+
cmd = if cmd =~ /{{.*}}/
|
245
|
+
if block
|
246
|
+
WalrusLang.render(cmd, block.binding)
|
247
|
+
else
|
248
|
+
offset = 3 # 3, because 1 references the stack frame corresponding to the caller of WalrusLang.eval,
|
249
|
+
# 2 references the stack frame corresponding to the caller of shell!,
|
250
|
+
# and 3 references the stack frame corresponding to teh caller of either sh/sh?/shell
|
251
|
+
WalrusLang.eval(cmd, offset)
|
252
|
+
end
|
253
|
+
else
|
254
|
+
cmd
|
255
|
+
end
|
256
|
+
# cmd = WalrusLang.eval(cmd) if !block && cmd =~ /{{.*}}/
|
257
|
+
# cmd = WalrusLang.render(cmd, block.binding) if block && cmd =~ /{{.*}}/
|
233
258
|
|
234
259
|
#cmd = Shellwords.escape(cmd)
|
235
260
|
|
data/lib/opswalrus/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "binding_of_caller"
|
1
2
|
require "citrus"
|
2
3
|
require "ostruct"
|
3
4
|
require "stringio"
|
@@ -61,12 +62,21 @@ module WalrusLang
|
|
61
62
|
ast = WalrusLang::Parser.parse(template)
|
62
63
|
ast.render(binding_obj)
|
63
64
|
end
|
65
|
+
|
66
|
+
def self.eval(template_string, bindings_from_stack_frame_offset = 1)
|
67
|
+
binding_from_earlier_stack_frame = binding.of_caller(bindings_from_stack_frame_offset)
|
68
|
+
template_string =~ /{{.*}}/ ? WalrusLang.render(template_string, binding_from_earlier_stack_frame) : template_string
|
69
|
+
end
|
64
70
|
end
|
65
71
|
|
66
72
|
class String
|
67
73
|
def render_template(hash)
|
68
74
|
WalrusLang.render(self, hash)
|
69
75
|
end
|
76
|
+
|
77
|
+
def mustache(bindings_from_stack_frame_offset = 2)
|
78
|
+
WalrusLang.eval(self, bindings_from_stack_frame_offset)
|
79
|
+
end
|
70
80
|
end
|
71
81
|
|
72
82
|
class Hash
|
@@ -81,11 +91,6 @@ class Binding
|
|
81
91
|
end
|
82
92
|
end
|
83
93
|
|
84
|
-
def mustache(&block)
|
85
|
-
template_string = block.call
|
86
|
-
template_string =~ /{{.*}}/ ? WalrusLang.render(template_string, block.binding) : template_string
|
87
|
-
end
|
88
|
-
|
89
94
|
|
90
95
|
# foo = 1
|
91
96
|
# bar = 2
|
@@ -95,4 +100,11 @@ end
|
|
95
100
|
# # puts m.dump
|
96
101
|
# puts m.render(binding)
|
97
102
|
|
98
|
-
# puts(
|
103
|
+
# puts("abc {{ 1 + 2 }} def".mustache)
|
104
|
+
|
105
|
+
# irb(main):096:0> a=5
|
106
|
+
# => 5
|
107
|
+
# irb(main):097:0> b=8
|
108
|
+
# => 8
|
109
|
+
# irb(main):098:0> "abc {{ a + b }} def".mustache
|
110
|
+
# => "abc 13 def"
|
data/opswalrus.gemspec
CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
|
34
34
|
# gem dependencies
|
35
35
|
spec.add_dependency "amazing_print", "~> 1.5"
|
36
|
+
spec.add_dependency "binding_of_caller", "~> 1.0"
|
36
37
|
spec.add_dependency "citrus", "~> 3.0"
|
37
38
|
spec.add_dependency "gli", "~> 2.21"
|
38
39
|
spec.add_dependency "git", "~> 1.18"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opswalrus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.34
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Ellis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: amazing_print
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: binding_of_caller
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: citrus
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|