opswalrus 1.0.77 → 1.0.78

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c19f0877541baca3fa57340c300382e8819e56d9bfc2225ca1f4a888c0df9fb6
4
- data.tar.gz: 279d36f24ff0861115ca06e4201d907c84082b764f308faceee9c9c4420a2ef2
3
+ metadata.gz: 13215ff324f0411cb258d2bb9228d4e6ab5a99bdab79d81fa13206063f3ab66c
4
+ data.tar.gz: 1ff2f044c230528bd3fa94ee3070380f6b5943bf1d8495bc608460f52128abbc
5
5
  SHA512:
6
- metadata.gz: 54b958066621d691e460702e41388b76c34c3a9cc379f1fe431e52f70509c581a81f8d1a9d7c11ea15f5d5406c5862659534b5c7b18aa086494e0ac3a2b5c564
7
- data.tar.gz: 0771e13131d4db57fdc9f730ed80a286aaaf80409b35cdbdfe2091c0e80b35d321ccba1fbad6c89a6ce28438207330bbd944833618aef762ab42fb6ab7b98641
6
+ metadata.gz: afcaa074c96bf612c7c51c75199ff18d0de8988bbb7037068736533f272f83b39fa18501278586037abfd6c64a49ff41f6c1d344028bc373b4381ab6239f1255
7
+ data.tar.gz: 2d87b71f172c144010f29e625a82d7c10628c11684cc75c9686accc8392b24ff8e4c81f05df8d2ce3ed02497171faacbb59c0821a588563902d5623d4d58ae69
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in opswalrus.gemspec
6
6
  gemspec
7
7
 
8
+ # gem "kleene", path: '../../kleene-rb'
8
9
  gem "rake", "~> 13.0"
9
10
  gem "rspec", "~> 3.0"
10
11
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- opswalrus (1.0.77)
4
+ opswalrus (1.0.78)
5
5
  activesupport (~> 7.0)
6
6
  bcrypt_pbkdf (~> 1.1)
7
7
  binding_of_caller (~> 1.0)
@@ -9,6 +9,7 @@ PATH
9
9
  ed25519 (~> 1.3)
10
10
  git (~> 1.18)
11
11
  gli (~> 2.21)
12
+ kleene
12
13
  pastel (~> 0.8)
13
14
  rubyzip (~> 2.3)
14
15
  semantic_logger (~> 4.13)
@@ -32,9 +33,9 @@ GEM
32
33
  public_suffix (>= 2.0.2, < 6.0)
33
34
  ast (2.4.2)
34
35
  backport (1.2.0)
35
- base64 (0.1.1)
36
+ base64 (0.2.0)
36
37
  bcrypt_pbkdf (1.1.0)
37
- benchmark (0.2.1)
38
+ benchmark (0.3.0)
38
39
  bigdecimal (3.1.4)
39
40
  binding_of_caller (1.0.0)
40
41
  debug_inspector (>= 0.0.1)
@@ -43,7 +44,7 @@ GEM
43
44
  connection_pool (2.4.1)
44
45
  debug_inspector (1.1.0)
45
46
  diff-lcs (1.5.0)
46
- drb (2.1.1)
47
+ drb (2.2.0)
47
48
  ruby2_keywords
48
49
  e2mmap (0.1.0)
49
50
  ed25519 (1.3.0)
@@ -55,13 +56,16 @@ GEM
55
56
  concurrent-ruby (~> 1.0)
56
57
  jaro_winkler (1.5.6)
57
58
  json (2.6.3)
59
+ kleene (0.8.0)
60
+ activesupport (~> 7.1)
61
+ regexp_parser (~> 2.8)
58
62
  kramdown (2.4.0)
59
63
  rexml
60
64
  kramdown-parser-gfm (1.1.0)
61
65
  kramdown (~> 2.0)
62
66
  language_server-protocol (3.17.0.3)
63
67
  minitest (5.20.0)
64
- mutex_m (0.1.2)
68
+ mutex_m (0.2.0)
65
69
  net-scp (4.0.0)
66
70
  net-ssh (>= 2.6.5, < 8.0.0)
67
71
  net-ssh (7.2.0)
@@ -74,7 +78,7 @@ GEM
74
78
  pastel (0.8.0)
75
79
  tty-color (~> 0.5)
76
80
  public_suffix (5.0.3)
77
- racc (1.7.2)
81
+ racc (1.7.3)
78
82
  rainbow (3.1.1)
79
83
  rake (13.1.0)
80
84
  rbs (2.8.4)
data/cli2.rb ADDED
@@ -0,0 +1,88 @@
1
+ require 'tty-option'
2
+
3
+ class Command
4
+ include TTY::Option
5
+
6
+ usage do
7
+ program "dock"
8
+
9
+ command "run"
10
+
11
+ desc "Run a command in a new container"
12
+
13
+ example "Set working directory (-w)",
14
+ " $ dock run -w /path/to/dir/ ubuntu pwd"
15
+
16
+ example <<~EOS
17
+ Mount volume
18
+ $ dock run -v `pwd`:`pwd` -w `pwd` ubuntu pwd
19
+ EOS
20
+ end
21
+
22
+ argument :image do
23
+ required
24
+ desc "The name of the image to use"
25
+ end
26
+
27
+ argument :command do
28
+ optional
29
+ desc "The command to run inside the image"
30
+ end
31
+
32
+ keyword :restart do
33
+ default "no"
34
+ permit %w[no on-failure always unless-stopped]
35
+ desc "Restart policy to apply when a container exits"
36
+ end
37
+
38
+ option :verbose do
39
+ arity "+"
40
+ short "-v"
41
+ desc "Verbose mode"
42
+ end
43
+
44
+ flag :detach do
45
+ short "-d"
46
+ long "--detach"
47
+ desc "Run container in background and print container ID"
48
+ end
49
+
50
+ flag :help do
51
+ short "-h"
52
+ long "--help"
53
+ desc "Print usage"
54
+ end
55
+
56
+ option :name do
57
+ required
58
+ long "--name string"
59
+ desc "Assign a name to the container"
60
+ end
61
+
62
+ option :port do
63
+ arity one_or_more
64
+ short "-p"
65
+ long "--publish list"
66
+ convert :list
67
+ desc "Publish a container's port(s) to the host"
68
+ end
69
+
70
+ def run
71
+ puts params[:verbose].inspect
72
+ if params[:help]
73
+ print help
74
+ elsif params.errors.any?
75
+ puts params.errors.summary
76
+ else
77
+ pp params.to_h
78
+ end
79
+ end
80
+ end
81
+
82
+ def main
83
+ cmd = Command.new
84
+ cmd.parse
85
+ puts cmd.run
86
+ end
87
+
88
+ main
@@ -255,7 +255,7 @@ module OpsWalrus
255
255
  if App.instance.info? # this is true if log_level is trace, debug, info
256
256
  io.print Style.blue(host)
257
257
  io.print " (#{Style.blue(self.alias)})" if self.alias
258
- io.print " | #{Style.magenta(description)}" if description
258
+ io.print " | #{Style.green(description)}" if description
259
259
  io.puts
260
260
  io.print Style.yellow(cmd_id)
261
261
  io.print Style.green.bold(" > ")
@@ -263,7 +263,7 @@ module OpsWalrus
263
263
  elsif App.instance.warn? && description
264
264
  io.print Style.blue(host)
265
265
  io.print " (#{Style.blue(self.alias)})" if self.alias
266
- io.print " | #{Style.magenta(description)}" if description
266
+ io.print " | #{Style.green(description)}" if description
267
267
  io.puts
268
268
  end
269
269
  io.string
@@ -1,3 +1,4 @@
1
+ require 'kleene'
1
2
  require 'sshkit'
2
3
 
3
4
  module OpsWalrus
@@ -8,8 +9,9 @@ module OpsWalrus
8
9
 
