opswalrus 1.0.62 → 1.0.64

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: 23ccee9336c9eeffa5c8bf4fd9c4f26353eb49fada6d7643ad236b81f5ad4061
4
- data.tar.gz: b43f9ee85f5557c60506d74a9a21d7d31d21762a47449bed8fa6a145cc05f8eb
3
+ metadata.gz: '03538d35b647412c40af0d2df5aa214ea53ea1beda900abe6825096e1e102db0'
4
+ data.tar.gz: b32414001a3a66a94537ad5fefaa789f24cba8e42da20d47db4c47d9f7834b1b
5
5
  SHA512:
6
- metadata.gz: 2f172ded5af3368a410705b17ea624da8ab0f994d84a2441a403066af0a4b56010345bee5437b9eac8d2cc883644d4febc479d666a4a5b4309efe6ce841d22f9
7
- data.tar.gz: 4022b1f2bf0aadbd83067798639f6ac593228f9d54cc3f79e0df3dee5172069a59ce72421f569a140ee31b1f382724435482c7860bcf8eb02d783150ab37e78e
6
+ metadata.gz: ecdbb125b8d658bf841d9ef62ed5ed10ec145a62cf7d82d5182398955df9b0d2cf8a62f2fbd64ebcf52f6974032f9f0658e55236e6e963acf29c718df75a3197
7
+ data.tar.gz: c5387283ba8982f5fd6c9a3f29935ed49ea895667c3f4f2ea6db0c39f8fde5a9e2ccfdd873a55cfd2d9b8d680506da4c8f0228fe74fe1da627288f266bdeb13c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- opswalrus (1.0.62)
4
+ opswalrus (1.0.64)
5
5
  activesupport (~> 7.0)
6
6
  bcrypt_pbkdf (~> 1.1)
7
7
  binding_of_caller (~> 1.0)
@@ -6,6 +6,5 @@ ssh in: :sequence do
6
6
  # ssh_noprep do
7
7
  # puts params.stringify_keys!
8
8
  # desc "Running `#{params.ops_file.ops_file_path} #{params.operation_kv_args.join(' ')}` on #{to_s} (alias=#{self.alias})"
9
- # run_ops(ops_command, ops_command_options = nil, command_arguments, in_bundle_root_dir: true, ops_prompt_for_sudo_password: false)
10
9
  _invoke_remote(params.ops_file, *params.operation_kv_args)
11
10
  end
@@ -322,21 +322,25 @@ module OpsWalrus
322
322
  end
323
323
 
324
324
  def parse_stdout_and_script_return_value(command_output)
