MuranoCLI 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +50 -27
- data/.trustme.vim +12 -8
- data/bin/murano +23 -8
- data/docs/basic_example.rst +1 -1
- data/docs/completions/murano_completion-bash +88 -0
- data/lib/MrMurano/Account.rb +3 -3
- data/lib/MrMurano/Business.rb +6 -6
- data/lib/MrMurano/Config-Migrate.rb +1 -3
- data/lib/MrMurano/Config.rb +16 -8
- data/lib/MrMurano/Content.rb +56 -45
- data/lib/MrMurano/Gateway.rb +62 -21
- data/lib/MrMurano/Mock.rb +27 -19
- data/lib/MrMurano/Passwords.rb +7 -7
- data/lib/MrMurano/ReCommander.rb +171 -28
- data/lib/MrMurano/Setting.rb +38 -40
- data/lib/MrMurano/Solution-ServiceConfig.rb +2 -1
- data/lib/MrMurano/Solution-Services.rb +196 -61
- data/lib/MrMurano/Solution-Users.rb +7 -7
- data/lib/MrMurano/Solution.rb +22 -8
- data/lib/MrMurano/SolutionId.rb +10 -4
- data/lib/MrMurano/SubCmdGroupContext.rb +14 -5
- data/lib/MrMurano/SyncAllowed.rb +42 -0
- data/lib/MrMurano/SyncUpDown.rb +122 -65
- data/lib/MrMurano/Webservice-Cors.rb +9 -3
- data/lib/MrMurano/Webservice-Endpoint.rb +39 -33
- data/lib/MrMurano/Webservice-File.rb +35 -24
- data/lib/MrMurano/commands/business.rb +18 -18
- data/lib/MrMurano/commands/content.rb +3 -2
- data/lib/MrMurano/commands/devices.rb +137 -22
- data/lib/MrMurano/commands/globals.rb +8 -2
- data/lib/MrMurano/commands/keystore.rb +3 -2
- data/lib/MrMurano/commands/link.rb +13 -13
- data/lib/MrMurano/commands/login.rb +3 -2
- data/lib/MrMurano/commands/mock.rb +4 -3
- data/lib/MrMurano/commands/password.rb +4 -2
- data/lib/MrMurano/commands/postgresql.rb +5 -3
- data/lib/MrMurano/commands/settings.rb +78 -62
- data/lib/MrMurano/commands/show.rb +79 -74
- data/lib/MrMurano/commands/solution.rb +6 -4
- data/lib/MrMurano/commands/solution_picker.rb +5 -4
- data/lib/MrMurano/commands/status.rb +15 -4
- data/lib/MrMurano/commands/timeseries.rb +3 -2
- data/lib/MrMurano/commands/tsdb.rb +3 -2
- data/lib/MrMurano/hash.rb +6 -6
- data/lib/MrMurano/http.rb +66 -67
- data/lib/MrMurano/makePretty.rb +18 -12
- data/lib/MrMurano/progress.rb +9 -2
- data/lib/MrMurano/verbosing.rb +14 -2
- data/lib/MrMurano/version.rb +2 -2
- data/spec/GatewayDevice_spec.rb +190 -149
- data/spec/Mock_spec.rb +3 -3
- data/spec/Solution-ServiceEventHandler_spec.rb +170 -137
- data/spec/SyncUpDown_spec.rb +205 -191
- metadata +3 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -10,7 +10,7 @@ require 'MrMurano/Business'
|
|
10
10
|
require 'MrMurano/ReCommander'
|
11
11
|
require 'MrMurano/Solution'
|
12
12
|
|
13
|
-
command
|
13
|
+
command :show do |c|
|
14
14
|
c.syntax = %(murano show)
|
15
15
|
c.summary = %(Show readable information about the current configuration)
|
16
16
|
c.description = %(
|
@@ -18,89 +18,94 @@ Show readable information about the current configuration.
|
|
18
18
|
).strip
|
19
19
|
c.project_not_required = true
|
20
20
|
|
21
|
-
c.
|
22
|
-
if args.include?('help')
|
23
|
-
::Commander::UI.enable_paging
|
24
|
-
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
25
|
-
else
|
26
|
-
acc = MrMurano::Account.instance
|
27
|
-
biz = MrMurano::Business.new
|
28
|
-
|
29
|
-
selected_business = nil
|
30
|
-
selected_business_id = $cfg['business.id']
|
31
|
-
unless selected_business_id.to_s.empty?
|
32
|
-
acc.businesses.each do |sol|
|
33
|
-
selected_business = sol if sol.bizid == selected_business_id
|
34
|
-
end
|
35
|
-
end
|
21
|
+
c.option '--[no-]ids', 'Show IDs'
|
36
22
|
|
37
|
-
|
38
|
-
|
39
|
-
unless selected_application_id.to_s.empty?
|
40
|
-
MrMurano::Verbose.whirly_start('Fetching Applications...')
|
41
|
-
biz.applications.each do |sol|
|
42
|
-
selected_application = sol if sol.apiId == selected_application_id
|
43
|
-
end
|
44
|
-
MrMurano::Verbose.whirly_stop
|
45
|
-
end
|
23
|
+
c.action do |args, options|
|
24
|
+
c.verify_arg_count!(args)
|
46
25
|
|
47
|
-
|
48
|
-
|
49
|
-
unless selected_product_id.to_s.empty?
|
50
|
-
MrMurano::Verbose.whirly_start('Fetching Products...')
|
51
|
-
biz.products.each do |sol|
|
52
|
-
selected_product = sol if sol.apiId == selected_product_id
|
53
|
-
end
|
54
|
-
MrMurano::Verbose.whirly_stop
|
55
|
-
end
|
26
|
+
acc = MrMurano::Account.instance
|
27
|
+
biz = MrMurano::Business.new
|
56
28
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
29
|
+
selected_business = nil
|
30
|
+
selected_business_id = $cfg['business.id']
|
31
|
+
unless selected_business_id.to_s.empty?
|
32
|
+
acc.businesses.each do |sol|
|
33
|
+
selected_business = sol if sol.bizid == selected_business_id
|
61
34
|
end
|
35
|
+
end
|
62
36
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
37
|
+
selected_application = nil
|
38
|
+
selected_application_id = $cfg['application.id']
|
39
|
+
unless selected_application_id.to_s.empty?
|
40
|
+
MrMurano::Verbose.whirly_start('Fetching Applications...')
|
41
|
+
biz.applications.each do |sol|
|
42
|
+
selected_application = sol if sol.apiId == selected_application_id
|
68
43
|
end
|
44
|
+
MrMurano::Verbose.whirly_stop
|
45
|
+
end
|
69
46
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
elsif selected_application_id
|
77
|
-
#puts 'selected application not in business'
|
78
|
-
puts "application ID from config is not in business (#{selected_application_id})"
|
79
|
-
id_not_in_biz = true
|
80
|
-
elsif !selected_business
|
81
|
-
puts 'application ID depends on business ID'
|
82
|
-
else
|
83
|
-
#puts 'no application selected'
|
84
|
-
puts 'application ID not found in config'
|
47
|
+
selected_product = nil
|
48
|
+
selected_product_id = $cfg['product.id']
|
49
|
+
unless selected_product_id.to_s.empty?
|
50
|
+
MrMurano::Verbose.whirly_start('Fetching Products...')
|
51
|
+
biz.products.each do |sol|
|
52
|
+
selected_product = sol if sol.apiId == selected_product_id
|
85
53
|
end
|
54
|
+
MrMurano::Verbose.whirly_stop
|
55
|
+
end
|
86
56
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
57
|
+
if $cfg['user.name']
|
58
|
+
puts %(user: #{$cfg['user.name']})
|
59
|
+
else
|
60
|
+
puts 'no user selected'
|
61
|
+
end
|
62
|
+
|
63
|
+
if selected_business
|
64
|
+
biz_info = %(business: #{selected_business.name})
|
65
|
+
biz_info += %( <#{selected_business.bid}>) if options.ids
|
66
|
+
puts biz_info
|
67
|
+
else
|
68
|
+
#puts 'no business selected'
|
69
|
+
MrMurano::Verbose.error MrMurano::Business.missing_business_id_msg
|
70
|
+
end
|
101
71
|
|
102
|
-
|
72
|
+
id_not_in_biz = false
|
73
|
+
|
74
|
+
# E.g., {:bizid=>"ABC", :type=>"application", :apiId=>"XXX", :sid=>"XXX",
|
75
|
+
# :name=>"ABC", :domain=>"ABC.apps.exosite.io" }
|
76
|
+
if selected_application
|
77
|
+
sol_info = %(application: https://#{selected_application.domain})
|
78
|
+
sol_info += %( <#{selected_application.sid}>) if options.ids
|
79
|
+
puts sol_info
|
80
|
+
elsif selected_application_id
|
81
|
+
#puts 'selected application not in business'
|
82
|
+
puts "application ID from config is not in business (#{selected_application_id})"
|
83
|
+
id_not_in_biz = true
|
84
|
+
elsif !selected_business
|
85
|
+
puts 'application ID depends on business ID'
|
86
|
+
else
|
87
|
+
#puts 'no application selected'
|
88
|
+
puts 'application ID not found in config'
|
103
89
|
end
|
90
|
+
|
91
|
+
# E.g., {:bizid=>"ABC", :type=>"product", :apiId=>"XXX", :sid=>"XXX",
|
92
|
+
# :name=>"ABC", :domain=>"ABC.m2.exosite.io" }
|
93
|
+
if selected_product
|
94
|
+
sol_info = %(product: #{selected_product.name})
|
95
|
+
sol_info += %( <#{selected_product.sid}>) if options.ids
|
96
|
+
puts sol_info
|
97
|
+
elsif selected_product_id
|
98
|
+
#puts 'selected product not in business'
|
99
|
+
puts "product ID from config is not in business (#{selected_product_id})"
|
100
|
+
id_not_in_biz = true
|
101
|
+
elsif !selected_business
|
102
|
+
puts 'product ID depends on business ID'
|
103
|
+
else
|
104
|
+
#puts 'no product selected'
|
105
|
+
puts 'product ID not found in config'
|
106
|
+
end
|
107
|
+
|
108
|
+
MrMurano::SolutionBase.warn_configfile_env_maybe if id_not_in_biz
|
104
109
|
end
|
105
110
|
end
|
106
111
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.23 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -19,9 +19,10 @@ command :solution do |c|
|
|
19
19
|
Commands for working with Application and Product solutions.
|
20
20
|
).strip
|
21
21
|
c.project_not_required = true
|
22
|
+
c.subcmdgrouphelp = true
|
22
23
|
|
23
24
|
c.action do |_args, _options|
|
24
|
-
::Commander::UI.enable_paging
|
25
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
25
26
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
26
27
|
end
|
27
28
|
end
|
@@ -156,7 +157,7 @@ def cmd_solution_del_get_names_and_ids!(biz, args, options)
|
|
156
157
|
end
|
157
158
|
solz = must_fetch_solutions!(options, args, biz)
|
158
159
|
solz.each do |sol|
|
159
|
-
nmorids += [[sol.sid, "
|
160
|
+
nmorids += [[sol.sid, "#{MrMurano::Verbose.fancy_ticks(sol.name)} <#{sol.sid}>", sol]]
|
160
161
|
end
|
161
162
|
nmorids
|
162
163
|
end
|
@@ -230,7 +231,8 @@ def solution_delete(name_or_id, use_sol: nil, type: :all, yes: false)
|
|
230
231
|
n_faulted = 0
|
231
232
|
if solz.empty?
|
232
233
|
if !name_or_id.empty?
|
233
|
-
MrMurano::Verbose.
|
234
|
+
name_or_id_q = MrMurano::Verbose.fancy_ticks(name_or_id)
|
235
|
+
MrMurano::Verbose.error("No solution matching #{name_or_id_q} found")
|
234
236
|
else
|
235
237
|
MrMurano::Verbose.error(MSG_SOLUTIONS_NONE_FOUND)
|
236
238
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.23 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -156,12 +156,12 @@ def must_fetch_solutions!(options, args=[], biz=nil)
|
|
156
156
|
|
157
157
|
if args.none? && !any_solution_pickers!(options)
|
158
158
|
if !options.all
|
159
|
-
if $cfg['application.id']
|
159
|
+
if %i[all application].include?(options.type) && $cfg['application.id']
|
160
160
|
solz += solution_get_solutions(
|
161
161
|
biz, :application, sid: $cfg['application.id']
|
162
162
|
)
|
163
163
|
end
|
164
|
-
if $cfg['product.id']
|
164
|
+
if %i[all product].include?(options.type) && $cfg['product.id']
|
165
165
|
solz += solution_get_solutions(
|
166
166
|
biz, :product, sid: $cfg['product.id']
|
167
167
|
)
|
@@ -449,7 +449,8 @@ module MrMurano
|
|
449
449
|
say "Found #{sol.type_name} #{sol.pretty_desc}"
|
450
450
|
elsif !@searching
|
451
451
|
# The solution ID in the config was not found for this business.
|
452
|
-
|
452
|
+
tried_sid = MrMurano::Verbose.fancy_ticks(tried_sid)
|
453
|
+
say "The #{sol.type_name} ID #{tried_sid} from the config was not found"
|
453
454
|
end
|
454
455
|
puts ''
|
455
456
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -109,6 +109,7 @@ Endpoints can be selected with a "#<method>#<path glob>" pattern.
|
|
109
109
|
unless item[:pp_desc].to_s.empty? || item[:pp_desc] == item[:synckey]
|
110
110
|
desc += " (#{item[:pp_desc]})"
|
111
111
|
end
|
112
|
+
# NOTE: This path is the endpoint path.
|
112
113
|
desc += " [#{item[:method]} #{item[:path]}]" if item[:method] && item[:path]
|
113
114
|
desc
|
114
115
|
end
|
@@ -149,6 +150,16 @@ Endpoints can be selected with a "#<method>#<path glob>" pattern.
|
|
149
150
|
end
|
150
151
|
end
|
151
152
|
|
153
|
+
unless ret[:clash].empty?
|
154
|
+
pretty_group_header(
|
155
|
+
ret[:clash], 'Conflicting items', 'in conflict', options.grouped
|
156
|
+
)
|
157
|
+
ret[:clash].each do |item|
|
158
|
+
abbrev = $cfg['tool.ascii'] && 'x' || '✗'
|
159
|
+
interject " #{abbrev} #{item[:pp_type]} #{highlight_del(fmtr(item, options))}"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
152
163
|
return unless options.show_all
|
153
164
|
interject 'Unchanged:' if options.grouped
|
154
165
|
ret[:unchg].each { |item| interject " #{item[:pp_type]} #{fmtr(item, options)}" }
|
@@ -171,15 +182,15 @@ Endpoints can be selected with a "#<method>#<path glob>" pattern.
|
|
171
182
|
Rainbow(msg).red.bright
|
172
183
|
end
|
173
184
|
|
174
|
-
@grouped = { toadd: [], todel: [], tomod: [], unchg: [], skipd: [] }
|
185
|
+
@grouped = { toadd: [], todel: [], tomod: [], unchg: [], skipd: [], clash: [] }
|
175
186
|
def gmerge(ret, type, desc, options)
|
176
187
|
if options.grouped
|
177
188
|
out = @grouped
|
178
189
|
else
|
179
|
-
out = { toadd: [], todel: [], tomod: [], unchg: [], skipd: [] }
|
190
|
+
out = { toadd: [], todel: [], tomod: [], unchg: [], skipd: [], clash: [] }
|
180
191
|
end
|
181
192
|
|
182
|
-
%i[toadd todel tomod unchg skipd].each do |kind|
|
193
|
+
%i[toadd todel tomod unchg skipd clash].each do |kind|
|
183
194
|
ret[kind].each do |item|
|
184
195
|
item = item.to_h
|
185
196
|
item[:pp_type] = type
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -42,9 +42,10 @@ The timeseries sub-commands let you interact directly with the Timeseries
|
|
42
42
|
instance in a solution. This allows for easier debugging, being able to
|
43
43
|
quickly try out different queries or write test data.
|
44
44
|
).strip
|
45
|
+
c.subcmdgrouphelp = true
|
45
46
|
|
46
47
|
c.action do |_args, _options|
|
47
|
-
::Commander::UI.enable_paging
|
48
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
48
49
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
49
50
|
end
|
50
51
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.22 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -59,9 +59,10 @@ solution. This allows for easier debugging, being able to quickly try out
|
|
59
59
|
different queries or write test data.
|
60
60
|
).strip
|
61
61
|
c.project_not_required = true
|
62
|
+
c.subcmdgrouphelp = true
|
62
63
|
|
63
64
|
c.action do |_args, _options|
|
64
|
-
::Commander::UI.enable_paging
|
65
|
+
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
65
66
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
66
67
|
end
|
67
68
|
end
|
data/lib/MrMurano/hash.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.20 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -14,8 +14,8 @@ class Hash
|
|
14
14
|
# Take keys of hash and transform those to symbols.
|
15
15
|
def self.transform_keys_to_symbols(value)
|
16
16
|
return value.map { |v| Hash.transform_keys_to_symbols(v) } if value.is_a?(Array)
|
17
|
-
return value
|
18
|
-
value.inject({}) { |memo, (k,v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo }
|
17
|
+
return value unless value.is_a?(Hash)
|
18
|
+
value.inject({}) { |memo, (k, v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo }
|
19
19
|
end
|
20
20
|
|
21
21
|
# From:
|
@@ -24,8 +24,8 @@ class Hash
|
|
24
24
|
# Take keys of hash and transform those to strings.
|
25
25
|
def self.transform_keys_to_strings(value)
|
26
26
|
return value.map { |v| Hash.transform_keys_to_strings(v) } if value.is_a?(Array)
|
27
|
-
return value
|
28
|
-
value.inject({}) { |memo, (k,v)| memo[k.to_s] = Hash.transform_keys_to_strings(v); memo }
|
27
|
+
return value unless value.is_a?(Hash)
|
28
|
+
value.inject({}) { |memo, (k, v)| memo[k.to_s] = Hash.transform_keys_to_strings(v); memo }
|
29
29
|
end
|
30
30
|
|
31
31
|
# From Rails.
|
@@ -35,7 +35,7 @@ class Hash
|
|
35
35
|
if this_value.is_a?(Hash) && other_value.is_a?(Hash)
|
36
36
|
self[current_key] = this_value.deep_merge(other_value, &block)
|
37
37
|
elsif block_given? && key?(current_key)
|
38
|
-
self[current_key] =
|
38
|
+
self[current_key] = yield(current_key, this_value, other_value)
|
39
39
|
else
|
40
40
|
self[current_key] = other_value
|
41
41
|
end
|
data/lib/MrMurano/http.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Last Modified: 2017.08.
|
1
|
+
# Last Modified: 2017.08.20 /coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# Copyright © 2016-2017 Exosite LLC.
|
@@ -30,50 +30,48 @@ module MrMurano
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def ensure_token!(tok)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
33
|
+
return unless tok.nil?
|
34
|
+
error 'Not logged in!'
|
35
|
+
exit 1
|
37
36
|
end
|
38
37
|
|
39
38
|
def json_opts
|
40
|
-
return @json_opts unless
|
39
|
+
return @json_opts unless !defined?(@json_opts) || @json_opts.nil?
|
41
40
|
@json_opts = {
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
41
|
+
allow_nan: true,
|
42
|
+
symbolize_names: true,
|
43
|
+
create_additions: false,
|
45
44
|
}
|
46
45
|
end
|
47
46
|
|
48
47
|
def curldebug(request)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
else
|
67
|
-
a << %{-d '#{request.body}'}
|
68
|
-
end
|
69
|
-
end
|
70
|
-
if $cfg.curlfile_f.nil?
|
71
|
-
MrMurano::Progress.instance.whirly_interject { puts a.join(' ') }
|
48
|
+
return unless $cfg['tool.curldebug']
|
49
|
+
formp = (request.content_type =~ %r{multipart/form-data})
|
50
|
+
a = []
|
51
|
+
a << %(curl -s)
|
52
|
+
if request.key?('Authorization')
|
53
|
+
a << %(-H 'Authorization: #{request['Authorization']}')
|
54
|
+
end
|
55
|
+
a << %(-H 'User-Agent: #{request['User-Agent']}')
|
56
|
+
a << %(-H 'Content-Type: #{request.content_type}') unless formp
|
57
|
+
a << %(-X #{request.method})
|
58
|
+
a << %('#{request.uri}')
|
59
|
+
unless request.body.nil?
|
60
|
+
if formp
|
61
|
+
m = request.body.match(
|
62
|
+
/form-data;\s+name="(?<name>[^"]+)";\s+filename="(?<filename>[^"]+)"/
|
63
|
+
)
|
64
|
+
a << %(-F #{m[:name]}=@#{m[:filename]}) unless m.nil?
|
72
65
|
else
|
73
|
-
|
74
|
-
$cfg.curlfile_f.flush
|
66
|
+
a << %(-d '#{request.body}')
|
75
67
|
end
|
76
68
|
end
|
69
|
+
if $cfg.curlfile_f.nil?
|
70
|
+
MrMurano::Progress.instance.whirly_interject { puts a.join(' ') }
|
71
|
+
else
|
72
|
+
$cfg.curlfile_f << a.join(' ') + "\n\n"
|
73
|
+
$cfg.curlfile_f.flush
|
74
|
+
end
|
77
75
|
end
|
78
76
|
|
79
77
|
# Default endpoint unless Class overrides it.
|
@@ -83,18 +81,19 @@ module MrMurano
|
|
83
81
|
|
84
82
|
def http
|
85
83
|
uri = URI('https://' + $cfg['net.host'])
|
86
|
-
if
|
84
|
+
if !defined?(@http) || @http.nil?
|
87
85
|
@http = Net::HTTP.new(uri.host, uri.port)
|
88
86
|
@http.use_ssl = true
|
89
87
|
@http.start
|
90
88
|
end
|
91
89
|
@http
|
92
90
|
end
|
91
|
+
|
93
92
|
def http_reset
|
94
93
|
@http = nil
|
95
94
|
end
|
96
95
|
|
97
|
-
def
|
96
|
+
def add_headers(request)
|
98
97
|
request.content_type = 'application/json'
|
99
98
|
# 2017-08-14: MrMurano::Account overrides the token method, and
|
100
99
|
# it doesn't exit if no token, and then we end up here.
|
@@ -104,24 +103,24 @@ module MrMurano
|
|
104
103
|
request
|
105
104
|
end
|
106
105
|
|
106
|
+
# rubocop:disable Style/MethodName "Use snake_case for method names."
|
107
|
+
# 2017-08-20: isJSON and showHttpError are grandparented into lint exceptions.
|
107
108
|
def isJSON(data)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
[false, data]
|
112
|
-
end
|
109
|
+
[true, JSON.parse(data, json_opts)]
|
110
|
+
rescue
|
111
|
+
[false, data]
|
113
112
|
end
|
114
113
|
|
115
114
|
def showHttpError(request, response)
|
116
115
|
if $cfg['tool.debug']
|
117
|
-
puts "Sent #{request.method} #{request.uri
|
118
|
-
request.each_capitalized{|k,v| puts "> #{k}: #{v}"}
|
116
|
+
puts "Sent #{request.method} #{request.uri}"
|
117
|
+
request.each_capitalized { |k, v| puts "> #{k}: #{v}" }
|
119
118
|
if request.body.nil?
|
120
119
|
else
|
121
120
|
puts ">> #{request.body[0..156]}"
|
122
121
|
end
|
123
122
|
puts "Got #{response.code} #{response.message}"
|
124
|
-
response.each_capitalized{|k,v| puts "< #{k}: #{v}"}
|
123
|
+
response.each_capitalized { |k, v| puts "< #{k}: #{v}" }
|
125
124
|
end
|
126
125
|
isj, jsn = isJSON(response.body)
|
127
126
|
resp = "Request Failed: #{response.code}: "
|
@@ -130,25 +129,25 @@ module MrMurano
|
|
130
129
|
# to support Ruby 3.0 frozen string literals.
|
131
130
|
if $cfg['tool.fullerror']
|
132
131
|
resp += JSON.pretty_generate(jsn)
|
133
|
-
elsif jsn.
|
134
|
-
resp += "[#{jsn[:statusCode]}] " if jsn.
|
135
|
-
resp += jsn[:message] if jsn.
|
132
|
+
elsif jsn.is_a? Hash
|
133
|
+
resp += "[#{jsn[:statusCode]}] " if jsn.key? :statusCode
|
134
|
+
resp += jsn[:message] if jsn.key? :message
|
136
135
|
else
|
137
136
|
resp += jsn.to_s
|
138
137
|
end
|
139
138
|
else
|
140
|
-
resp += (jsn
|
139
|
+
resp += (jsn || 'nil')
|
141
140
|
end
|
142
141
|
# assuming verbosing was included.
|
143
142
|
error resp
|
144
143
|
end
|
145
144
|
|
146
|
-
def workit(request
|
145
|
+
def workit(request)
|
147
146
|
curldebug(request)
|
148
147
|
if block_given?
|
149
|
-
yield request, http
|
148
|
+
yield request, http
|
150
149
|
else
|
151
|
-
response = http
|
150
|
+
response = http.request(request)
|
152
151
|
case response
|
153
152
|
when Net::HTTPSuccess
|
154
153
|
workit_response(response)
|
@@ -174,13 +173,13 @@ module MrMurano
|
|
174
173
|
def get(path='', query=nil, &block)
|
175
174
|
uri = endpoint(path)
|
176
175
|
uri.query = URI.encode_www_form(query) unless query.nil?
|
177
|
-
workit(
|
176
|
+
workit(add_headers(Net::HTTP::Get.new(uri)), &block)
|
178
177
|
end
|
179
178
|
|
180
179
|
def post(path='', body={}, &block)
|
181
180
|
uri = endpoint(path)
|
182
181
|
req = Net::HTTP::Post.new(uri)
|
183
|
-
|
182
|
+
add_headers(req)
|
184
183
|
req.body = JSON.generate(body)
|
185
184
|
workit(req, &block)
|
186
185
|
end
|
@@ -188,7 +187,7 @@ module MrMurano
|
|
188
187
|
def postf(path='', form={}, &block)
|
189
188
|
uri = endpoint(path)
|
190
189
|
req = Net::HTTP::Post.new(uri)
|
191
|
-
|
190
|
+
add_headers(req)
|
192
191
|
req.content_type = 'application/x-www-form-urlencoded; charset=utf-8'
|
193
192
|
req.form_data = form
|
194
193
|
workit(req, &block)
|
@@ -197,7 +196,7 @@ module MrMurano
|
|
197
196
|
def put(path='', body={}, &block)
|
198
197
|
uri = endpoint(path)
|
199
198
|
req = Net::HTTP::Put.new(uri)
|
200
|
-
|
199
|
+
add_headers(req)
|
201
200
|
req.body = JSON.generate(body)
|
202
201
|
workit(req, &block)
|
203
202
|
end
|
@@ -205,14 +204,14 @@ module MrMurano
|
|
205
204
|
def patch(path='', body={}, &block)
|
206
205
|
uri = endpoint(path)
|
207
206
|
req = Net::HTTP::Patch.new(uri)
|
208
|
-
|
207
|
+
add_headers(req)
|
209
208
|
req.body = JSON.generate(body)
|
210
209
|
workit(req, &block)
|
211
210
|
end
|
212
211
|
|
213
212
|
def delete(path='', &block)
|
214
213
|
uri = endpoint(path)
|
215
|
-
workit(
|
214
|
+
workit(add_headers(Net::HTTP::Delete.new(uri)), &block)
|
216
215
|
end
|
217
216
|
end
|
218
217
|
end
|
@@ -238,17 +237,17 @@ if RUBY_VERSION == '2.0.0'
|
|
238
237
|
end
|
239
238
|
|
240
239
|
D "opening connection to #{conn_address}:#{conn_port}..."
|
241
|
-
s = Timeout.timeout(@open_timeout, Net::OpenTimeout)
|
240
|
+
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
|
242
241
|
TCPSocket.open(conn_address, conn_port, @local_host, @local_port)
|
243
|
-
|
242
|
+
end
|
244
243
|
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
245
|
-
D
|
244
|
+
D 'opened'
|
246
245
|
if use_ssl?
|
247
|
-
ssl_parameters =
|
246
|
+
ssl_parameters = {}
|
248
247
|
iv_list = instance_variables
|
249
248
|
SSL_IVNAMES.each_with_index do |ivname, i|
|
250
|
-
if iv_list.include?(ivname)
|
251
|
-
|
249
|
+
if iv_list.include?(ivname)
|
250
|
+
value = instance_variable_get(ivname)
|
252
251
|
ssl_parameters[SSL_ATTRIBUTES[i]] = value if value
|
253
252
|
end
|
254
253
|
end
|
@@ -257,7 +256,7 @@ if RUBY_VERSION == '2.0.0'
|
|
257
256
|
D "starting SSL for #{conn_address}:#{conn_port}..."
|
258
257
|
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
|
259
258
|
s.sync_close = true
|
260
|
-
D
|
259
|
+
D 'SSL established'
|
261
260
|
end
|
262
261
|
@socket = BufferedIO.new(s)
|
263
262
|
@socket.read_timeout = @read_timeout
|
@@ -281,8 +280,8 @@ if RUBY_VERSION == '2.0.0'
|
|
281
280
|
end
|
282
281
|
# Server Name Indication (SNI) RFC 3546
|
283
282
|
s.hostname = @address if s.respond_to? :hostname=
|
284
|
-
if @ssl_session
|
285
|
-
|
283
|
+
if @ssl_session &&
|
284
|
+
Time.now < @ssl_session.time + @ssl_session.timeout
|
286
285
|
s.session = @ssl_session if @ssl_session
|
287
286
|
end
|
288
287
|
Timeout.timeout(@open_timeout, Net::OpenTimeout) { s.connect }
|
@@ -292,7 +291,7 @@ if RUBY_VERSION == '2.0.0'
|
|
292
291
|
@ssl_session = s.session
|
293
292
|
rescue => exception
|
294
293
|
D "Conn close because of connect error #{exception}"
|
295
|
-
@socket.close if @socket
|
294
|
+
@socket.close if @socket && !@socket.closed?
|
296
295
|
raise exception
|
297
296
|
end
|
298
297
|
end
|