9
10
  attr_accessor :input_mappings # Hash[ String | Regex => (String | Proc) ]
10
11
 
11
- def initialize(mapping)
12
- @input_mappings = mapping
12
+ def initialize(mappings, lookback_window_chars = 200)
13
+ @input_mappings = mappings
14
+ @online_matcher = Kleene::NaiveOnlineRegex.new(mappings.keys, lookback_window_chars)
13
15
  end
14
16
 
15
17
  # sudo_password : String | Nil
@@ -40,8 +42,8 @@ module OpsWalrus
40
42
  # when the given block returns, then the temporary mapping is removed from the interaction handler
41
43
  #
42
44
  # mapping : Hash[ String | Regex => (String | Proc) ] | Nil
43
- def with_mapping(mapping = nil, sudo_password: nil, ops_sudo_password: nil, inherit_existing_mappings: true)
44
- new_mapping = inherit_existing_mappings ? @input_mappings : {}
45
+ def with_mapping(mapping = nil, sudo_password: nil, ops_sudo_password: nil, inherit_existing_mappings: true, lookback_window_chars: 200)
46
+ new_mapping = inherit_existing_mappings ? @input_mappings.clone : {}
45
47
 
46
48
  if mapping
47
49
  raise ArgumentError.new("mapping must be a Hash") unless mapping.is_a?(Hash)
@@ -58,19 +60,26 @@ module OpsWalrus
58
60
  end
59
61
  new_mapping.merge!(password_mappings) if password_mappings
60
62
 
63
+ # trace(Style.green("mapping: #{mapping}"))
64
+ # trace(Style.green("new_mapping: #{new_mapping}"))
65
+ # trace(Style.green("new_mapping.empty?: #{new_mapping.empty?}"))
66
+ # trace(Style.green("new_mapping == @input_mappings: #{new_mapping == @input_mappings}"))
61
67
  if new_mapping.empty? || new_mapping == @input_mappings
68
+ trace(Style.red("with_mapping -> reset"))
69
+ @online_matcher.reset
62
70
  yield self
63
71
  else
64
- yield ScopedMappingInteractionHandler.new(new_mapping)
72
+ trace(Style.red("with_mapping -> new mapping"))
73
+ yield ScopedMappingInteractionHandler.new(new_mapping, lookback_window_chars)
65
74
  end
66
75
  end
67
76
 
68
77
  # adds the specified input mapping to the interaction handler
69
78
  #
70
79
  # mapping : Hash[ String | Regex => (String | Proc) ]
71
- def add_mapping(mapping)
72
- @input_mappings.merge!(mapping)
73
- end
80
+ # def add_mapping(mapping)
81
+ # @input_mappings.merge!(mapping)
82
+ # end
74
83
 
75
84
  # cmd, :stdout, data, stdin
76
85
  # the return value from on_data is returned to Command#call_interaction_handler which is then returned verbatim
@@ -84,17 +93,33 @@ module OpsWalrus
84
93
  # This method returns the data that is emitted to the response channel as a result of having processed the output
85
94
  # from a command that the interaction handler was expecting.
86
95
  def on_data(_command, stream_name, data, response_channel)
87
- response_data = @input_mappings.find_map do |pattern, mapped_output_value|
88
- pattern = pattern.is_a?(String) ? Regexp.new(Regexp.escape(pattern)) : pattern
89
- if pattern_match = data.match(pattern) # pattern_match : MatchData | Nil
90
- case mapped_output_value
91
- when Proc, Method
92
- mapped_output_value.call(pattern_match)
93
- when String
94
- mapped_output_value
95
- end
96
+ # trace(Style.yellow("regexen=#{@online_matcher.instance_exec { @regexen } }"))
97
+ # trace(Style.yellow("data=`#{data}`"))
98
+ # trace(Style.yellow("buffer=#{@online_matcher.instance_exec { @buffer } }"))
99
+ new_matches = @online_matcher.ingest(data)
100
+ # trace(Style.yellow("new_matches=`#{new_matches}`"))
101
+ response_data = new_matches.find_map do |online_match|
102
+ mapped_output_value = @input_mappings[online_match.regex]
103
+ case mapped_output_value
104
+ when Proc, Method
105
+ mapped_output_value.call(online_match.match)
106
+ when String
107
+ mapped_output_value
96
108
  end
97
109
  end
110
+ # trace(Style.yellow("response_data=`#{response_data.inspect}`"))
111
+
112
+ # response_data = @input_mappings.find_map do |pattern, mapped_output_value|
113
+ # pattern = pattern.is_a?(String) ? Regexp.new(Regexp.escape(pattern)) : pattern
114
+ # if pattern_match = data.match(pattern) # pattern_match : MatchData | Nil
115
+ # case mapped_output_value
116
+ # when Proc, Method
117
+ # mapped_output_value.call(pattern_match)
118
+ # when String
119
+ # mapped_output_value
120
+ # end
121
+ # end
122
+ # end
98
123
 
99
124
  if response_data.nil?
100
125
  trace(Style.red("No interaction handler mapping for #{stream_name}: `#{data}` so no response was sent"))
@@ -294,7 +294,7 @@ module OpsWalrus
294
294
  if App.instance.dry_run?
295
295
  ["", "", 0]
296
296
  else
297
- sshkit_cmd = @runtime_env.handle_input(input, inherit_existing_mappings: true) do |interaction_handler|
297
+ sshkit_cmd = @runtime_env.handle_input(input, inherit_existing_mappings: true, lookback_window_chars: 200) do |interaction_handler|
298
298
  # puts "self=#{self.class.superclass}"
299
299
  # self is an instance of one of the dynamically defined subclasses of OpsFileScript
300
300
  App.instance.debug("OpsFileScriptDSL#shell! cmd=#{cmd} with input mappings #{interaction_handler.input_mappings.inspect} given input: #{input.inspect})")
@@ -311,14 +311,14 @@ module OpsWalrus
311
311
  output_block = StringIO.open do |io|
312
312
  if App.instance.info? # this is true if log_level is trace, debug, info
313
313
  io.print Style.blue(hostname)
314
- io.print " | #{Style.magenta(description)}" if description
314
+ io.print " | #{Style.green(description)}" if description
315
315
  io.puts
316
316
  io.print Style.yellow(cmd_id)
317
317
  io.print Style.green.bold(" > ")
318
318
  io.puts Style.yellow(cmd)
319
319
  elsif App.instance.warn? && description
320
320
  io.print Style.blue(hostname)
321
- io.print " | #{Style.magenta(description)}" if description
321
+ io.print " | #{Style.green(description)}" if description
322
322
  io.puts
323
323
  end
324
324
  io.string
@@ -267,12 +267,13 @@ module OpsWalrus
267
267
 
268
268
  # input_mapping : Hash[ String | Regex => String ]
269
269
  # sudo_password : String
270
- def handle_input(input_mapping, sudo_password: nil, ops_sudo_password: nil, inherit_existing_mappings: true, &block)
270
+ def handle_input(input_mapping, sudo_password: nil, ops_sudo_password: nil, inherit_existing_mappings: true, lookback_window_chars: 200, &block)
271
271
  @interaction_handler.with_mapping(
272
272
  input_mapping,
273
273
  sudo_password: sudo_password,
274
274
  ops_sudo_password: ops_sudo_password,
275
275
  inherit_existing_mappings: inherit_existing_mappings,
276
+ lookback_window_chars: lookback_window_chars,
276
277
  &block
277
278
  )
278
279
  end
@@ -1,3 +1,3 @@
1
1
  module OpsWalrus
2
- VERSION = "1.0.77"
2
+ VERSION = "1.0.78"
3
3
  end
data/opswalrus.gemspec CHANGED
@@ -44,6 +44,7 @@ Gem::Specification.new do |spec|
44
44
 
45
45
  spec.add_dependency "bcrypt_pbkdf", "~> 1.1"