325
- output_sections = command_output.split(/^#{::OpsWalrus::App::SCRIPT_RESULT_HEADER}$/)
325
+ output_sections = command_output.split(/#{::OpsWalrus::App::SCRIPT_RESULT_HEADER}/)
326
326
  case output_sections.count
327
327
  when 1
328
328
  stdout, ops_script_retval = output_sections.first, nil
329
+ # puts "found it1!: #{output_sections.inspect}"
329
330
  when 2
330
331
  stdout, ops_script_retval = *output_sections
332
+ # puts "found it2!: #{ops_script_retval}"
331
333
  else
332
334
  # this is unexpected
333
335
  ops_script_retval = output_sections.pop
334
336
  stdout = output_sections.join(::OpsWalrus::App::SCRIPT_RESULT_HEADER)
337
+ # puts "found it3!: #{ops_script_retval}"
335
338
  end
336
339
  [stdout, ops_script_retval]
337
340
  end
338
341
 
339
342
  # runs the specified ops command with the specified command arguments
343
+ # returns [stdout, stderr, exit_status]
340
344
  def run_ops(ops_command, ops_command_options = nil, command_arguments, in_bundle_root_dir: true, ops_prompt_for_sudo_password: false)
341
345
  local_hostname_for_remote_host = if self.alias
342
346
  "#{host} (#{self.alias})"
@@ -125,13 +125,16 @@ module OpsWalrus
125
125
  ops_command_options = "--script"
126
126
  ops_command_options << " --pass" if @ops_prompt_for_sudo_password
127
127
  ops_command_options << " --params #{remote_json_kwargs_tempfile_basename}" if remote_json_kwargs_tempfile_basename
128
- retval = if ops_command_options.empty?
128
+
129
+ output, stderr, exit_status = if ops_command_options.empty?
129
130
  @host_proxy.run_ops(:run, remote_run_command_args, ops_prompt_for_sudo_password: @ops_prompt_for_sudo_password)
130
131
  else
131
132
  @host_proxy.run_ops(:run, ops_command_options, remote_run_command_args, ops_prompt_for_sudo_password: @ops_prompt_for_sudo_password)
132
133
  end
133
134
 
134
- retval
135
+ App.instance.debug("Remote invocation failed:\n cmd: ops run #{ops_command_options.to_s} #{remote_run_command_args.to_s}\n stdout: #{output}\n") unless exit_status == 0
136
+
137
+ RemoteInvocation.parse_remote_script_invocation_result(output)
135
138
  ensure
136
139
  if json_kwargs_tempfile
137
140
  json_kwargs_tempfile.close rescue nil
@@ -198,9 +201,19 @@ module OpsWalrus
198
201
 
199
202
 
200
203
 
201
-
202
-
203
204
  class RemoteInvocation
205
+ def self.parse_remote_script_invocation_result(json_string)
206
+ retval = JSON.parse(json_string)
207
+ case retval
208
+ when Hash
209
+ retval.with_indifferent_access.easynav
210
+ when Array
211
+ retval.easynav
212
+ else
213
+ retval
214
+ end
215
+ end
216
+
204
217
  def initialize(host_proxy, ops_file, ops_prompt_for_sudo_password: nil)
205
218
  @host_proxy = host_proxy
206
219
  @ops_file = ops_file
@@ -235,13 +248,16 @@ module OpsWalrus
235
248
  ops_command_options = "--script"
236
249
  ops_command_options << " --pass" if @ops_prompt_for_sudo_password
237
250
  ops_command_options << " --params #{remote_json_kwargs_tempfile_basename}" if remote_json_kwargs_tempfile_basename
238
- retval = if ops_command_options.empty?
251
+
252
+ output, stderr, exit_status = if ops_command_options.empty?
239
253
  @host_proxy.run_ops(:run, remote_run_command_args, ops_prompt_for_sudo_password: @ops_prompt_for_sudo_password)
240
254
  else
241
255
  @host_proxy.run_ops(:run, ops_command_options, remote_run_command_args, ops_prompt_for_sudo_password: @ops_prompt_for_sudo_password)
242
256
  end
243
257
 
244
- retval
258
+ App.instance.debug("Remote invocation failed:\n cmd: ops run #{ops_command_options.to_s} #{remote_run_command_args.to_s}\n stdout: #{output}\n") unless exit_status == 0
259
+
260
+ RemoteInvocation.parse_remote_script_invocation_result(output)
245
261
  ensure
246
262
  if json_kwargs_tempfile
247
263
  json_kwargs_tempfile.close rescue nil
@@ -5,82 +5,81 @@ require_relative 'ops_file_script_dsl'
5
5
 
6
6
  module OpsWalrus
7
7
 
8
- class ArrayOrHashNavigationProxy
9
- extend Forwardable
10
-
11
- def initialize(array_or_hash)
12
- @obj = array_or_hash
13
- end
14
-
15
- def_delegators :@obj, :to_s, :inspect, :hash, :===, :eql?, :kind_of?, :is_a?, :instance_of?, :respond_to?, :<=>
16
-
17
- def [](index, *args, **kwargs, &block)
18
- @obj.method(:[]).call(index, *args, **kwargs, &block)
19
- end
20
- def respond_to_missing?(method, *)
21
- @obj.is_a?(Hash) && @obj.respond_to?(method)
22
- end
23
- def method_missing(name, *args, **kwargs, &block)
24
- case @obj
25
- when Array
26
- @obj.method(name).call(*args, **kwargs, &block)
27
- when Hash
28
- if @obj.respond_to?(name)
29
- @obj.method(name).call(*args, **kwargs, &block)
30
- else
31
- value = self[name.to_s]
32
- case value
33
- when Array, Hash
34
- ArrayOrHashNavigationProxy.new(value)
35
- else
36
- value
37
- end
38
- end
39
- end
40
- end
41
- end
42
-
43
- class InvocationParams
44
- # @params : Hash
45
-
46
- # params : Hash | ArrayOrHashNavigationProxy
47
- def initialize(hashlike_params)
48
- # this doesn't seem to make any difference
49
- @params = hashlike_params.to_h
50
- # @params = hashlike_params
51
- end
52
-
53
- def [](key)
54
- key = key.to_s if key.is_a? Symbol
55
- @params[key]
56
- end
57
-
58
- def dig(*keys, default: nil)
59
- # keys = keys.map {|key| key.is_a?(Integer) ? key : key.to_s }
60
- @params.dig(*keys) || default
61
- end
62
-
63
- def method_missing(name, *args, **kwargs, &block)
64
- if @params.respond_to?(name)
65
- @params.method(name).call(*args, **kwargs, &block)
66
- else
67
- value = self[name]
68
- case value
69
- when Array, Hash
70
- ArrayOrHashNavigationProxy.new(value)
71
- else
72
- value
73
- end
74
- end
75
- end
76
- end
77
-
78
- class EnvParams < InvocationParams
79
- # params : Hash | ArrayOrHashNavigationProxy
80
- def initialize(hashlike_params = ENV)
81
- super(hashlike_params)
82
- end
83
- end
8
+ # class ArrayOrHashNavigationProxy
9
+ # extend Forwardable
10
+
11
+ # def initialize(array_or_hash)
12
+ # @obj = array_or_hash
13
+ # end
14
+
15
+ # def_delegators :@obj, :[], :to_s, :inspect, :hash, :===, :eql?, :kind_of?, :is_a?, :instance_of?, :respond_to?, :<=>
16
+
17
+ # # def [](index, *args, **kwargs, &block)
18
+ # # @obj.method(:[]).call(index, *args, **kwargs, &block)
19
+ # # end
20
+ # def respond_to_missing?(method, *)
21
+ # @obj.is_a?(Hash) && @obj.respond_to?(method)
22
+ # end
23
+ # def method_missing(name, *args, **kwargs, &block)
24
+ # case @obj
25
+ # when Array
26
+ # @obj.method(name).call(*args, **kwargs, &block)
27
+ # when Hash
28
+ # if @obj.respond_to?(name)
29
+ # @obj.method(name).call(*args, **kwargs, &block)
30
+ # else
31
+ # value = self[name.to_s]
32
+ # case value
33
+ # when Array, Hash
34
+ # ArrayOrHashNavigationProxy.new(value)
35
+ # else
36
+ # value
37
+ # end
38
+ # end
39
+ # end
40
+ # end
41
+ # end
42
+
43
+ # class InvocationParams
44
+ # # @params : Hash
45
+
46
+ # # params : Hash | ArrayOrHashNavigationProxy
47
+ # def initialize(hashlike_params)
48
+ # # this doesn't seem to make any difference
49
+ # @params = hashlike_params.to_h
50
+ # # @params = hashlike_params
51
+ # end
52
+
53
+ # def [](key)
54
+ # @params[key]
55
+ # end
56
+
57
+ # def dig(*keys, default: nil)
58
+ # # keys = keys.map {|key| key.is_a?(Integer) ? key : key.to_s }
59
+ # @params.dig(*keys) || default
60
+ # end
61
+
62
+ # def method_missing(name, *args, **kwargs, &block)
63
+ # if @params.respond_to?(name)
64
+ # @params.method(name).call(*args, **kwargs, &block)
65
+ # else
66
+ # value = self[name]
67
+ # case value
68
+ # when Array, Hash
69
+ # ArrayOrHashNavigationProxy.new(value)
70
+ # else
71
+ # value
72
+ # end
73
+ # end
74
+ # end
75
+ # end
76
+
77
+ # class EnvParams < InvocationParams
78
+ # # params : Hash | ArrayOrHashNavigationProxy
79
+ # def initialize(hashlike_params = ENV)
80
+ # super(hashlike_params)
81
+ # end
82
+ # end
84
83
 
85
84
  class OpsFileScript
86
85
 
@@ -135,16 +134,27 @@ module OpsWalrus
135
134
  # - #host_proxy_class
136
135
  # - #backend
137
136
  # - all the dynamically defined methods in the subclass of Invocation
137
+ #
138
+ # Return value is whatever the script returned with one exception:
139
+ # - if the script returns a Hash or an Array, the return value is an EasyNavProxy
138
140
  invoke_method_definition = <<~INVOKE_METHOD
139
141
  def _invoke(runtime_env, hashlike_params)
140
142
  @runtime_env = runtime_env
141
- @params = InvocationParams.new(hashlike_params)
143
+ @params = hashlike_params.easynav
142
144
  @runtime_ops_file_path = __FILE__
143
- #{ruby_script}
145
+ _retval = begin
146
+ #{ruby_script}
147
+ end
148
+ case _retval
149
+ when Hash, Array
150
+ _retval.easynav
151
+ else
152
+ _retval
153
+ end
144
154
  end
145
155
  INVOKE_METHOD
146
156
 
147
- invoke_method_line_count_prior_to_ruby_script_from_ops_file = 4
157
+ invoke_method_line_count_prior_to_ruby_script_from_ops_file = 5
148
158
  klass.module_eval(invoke_method_definition, ops_file.ops_file_path.to_s, ops_file.script_line_offset - invoke_method_line_count_prior_to_ruby_script_from_ops_file)
149
159
 
150
160
  klass
@@ -366,7 +366,7 @@ module OpsWalrus
366
366
  end
367
367
 
368
368
  def parse_stdout_and_script_return_value(command_output)
369
- output_sections = command_output.split(/^#{::OpsWalrus::App::SCRIPT_RESULT_HEADER}$/)
369
+ output_sections = command_output.split(/#{::OpsWalrus::App::SCRIPT_RESULT_HEADER}/)
370
370
  case output_sections.count
371
371
  when 1
372
372
  stdout, ops_script_retval = output_sections.first, nil
@@ -1,7 +1,54 @@
1
- require 'json'
2
- require 'pathname'
3
1
  require 'active_support'
4
2
  require 'active_support/core_ext/hash'
3
+ require 'json'
4
+ require 'pathname'
5
+
6
+ class EasyNavProxy
7
+ extend Forwardable
8
+
9
+ # indexable_obj must implement #respond_to? and #has_key?
10
+ def initialize(indexable_obj)
11
+ @obj = indexable_obj
12
+ end
13
+
14
+ def_delegators :@obj, :[], :to_s, :inspect, :hash, :===, :==, :eql?, :kind_of?, :is_a?, :instance_of?, :respond_to?, :<=>
15
+
16
+ def easynav
17
+ self
18
+ end
19
+
20
+ def respond_to_missing?(method, *)
21
+ @obj.respond_to?(method) || @obj.has_key?(method)
22
+ end
23
+ def method_missing(method, *args, **kwargs, &block)
24
+ if @obj.respond_to?(method)
25
+ @obj.method(method).call(*args, **kwargs, &block)
26
+ elsif @obj.has_key?(method)
27
+ value = self[method]
28
+ case value
29
+ when Array, Hash
30
+ EasyNavProxy.new(value)
31
+ else
32
+ value
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ class Hash
39
+ def easynav
40
+ EasyNavProxy.new(self.with_indifferent_access)
41
+ end
42
+ end
43
+
44
+ class Array
45
+ def has_key?(key)
46
+ key.is_a?(Integer) && key < size
47
+ end
48
+ def easynav
49
+ EasyNavProxy.new(self)
50
+ end
51
+ end
5
52
 
6
53
  class String
7
54
  def escape_single_quotes
@@ -23,7 +70,6 @@ class Pathname
23
70
  end
24
71
  end
25
72
 
26
-
27
73
  class String
28
74
  def boolean!(default: false)
29
75
  boolean_str = strip.downcase
@@ -1,3 +1,5 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/hash'
1
3
  require 'json'
2
4
  require 'shellwords'
3
5
  require 'socket'
@@ -238,7 +240,8 @@ module OpsWalrus
238
240
 
239
241
  def initialize(app)
240
242
  @app = app
241
- @env = EnvParams.new(ENV)
243
+ # @env = EnvParams.new(ENV)
244
+ @env = ENV.to_h.with_indifferent_access.easynav
242
245
  @bundle_load_path = LoadPath.new(self, @app.bundle_dir)
243
246
  @app_load_path = LoadPath.new(self, @app.pwd)
244
247
 
@@ -1,3 +1,3 @@
1
1
  module OpsWalrus
2
- VERSION = "1.0.62"
2
+ VERSION = "1.0.64"
3
3
  end
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.62
4
+ version: 1.0.64
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-25 00:00:00.000000000 Z
11
+ date: 2023-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport