marty 2.3.15 → 2.4.0
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 +4 -4
- data/Gemfile.lock +2 -2
- data/app/components/marty/api_auth_view.rb +27 -4
- data/app/components/marty/api_config_view.rb +27 -4
- data/app/components/marty/extras/layout.rb +4 -7
- data/app/components/marty/form.rb +8 -0
- data/app/components/marty/grid.rb +45 -19
- data/app/components/marty/main_auth_app.rb +12 -11
- data/app/controllers/marty/rpc_controller.rb +63 -150
- data/app/models/marty/api_auth.rb +86 -14
- data/app/models/marty/api_config.rb +11 -6
- data/app/models/marty/delorean_rule.rb +3 -2
- data/config/routes.rb +1 -1
- data/db/migrate/501_add_api_class_to_marty_api_config.rb +6 -0
- data/db/migrate/502_add_parameters_to_marty_api_auth.rb +5 -0
- data/lib/marty/util.rb +0 -15
- data/lib/marty/version.rb +1 -1
- data/other/marty/api/base.rb +207 -0
- data/other/marty/diagnostic/aws/ec2_instance.rb +12 -87
- data/other/marty/diagnostic/environment_variables.rb +1 -1
- data/spec/controllers/job_controller_spec.rb +1 -1
- data/spec/dummy/app/components/gemini/xyz_rule_view.rb +1 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/features/enum_spec.rb +35 -100
- data/spec/features/log_view_spec.rb +5 -5
- data/spec/features/rule_spec.rb +30 -30
- data/spec/features/user_view_spec.rb +0 -2
- data/spec/lib/logger_spec.rb +1 -1
- data/spec/models/api_auth_spec.rb +33 -12
- data/spec/models/event_spec.rb +1 -1
- data/spec/models/promise_spec.rb +1 -1
- data/spec/models/user_spec.rb +6 -6
- data/spec/spec_helper.rb +69 -9
- data/spec/support/{shared_connection_db_helpers.rb → clean_db_helpers.rb} +2 -2
- data/spec/support/delayed_job_helpers.rb +1 -1
- data/spec/support/{users.rb → integration_helpers.rb} +9 -11
- data/spec/support/{setup.rb → spec_setup.rb} +6 -19
- data/spec/support/user_helpers.rb +12 -0
- metadata +10 -21
- data/spec/dummy/app/assets/client/application.css +0 -13
- data/spec/dummy/app/assets/client/application.js +0 -15
- data/spec/support/chromedriver.rb +0 -41
- data/spec/support/components/netzke_combobox.rb +0 -57
- data/spec/support/components/netzke_grid.rb +0 -356
- data/spec/support/custom_matchers.rb +0 -18
- data/spec/support/custom_selectors.rb +0 -49
- data/spec/support/download_helper.rb +0 -52
- data/spec/support/helper.rb +0 -20
- data/spec/support/netzke.rb +0 -306
- data/spec/support/performance_helper.rb +0 -26
- data/spec/support/post_run_logger.rb +0 -32
- data/spec/support/shared_connection.rb +0 -31
- data/spec/support/structure_compare.rb +0 -62
- data/spec/support/suite.rb +0 -27
@@ -1,11 +1,11 @@
|
|
1
1
|
class Marty::ApiAuth < Marty::Base
|
2
2
|
has_mcfly
|
3
3
|
|
4
|
+
belongs_to :entity, polymorphic: true, optional: true
|
5
|
+
|
4
6
|
KEY_SIZE = 19
|
5
7
|
|
6
|
-
|
7
|
-
SecureRandom.hex(KEY_SIZE)
|
8
|
-
end
|
8
|
+
validates_presence_of :app_name, :api_key, :script_name
|
9
9
|
|
10
10
|
class ApiAuthValidator < ActiveModel::Validator
|
11
11
|
def validate(api)
|
@@ -17,24 +17,96 @@ class Marty::ApiAuth < Marty::Base
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
validates_with ApiAuthValidator
|
21
|
+
|
22
|
+
mcfly_validates_uniqueness_of :api_key, scope: [:script_name]
|
23
|
+
validates_uniqueness_of :app_name, scope: [:script_name,
|
24
|
+
:obsoleted_dt]
|
25
|
+
|
26
|
+
|
20
27
|
before_validation do
|
21
28
|
self.api_key = Marty::ApiAuth.generate_key if
|
22
29
|
self.api_key.nil? || self.api_key.length == 0
|
23
30
|
end
|
24
31
|
|
25
|
-
|
32
|
+
before_save do
|
33
|
+
return unless changed.include?(:entity_id) && !parameters['aws_api_key']
|
26
34
|
|
27
|
-
|
35
|
+
msg = 'API Auth must be associated with an AWS API KEY before '\
|
36
|
+
'it can be associated with an entity'
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
|
38
|
+
errors.add(:base, msg)
|
39
|
+
end
|
40
|
+
|
41
|
+
before_destroy do
|
42
|
+
next unless aws = parameters['aws_api_key']
|
43
|
+
begin
|
44
|
+
client = Marty::Aws::Apigateway.new
|
45
|
+
resp = client.delete_usage_plan_key(aws['api_usage_plan_id'],
|
46
|
+
aws['aid'])
|
47
|
+
client.delete_api_key(aws['aid']) if resp
|
48
|
+
rescue => e
|
49
|
+
Marty::Logger.log('api_test', 'error', e.message)
|
50
|
+
throw :abort unless e.message.include?('Invalid API Key')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.generate_key
|
55
|
+
SecureRandom.hex(KEY_SIZE)
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_aws_api_key api_id, api_usage_plan_id
|
59
|
+
client = Marty::Aws::Apigateway.new
|
60
|
+
app_id = Marty::Config['AWS_APP_IDENTIFIER'] || 'marty'
|
61
|
+
name = "#{app_id}-#{api_id}-#{api_key[0..3]}"
|
62
|
+
|
63
|
+
key = nil
|
64
|
+
begin
|
65
|
+
key = client.create_api_key(name, 'marty_api_key', api_key)
|
66
|
+
rescue => e
|
67
|
+
#Marty::Logger.log('api_test', 'error', e.message)
|
68
|
+
end
|
69
|
+
|
70
|
+
upkey = nil
|
71
|
+
begin
|
72
|
+
upkey = key &&
|
73
|
+
client.create_usage_plan_key(api_usage_plan_id, key.id)
|
74
|
+
rescue => e
|
75
|
+
#Marty::Logger.log('api_test', 'error', e.message)
|
76
|
+
# remove api key we created
|
77
|
+
client.delete_api_key(key.id)
|
78
|
+
end
|
79
|
+
|
80
|
+
raise "Unable to create AWS API Key" unless key && upkey
|
81
|
+
|
82
|
+
parameters['aws_api_key'] = {
|
83
|
+
'aid' => key.id,
|
84
|
+
'api_usage_plan_id' => api_usage_plan_id,
|
85
|
+
'api_id' => api_id,
|
86
|
+
}
|
87
|
+
|
88
|
+
save!
|
89
|
+
end
|
90
|
+
|
91
|
+
def move_aws_key usage_plan_id
|
92
|
+
return unless aws = parameters['aws_api_key']
|
93
|
+
return if aws['api_usage_plan_id'] == usage_plan_id
|
94
|
+
|
95
|
+
begin
|
96
|
+
client = Marty::Aws::Apigateway.new
|
97
|
+
resp = client.delete_usage_plan_key(aws['api_usage_plan_id'],
|
98
|
+
aws['aid'])
|
99
|
+
rescue => e
|
100
|
+
# on fail recreate usage plan key
|
101
|
+
Marty::Logger.log('api', 'api_test', aws)
|
102
|
+
client.create_usage_plan_key(aws['api_usage_plan_id'], aws['aid']) if
|
103
|
+
client
|
104
|
+
return
|
105
|
+
else
|
106
|
+
client.create_usage_plan_key(usage_plan_id, aws['aid']) if resp
|
107
|
+
end
|
32
108
|
|
33
|
-
|
34
|
-
|
35
|
-
obsoleted_dt: 'infinity').exists?
|
36
|
-
!is_secured || where(api_key: api_key,
|
37
|
-
script_name: script_name,
|
38
|
-
obsoleted_dt: 'infinity').pluck(:app_name).first
|
109
|
+
parameters['aws_api_key'] += {'api_usage_plan_id' => usage_plan_id}
|
110
|
+
save!
|
39
111
|
end
|
40
112
|
end
|
@@ -3,13 +3,18 @@ class Marty::ApiConfig < Marty::Base
|
|
3
3
|
|
4
4
|
def self.lookup(script, node, attr)
|
5
5
|
res = where(["script = ? AND (node IS NULL OR node = ?) "\
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
"AND (attr IS NULL OR attr = ?)",
|
7
|
+
script, node, attr]).
|
8
|
+
order('node nulls last, attr nulls last').first
|
9
|
+
|
10
|
+
res && res.as_json.except('id',
|
11
|
+
'created_at',
|
12
|
+
'updated_at',
|
13
|
+
'script',
|
14
|
+
'node',
|
15
|
+
'attr').symbolize_keys
|
12
16
|
end
|
17
|
+
|
13
18
|
def self.multi_lookup(script, node, attrs)
|
14
19
|
(attrs.nil? ? [nil] : attrs).
|
15
20
|
map { |attr| lookup(script, node, attr).try{|x| x.unshift(attr) }}
|
@@ -152,9 +152,10 @@ class Marty::DeloreanRule < Marty::BaseRule
|
|
152
152
|
estack_full = resh.delete(:err_stack)
|
153
153
|
estack = estack_full && {
|
154
154
|
err_stack: estack_full.select{ |l| l.starts_with?('DELOREAN')}} || {}
|
155
|
-
detail = { input: params, dgparams: dgparams} + resh + estack
|
156
155
|
Marty::Logger.info("Rule Log #{ruleh['name']}",
|
157
|
-
|
156
|
+
{ input: params,
|
157
|
+
dgparams: dgparams } + resh + estack
|
158
|
+
)
|
158
159
|
end
|
159
160
|
end
|
160
161
|
end
|
data/config/routes.rb
CHANGED
@@ -6,5 +6,5 @@ Marty::Engine.routes.draw do
|
|
6
6
|
match via: [:get, :post], "rpc/evaluate(.:format)" => "rpc", as: :rpc
|
7
7
|
match via: [:get, :post], "report(.:format)" => "report#index", as: :report
|
8
8
|
get 'job/download' => 'job', as: :job
|
9
|
-
get 'diag',
|
9
|
+
get 'diag', to: 'diagnostic/#op'
|
10
10
|
end
|
data/lib/marty/util.rb
CHANGED
@@ -132,19 +132,4 @@ module Marty::Util
|
|
132
132
|
URI.encode("#{Marty::Util.marty_path}/report?data=#{data}"\
|
133
133
|
"&reptitle=#{title}&format=#{format}")
|
134
134
|
end
|
135
|
-
|
136
|
-
def self.scrub_obj(obj)
|
137
|
-
trav = lambda {|o|
|
138
|
-
if o.is_a?(Hash)
|
139
|
-
return o.each_with_object({}) {|(k, v), h| h[k] = trav.call(v)}
|
140
|
-
elsif o.is_a?(Array)
|
141
|
-
return o.map {|v| trav.call(v)}
|
142
|
-
elsif o.to_s.length > 10000
|
143
|
-
o.class.to_s
|
144
|
-
else
|
145
|
-
o
|
146
|
-
end
|
147
|
-
}
|
148
|
-
trav.call(obj)
|
149
|
-
end
|
150
135
|
end
|
data/lib/marty/version.rb
CHANGED
@@ -0,0 +1,207 @@
|
|
1
|
+
class Marty::Api::Base
|
2
|
+
mattr_accessor :class_list
|
3
|
+
@@class_list ||= [name].to_set
|
4
|
+
|
5
|
+
def self.inherited(klass)
|
6
|
+
@@class_list << klass.to_s
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.respond_to controller
|
11
|
+
result = yield
|
12
|
+
controller.respond_to do |format|
|
13
|
+
format.json { controller.send_data result.to_json }
|
14
|
+
format.csv {
|
15
|
+
# SEMI-HACKY: strip outer list if there's only one element.
|
16
|
+
result = result[0] if result.is_a?(Array) && result.length==1
|
17
|
+
controller.send_data Marty::DataExporter.to_csv(result)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# api handles
|
23
|
+
def self.process_params params
|
24
|
+
params
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.before_evaluate api_params
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.after_evaluate api_params, result
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.is_authorized? params
|
34
|
+
is_secured = Marty::ApiAuth.where(
|
35
|
+
script_name: params[:script],
|
36
|
+
obsoleted_dt: 'infinity'
|
37
|
+
).exists?
|
38
|
+
|
39
|
+
!is_secured || Marty::ApiAuth.where(
|
40
|
+
api_key: params[:api_key],
|
41
|
+
script_name: params[:script],
|
42
|
+
obsoleted_dt: 'infinity'
|
43
|
+
).pluck(:app_name).first
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.evaluate params, request, config
|
47
|
+
# validate input schema
|
48
|
+
if config[:input_validated]
|
49
|
+
begin
|
50
|
+
schema = SchemaValidator::get_schema(params)
|
51
|
+
rescue => e
|
52
|
+
return {error: e.message}
|
53
|
+
end
|
54
|
+
|
55
|
+
begin
|
56
|
+
res = SchemaValidator::validate_schema(schema, params[:params])
|
57
|
+
rescue NameError
|
58
|
+
return {error: "Unrecognized PgEnum for attribute #{params[:attr]}"}
|
59
|
+
rescue => e
|
60
|
+
return {error: "#{params[:attr]}: #{e.message}"}
|
61
|
+
end
|
62
|
+
|
63
|
+
schema_errors = SchemaValidator::get_errors(res) unless res.empty?
|
64
|
+
return {error: "Error(s) validating: #{schema_errors}"} if
|
65
|
+
schema_errors
|
66
|
+
end
|
67
|
+
|
68
|
+
# get script engine
|
69
|
+
begin
|
70
|
+
engine = Marty::ScriptSet.new(params[:tag]).get_engine(params[:script])
|
71
|
+
rescue => e
|
72
|
+
error = "Can't get engine: #{params[:script] || 'nil'} with tag: " +
|
73
|
+
"#{params[:tag] || 'nil'}; message: #{e.message}"
|
74
|
+
Marty::Logger.info error
|
75
|
+
return {error: error}
|
76
|
+
end
|
77
|
+
|
78
|
+
retval = nil
|
79
|
+
|
80
|
+
# evaluate script
|
81
|
+
begin
|
82
|
+
if params[:background]
|
83
|
+
res = engine.background_eval(params[:node],
|
84
|
+
params[:params],
|
85
|
+
params[:attr])
|
86
|
+
|
87
|
+
return retval = {"job_id" => res.__promise__.id}
|
88
|
+
end
|
89
|
+
|
90
|
+
res = engine.evaluate(params[:node],
|
91
|
+
params[:attr],
|
92
|
+
params[:params])
|
93
|
+
|
94
|
+
# validate output schema
|
95
|
+
if config[:output_validated] && !(res.is_a?(Hash) && res['error'])
|
96
|
+
begin
|
97
|
+
output_schema_params = params + {attr: params[:attr] + '_'}
|
98
|
+
schema = SchemaValidator::get_schema(output_schema_params)
|
99
|
+
rescue => e
|
100
|
+
return {error: e.message}
|
101
|
+
end
|
102
|
+
|
103
|
+
begin
|
104
|
+
schema_errors = SchemaValidator::validate_schema(schema, res)
|
105
|
+
rescue NameError
|
106
|
+
return {error: "Unrecognized PgEnum for attribute #{attr}"}
|
107
|
+
rescue => e
|
108
|
+
return {error: "#{attr}: #{e.message}"}
|
109
|
+
end
|
110
|
+
|
111
|
+
if schema_errors.present?
|
112
|
+
errors = schema_errors.map{|e| e[:message]}
|
113
|
+
|
114
|
+
Marty::Logger.error(
|
115
|
+
"API #{params[:script]}:#{params[:node]}.#{params[:attr]}",
|
116
|
+
{error: errors, data: res}
|
117
|
+
)
|
118
|
+
|
119
|
+
msg = "Error(s) validating: #{errors}"
|
120
|
+
res = config[:strict_validate] ? {error: msg ,data: res} : res
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# if attr is an array, return result as an array
|
125
|
+
return retval = params[:return_array] ? [res] : res
|
126
|
+
|
127
|
+
rescue => e
|
128
|
+
msg = Delorean::Engine.grok_runtime_exception(e).symbolize_keys
|
129
|
+
Marty::Logger.info "Evaluation error: #{msg}"
|
130
|
+
return retval = msg
|
131
|
+
ensure
|
132
|
+
error = Hash === retval ? retval[:error] : nil
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.log result, params, request
|
137
|
+
ret_arr = params[:return_array]
|
138
|
+
Marty::Log.write_log('api',
|
139
|
+
params.values_at(:script, :node, :attr).join(' - '),
|
140
|
+
{script: params[:script],
|
141
|
+
node: params[:node],
|
142
|
+
attrs: ret_arr ? [params[:attr]] : params[:attr],
|
143
|
+
input: params[:params],
|
144
|
+
output: (result.is_a?(Hash) &&
|
145
|
+
result.include?('error')) ? nil : result,
|
146
|
+
start_time: params[:start_time],
|
147
|
+
end_time: Time.zone.now,
|
148
|
+
error: (result.is_a?(Hash) &&
|
149
|
+
result.include?('error')) ? result : nil,
|
150
|
+
remote_ip: request.remote_ip,
|
151
|
+
auth_name: params[:auth]
|
152
|
+
})
|
153
|
+
end
|
154
|
+
|
155
|
+
class SchemaValidator
|
156
|
+
def self.get_schema params
|
157
|
+
begin
|
158
|
+
Marty::ScriptSet.new(params[:tag]).get_engine(params[:script]+'Schemas').
|
159
|
+
evaluate(params[:node], params[:attr], {})
|
160
|
+
rescue => e
|
161
|
+
msg = e.message == 'No such script' ? 'Schema not defined' :
|
162
|
+
'Problem with schema: ' + e.message
|
163
|
+
|
164
|
+
raise "Schema error for #{params[:script]}/#{params[:node]} "\
|
165
|
+
"attrs=#{params[:attr]}: #{msg}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.validate_schema schema, hash
|
170
|
+
JSON::Validator.fully_validate(
|
171
|
+
schema.merge({"\$schema" => Marty::JsonSchema::RAW_URI}),
|
172
|
+
hash,
|
173
|
+
validate_schema: true,
|
174
|
+
errors_as_objects: true,
|
175
|
+
version: Marty::JsonSchema::RAW_URI,
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.massage_message(msg)
|
180
|
+
m = %r|'#/([^']+)' of type ([^ ]+) matched the disallowed schema|.
|
181
|
+
match(msg)
|
182
|
+
|
183
|
+
return msg unless m
|
184
|
+
"disallowed parameter '#{m[1]}' of type #{m[2]} was received"
|
185
|
+
end
|
186
|
+
|
187
|
+
def self._get_errors(errs)
|
188
|
+
if errs.is_a?(Array)
|
189
|
+
errs.map { |err| _get_errors(err) }
|
190
|
+
elsif errs.is_a?(Hash)
|
191
|
+
if !errs.include?(:failed_attribute)
|
192
|
+
errs.map { |k, v| _get_errors(v) }
|
193
|
+
else
|
194
|
+
fa, fragment, message, errors = errs.values_at(:failed_attribute,
|
195
|
+
:fragment,
|
196
|
+
:message, :errors)
|
197
|
+
((['AllOf','AnyOf','Not'].include?(fa) && fragment =='#/') ?
|
198
|
+
[] : [massage_message(message)]) + _get_errors(errors || {})
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def self.get_errors(errs)
|
204
|
+
_get_errors(errs).flatten
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -1,13 +1,8 @@
|
|
1
|
-
class Marty::Diagnostic::Aws::Ec2Instance
|
1
|
+
class Marty::Diagnostic::Aws::Ec2Instance < Marty::Aws::Base
|
2
2
|
# aws reserved host used to get instance meta-data
|
3
3
|
META_DATA_HOST = '169.254.169.254'
|
4
4
|
|
5
|
-
attr_reader :
|
6
|
-
:doc,
|
7
|
-
:role,
|
8
|
-
:creds,
|
9
|
-
:version,
|
10
|
-
:host,
|
5
|
+
attr_reader :host,
|
11
6
|
:tag,
|
12
7
|
:nodes,
|
13
8
|
:instances
|
@@ -33,76 +28,18 @@ class Marty::Diagnostic::Aws::Ec2Instance
|
|
33
28
|
end
|
34
29
|
end
|
35
30
|
|
36
|
-
def self.is_aws?
|
37
|
-
response = get("http://#{META_DATA_HOST}") rescue nil
|
38
|
-
response.present?
|
39
|
-
end
|
40
|
-
|
41
31
|
def initialize
|
42
|
-
|
43
|
-
@
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
47
|
-
@version = '2016-11-15'
|
48
|
-
@tag = get_tag
|
49
|
-
@instances = InstancesSet.new(get_instances)
|
50
|
-
@nodes = get_private_ips
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.get url
|
54
|
-
uri = URI.parse(url)
|
55
|
-
request = Net::HTTP.new(uri.host, uri.port)
|
56
|
-
request.read_timeout = request.open_timeout = ENV['DIAG_TIMEOUT'] || 0.25
|
57
|
-
request.start {|http|
|
58
|
-
http.get(uri.to_s)
|
59
|
-
}.body
|
60
|
-
end
|
61
|
-
|
62
|
-
def query_meta_data query
|
63
|
-
self.class.get("http://#{META_DATA_HOST}/latest/meta-data/#{query}/")
|
64
|
-
end
|
65
|
-
|
66
|
-
def query_dynamic query
|
67
|
-
self.class.get("http://#{META_DATA_HOST}/latest/dynamic/#{query}/")
|
32
|
+
super
|
33
|
+
@service = 'ec2'
|
34
|
+
@tag = get_tag
|
35
|
+
@instances = InstancesSet.new(get_instances)
|
36
|
+
@nodes = get_private_ips
|
68
37
|
end
|
69
38
|
|
70
39
|
private
|
71
|
-
def get_instance_id
|
72
|
-
query_meta_data('instance-id').to_s
|
73
|
-
end
|
74
|
-
|
75
|
-
def get_role
|
76
|
-
query_meta_data('iam/security-credentials').to_s
|
77
|
-
end
|
78
|
-
|
79
|
-
def get_credentials
|
80
|
-
JSON.parse(query_meta_data("iam/security-credentials/#{@role}"))
|
81
|
-
end
|
82
|
-
|
83
|
-
def get_document
|
84
|
-
JSON.parse(query_dynamic('instance-identity/document'))
|
85
|
-
end
|
86
|
-
|
87
40
|
def ec2_request action, params = {}
|
88
|
-
|
89
|
-
|
90
|
-
'Version' => @version
|
91
|
-
}
|
92
|
-
|
93
|
-
url = "https://#{@host}/?" +
|
94
|
-
(default + params).map{|a, v| "#{a}=#{v}"}.join('&')
|
95
|
-
|
96
|
-
sig = Aws::Sigv4::Signer.new(service: 'ec2',
|
97
|
-
region: @doc['region'],
|
98
|
-
access_key_id: @creds['AccessKeyId'],
|
99
|
-
secret_access_key: @creds['SecretAccessKey'],
|
100
|
-
session_token: @creds['Token'])
|
101
|
-
signed_url = sig.presign_url(http_method:'GET', url: url)
|
102
|
-
|
103
|
-
http = Net::HTTP.new(@host, 443)
|
104
|
-
http.use_ssl = true
|
105
|
-
Hash.from_xml(Net::HTTP.get(signed_url))["#{action}Response"]
|
41
|
+
resp = request({action: action}, params)
|
42
|
+
Hash.from_xml(resp)["#{action}Response"]
|
106
43
|
end
|
107
44
|
|
108
45
|
def get_tag
|
@@ -117,9 +54,11 @@ class Marty::Diagnostic::Aws::Ec2Instance
|
|
117
54
|
params = {'Filter.1.Name' => 'tag-value',
|
118
55
|
'Filter.1.Value.1' => @tag}
|
119
56
|
|
57
|
+
resp = ec2_request('DescribeInstances', params)
|
58
|
+
|
120
59
|
instances = ensure_resp(
|
121
60
|
['reservationSet', 'item', 'instancesSet', 'item'],
|
122
|
-
|
61
|
+
resp
|
123
62
|
).map do |i|
|
124
63
|
{
|
125
64
|
'id' => i['instanceId'],
|
@@ -132,18 +71,4 @@ class Marty::Diagnostic::Aws::Ec2Instance
|
|
132
71
|
def get_private_ips
|
133
72
|
@instances.running.map{|i| i['ip']}.compact
|
134
73
|
end
|
135
|
-
|
136
|
-
def ensure_resp path, obj
|
137
|
-
if path == []
|
138
|
-
obj.is_a?(Array) ? obj : [obj]
|
139
|
-
elsif obj.is_a?(Hash)
|
140
|
-
key = path.shift
|
141
|
-
raise "Unexpected AWS Response: #{key} missing" unless
|
142
|
-
(obj.is_a?(Hash) && obj[key])
|
143
|
-
|
144
|
-
ensure_resp(path, obj[key])
|
145
|
-
else
|
146
|
-
obj.map{|s| ensure_resp(path.clone, s)}.flatten(1)
|
147
|
-
end
|
148
|
-
end
|
149
74
|
end
|