46
46
  spec.add_dependency "ed25519", "~> 1.3"
47
+ spec.add_dependency "kleene", ">= 0"
47
48
  spec.add_dependency "sshkit", "~> 1.21" # sshkit uses net-ssh, which depends on bcrypt_pbkdf and ed25519 to dynamically add support for ed25519 if those two gems are present
48
49
 
49
50
  # For more information and examples about making a new gem, check out our
data/test.ops ADDED
@@ -0,0 +1,10 @@
1
+ params:
2
+ version: string
3
+
4
+ imports:
5
+ core: "https://github.com/opswalrus/core.git"
6
+
7
+ ...
8
+
9
+ totp = rand(10000)
10
+ sh("Push gem", input: {/You have enabled multi-factor authentication. Please enter OTP code./ => "#{totp}\n"}) { 'ruby test.rb' }
data/test.rb CHANGED
@@ -1,88 +1,3 @@
1
- require 'tty-option'
2
-
3
- class Command
4
- include TTY::Option
5
-
6
- usage do
7
- program "dock"
8
-
9
- command "run"
10
-
11
- desc "Run a command in a new container"
12
-
13
- example "Set working directory (-w)",
14
- " $ dock run -w /path/to/dir/ ubuntu pwd"
15
-
16
- example <<~EOS
17
- Mount volume
18
- $ dock run -v `pwd`:`pwd` -w `pwd` ubuntu pwd
19
- EOS
20
- end
21
-
22
- argument :image do
23
- required
24
- desc "The name of the image to use"
25
- end
26
-
27
- argument :command do
28
- optional
29
- desc "The command to run inside the image"
30
- end
31
-
32
- keyword :restart do
33
- default "no"
34
- permit %w[no on-failure always unless-stopped]
35
- desc "Restart policy to apply when a container exits"
36
- end
37
-
38
- option :verbose do
39
- arity "+"
40
- short "-v"
41
- desc "Verbose mode"
42
- end
43
-
44
- flag :detach do
45
- short "-d"
46
- long "--detach"
47
- desc "Run container in background and print container ID"
48
- end
49
-
50
- flag :help do
51
- short "-h"
52
- long "--help"
53
- desc "Print usage"
54
- end
55
-
56
- option :name do
57
- required
58
- long "--name string"
59
- desc "Assign a name to the container"
60
- end
61
-
62
- option :port do
63
- arity one_or_more
64
- short "-p"
65
- long "--publish list"
66
- convert :list
67
- desc "Publish a container's port(s) to the host"
68
- end
69
-
70
- def run
71
- puts params[:verbose].inspect
72
- if params[:help]
73
- print help
74
- elsif params.errors.any?
75
- puts params.errors.summary
76
- else
77
- pp params.to_h
78
- end
79
- end
80
- end
81
-
82
- def main
83
- cmd = Command.new
84
- cmd.parse
85
- puts cmd.run
86
- end
87
-
88
- main
1
+ puts "You have enabled multi-factor authentication. Please enter OTP code."
2
+ input = gets
3
+ puts "You typed: #{input}"
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.77
4
+ version: 1.0.78
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-11-02 00:00:00.000000000 Z
11
+ date: 2023-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: '1.3'
167
+ - !ruby/object:Gem::Dependency
168
+ name: kleene
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: sshkit
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -196,6 +210,7 @@ files:
196
210
  - README.md
197
211
  - Rakefile
198
212
  - build.ops
213
+ - cli2.rb
199
214
  - exe/ops
200
215
  - lib/opswalrus.rb
201
216
  - lib/opswalrus/_bootstrap.ops
@@ -229,6 +244,7 @@ files:
229
244
  - lib/opswalrus/zip.rb
230
245
  - opswalrus.gemspec
231
246
  - sig/opswalrus.rbs
247
+ - test.ops
232
248
  - test.rb
233
249
  - vms/arch/Vagrantfile
234
250
  - vms/debian/Vagrantfile