marty 2.5.2 → 2.5.4
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 +5 -5
- data/.gitignore +4 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +11 -589
- data/Gemfile +9 -9
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -3
- data/app/components/marty/api_auth_view.rb +3 -3
- data/app/components/marty/api_config_view.rb +8 -8
- data/app/components/marty/api_log_view.rb +16 -20
- data/app/components/marty/auth_app.rb +6 -6
- data/app/components/marty/base_rule_view.rb +27 -19
- data/app/components/marty/config_view.rb +12 -9
- data/app/components/marty/data_grid_view.rb +26 -26
- data/app/components/marty/delorean_rule_view.rb +0 -1
- data/app/components/marty/event_view.rb +27 -27
- data/app/components/marty/extras/layout.rb +26 -26
- data/app/components/marty/extras/misc.rb +2 -2
- data/app/components/marty/grid.rb +13 -13
- data/app/components/marty/grid_append_only.rb +0 -1
- data/app/components/marty/import_type_view.rb +13 -13
- data/app/components/marty/import_view.rb +17 -16
- data/app/components/marty/log_view.rb +16 -14
- data/app/components/marty/main_auth_app.rb +59 -59
- data/app/components/marty/main_auth_app/client/main_auth_app.js +3 -3
- data/app/components/marty/mcfly_grid_panel.rb +10 -10
- data/app/components/marty/new_posting_form.rb +11 -11
- data/app/components/marty/new_posting_window.rb +0 -1
- data/app/components/marty/posting_grid.rb +12 -13
- data/app/components/marty/promise_view.rb +6 -6
- data/app/components/marty/report_form.rb +50 -53
- data/app/components/marty/report_select.rb +27 -27
- data/app/components/marty/reporting.rb +4 -4
- data/app/components/marty/script_form.rb +40 -42
- data/app/components/marty/script_grid.rb +24 -24
- data/app/components/marty/script_tester.rb +40 -42
- data/app/components/marty/scripting.rb +25 -27
- data/app/components/marty/simple_app.rb +24 -9
- data/app/components/marty/tag_grid.rb +12 -13
- data/app/components/marty/user_view.rb +35 -35
- data/app/controllers/marty/application_controller.rb +3 -4
- data/app/controllers/marty/components_controller.rb +1 -1
- data/app/controllers/marty/delayed_job_controller.rb +1 -0
- data/app/controllers/marty/diagnostic/controller.rb +4 -6
- data/app/controllers/marty/job_controller.rb +6 -6
- data/app/controllers/marty/report_controller.rb +11 -11
- data/app/controllers/marty/rpc_controller.rb +15 -16
- data/app/helpers/marty/script_set.rb +4 -4
- data/app/models/marty/api_auth.rb +4 -5
- data/app/models/marty/api_config.rb +1 -1
- data/app/models/marty/base.rb +9 -8
- data/app/models/marty/base_rule.rb +18 -13
- data/app/models/marty/config.rb +4 -5
- data/app/models/marty/data_grid.rb +157 -181
- data/app/models/marty/delorean_rule.rb +63 -62
- data/app/models/marty/enum.rb +1 -1
- data/app/models/marty/event.rb +56 -59
- data/app/models/marty/helper.rb +38 -6
- data/app/models/marty/import_type.rb +6 -6
- data/app/models/marty/log.rb +3 -2
- data/app/models/marty/name_validator.rb +3 -2
- data/app/models/marty/pg_enum.rb +3 -4
- data/app/models/marty/posting.rb +20 -24
- data/app/models/marty/promise.rb +28 -30
- data/app/models/marty/script.rb +30 -28
- data/app/models/marty/tag.rb +8 -8
- data/app/models/marty/token.rb +2 -2
- data/app/models/marty/user.rb +24 -23
- data/app/models/marty/vw_promise.rb +10 -11
- data/config/routes.rb +2 -2
- data/delorean/blame_report.dl +268 -0
- data/{spec/dummy/delorean/fields.dl → delorean/marty_fields.dl} +8 -0
- data/delorean/table_report.dl +34 -0
- data/docker-compose.dummy.yml +2 -3
- data/lib/marty/aws/base.rb +8 -8
- data/lib/marty/aws/request.rb +4 -4
- data/lib/marty/cache_adapters/mcfly_ruby_cache.rb +1 -0
- data/lib/marty/content_handler.rb +25 -25
- data/lib/marty/data_change.rb +49 -71
- data/lib/marty/data_conversion.rb +20 -28
- data/lib/marty/data_exporter.rb +25 -28
- data/lib/marty/data_importer.rb +25 -27
- data/lib/marty/engine.rb +1 -2
- data/lib/marty/json_schema.rb +22 -24
- data/lib/marty/logger.rb +6 -9
- data/lib/marty/mcfly_model.rb +20 -24
- data/lib/marty/migrations.rb +37 -35
- data/lib/marty/monkey.rb +33 -33
- data/lib/marty/permissions.rb +18 -18
- data/lib/marty/promise_job.rb +17 -17
- data/lib/marty/promise_proxy.rb +6 -6
- data/lib/marty/relation.rb +6 -7
- data/lib/marty/rpc_call.rb +13 -12
- data/lib/marty/rule_script_set.rb +32 -28
- data/lib/marty/schema_helper.rb +37 -51
- data/lib/marty/util.rb +25 -24
- data/lib/marty/version.rb +1 -1
- data/lib/marty/xl.rb +121 -115
- data/make-dummy.mk +3 -0
- data/marty.gemspec +21 -21
- data/other/marty/api/base.rb +34 -35
- data/other/marty/diagnostic/aws/ec2_instance.rb +8 -8
- data/other/marty/diagnostic/base.rb +13 -14
- data/other/marty/diagnostic/collection.rb +2 -1
- data/other/marty/diagnostic/connections.rb +8 -6
- data/other/marty/diagnostic/database.rb +1 -0
- data/other/marty/diagnostic/delayed_job_version.rb +7 -9
- data/other/marty/diagnostic/delayed_job_worker_total_count.rb +1 -1
- data/other/marty/diagnostic/delayed_job_workers.rb +1 -1
- data/other/marty/diagnostic/environment_variables.rb +17 -15
- data/other/marty/diagnostic/fatal.rb +1 -1
- data/other/marty/diagnostic/node.rb +5 -9
- data/other/marty/diagnostic/nodes.rb +7 -5
- data/other/marty/diagnostic/packer.rb +7 -7
- data/other/marty/diagnostic/reporter.rb +24 -27
- data/other/marty/diagnostic/version.rb +3 -5
- data/script/rails +2 -1
- data/spec/controllers/application_controller_spec.rb +6 -6
- data/spec/controllers/delayed_job_controller_spec.rb +4 -4
- data/spec/controllers/diagnostic/controller_spec.rb +59 -60
- data/spec/controllers/job_controller_spec.rb +68 -69
- data/spec/controllers/rpc_controller_spec.rb +353 -359
- data/spec/controllers/rpc_import_spec.rb +15 -16
- data/spec/dummy/delorean/blame_report.dl +110 -15
- data/spec/dummy/delorean/data_report.dl +4 -4
- data/spec/dummy/delorean/marty_fields.dl +63 -0
- data/spec/dummy/delorean/table_report.dl +34 -0
- data/spec/features/auth_app_spec.rb +1 -2
- data/spec/features/data_import_spec.rb +2 -3
- data/spec/features/enum_spec.rb +42 -46
- data/spec/features/jobs_dashboard_spec.rb +14 -8
- data/spec/features/log_view_spec.rb +40 -43
- data/spec/features/reporting_spec.rb +15 -15
- data/spec/features/rule_spec.rb +195 -190
- data/spec/features/scripting_spec.rb +17 -20
- data/spec/features/scripting_test_spec.rb +32 -33
- data/spec/features/user_view_spec.rb +15 -17
- data/spec/job_helper.rb +11 -11
- data/spec/lib/data_blame_spec.rb +82 -0
- data/spec/lib/data_exporter_spec.rb +31 -32
- data/spec/lib/data_importer_spec.rb +382 -395
- data/spec/lib/delorean_query_spec.rb +117 -119
- data/spec/lib/json_schema_spec.rb +382 -392
- data/spec/lib/logger_spec.rb +23 -24
- data/spec/lib/mcfly_model_spec.rb +112 -109
- data/spec/lib/migrations_spec.rb +10 -10
- data/spec/lib/struct_compare_spec.rb +6 -6
- data/spec/lib/table_report_spec.rb +90 -0
- data/spec/lib/xl_spec.rb +63 -65
- data/spec/lib/xl_styles_spec.rb +16 -19
- data/spec/models/api_auth_spec.rb +30 -30
- data/spec/models/config_spec.rb +32 -32
- data/spec/models/data_grid_spec.rb +642 -655
- data/spec/models/event_spec.rb +96 -88
- data/spec/models/import_type_spec.rb +20 -20
- data/spec/models/posting_spec.rb +35 -35
- data/spec/models/promise_spec.rb +5 -5
- data/spec/models/rule_spec.rb +280 -269
- data/spec/models/script_spec.rb +27 -18
- data/spec/models/user_spec.rb +9 -9
- data/spec/other/diagnostic/base_spec.rb +20 -19
- data/spec/other/diagnostic/collection_spec.rb +6 -5
- data/spec/other/diagnostic/delayed_job_version_spec.rb +1 -1
- data/spec/other/diagnostic/delayed_job_workers_spec.rb +8 -8
- data/spec/other/diagnostic/reporter_spec.rb +31 -33
- data/spec/spec_helper.rb +5 -5
- data/spec/support/chromedriver.rb +3 -5
- data/spec/support/components/netzke_combobox.rb +1 -1
- data/spec/support/components/netzke_grid.rb +17 -17
- data/spec/support/custom_matchers.rb +2 -2
- data/spec/support/download_helper.rb +1 -1
- data/spec/support/helper.rb +1 -2
- data/spec/support/netzke.rb +31 -31
- data/spec/support/performance_helper.rb +8 -8
- data/spec/support/post_run_logger.rb +1 -2
- data/spec/support/setup.rb +1 -4
- data/spec/support/shared_connection.rb +2 -2
- data/spec/support/structure_compare.rb +21 -22
- data/spec/support/suite.rb +1 -2
- data/spec/support/users.rb +5 -6
- metadata +32 -26
|
@@ -4,7 +4,7 @@ module Marty::Diagnostic; class DelayedJobWorkerTotalCount < Base
|
|
|
4
4
|
[c['application_name'], c['client_addr'] || '127.0.0.1'] if
|
|
5
5
|
c['application_name'].include?('delayed')
|
|
6
6
|
end.compact.uniq.count
|
|
7
|
-
{'Delayed Workers' => count.zero? ? error(count) : count}
|
|
7
|
+
{ 'Delayed Workers' => count.zero? ? error(count) : count }
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
end
|
|
@@ -6,7 +6,7 @@ module Marty::Diagnostic; class DelayedJobWorkers < Base
|
|
|
6
6
|
name = c['application_name']
|
|
7
7
|
name if name.include?('delayed') && (ip == my_ip || ip == '127.0.0.1')
|
|
8
8
|
end.compact.uniq.count
|
|
9
|
-
{'Delayed Workers / Node' => workers.zero? ? error(workers) : workers}
|
|
9
|
+
{ 'Delayed Workers / Node' => workers.zero? ? error(workers) : workers }
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -3,37 +3,39 @@ module Marty::Diagnostic; class EnvironmentVariables < Base
|
|
|
3
3
|
env
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
-
def self.env filter=''
|
|
6
|
+
def self.env filter = ''
|
|
7
7
|
env = ENV.clone
|
|
8
8
|
|
|
9
9
|
to_delete = (Marty::Config['DIAG_ENV_BLOCK'] || []).map(&:upcase) + [
|
|
10
|
-
'SCRIPT_URI', 'SCRIPT_URL'
|
|
10
|
+
'SCRIPT_URI', 'SCRIPT_URL'
|
|
11
|
+
]
|
|
11
12
|
|
|
12
13
|
to_obfus = (Marty::Config['DIAG_ENV_OBFUSCATE'] || []).map(&:upcase) + [
|
|
13
|
-
'SECRET_KEY_BASE'
|
|
14
|
+
'SECRET_KEY_BASE'
|
|
15
|
+
]
|
|
14
16
|
|
|
15
17
|
to_block = (Marty::Config['DIAG_ENV_BLOCK_IF_INCL'] || []).map(&:upcase) + [
|
|
16
|
-
'ACCESS', 'SECRET', 'PASSWORD', 'DEBUG'
|
|
18
|
+
'ACCESS', 'SECRET', 'PASSWORD', 'DEBUG'
|
|
19
|
+
]
|
|
17
20
|
|
|
18
|
-
to_delete.each{|k| env.delete(k)}
|
|
21
|
+
to_delete.each { |k| env.delete(k) }
|
|
19
22
|
|
|
20
|
-
to_obfus.each{|k| env[k] = env[k][0,4] if env[k]}
|
|
23
|
+
to_obfus.each { |k| env[k] = env[k][0, 4] if env[k] }
|
|
21
24
|
|
|
22
|
-
env.sort.each_with_object({})
|
|
23
|
-
h[k] = v if to_block.all?{|b| !k.include?(b)} && k.include?(filter)
|
|
25
|
+
env.sort.each_with_object({}) do |(k, v), h|
|
|
26
|
+
h[k] = v if to_block.all? { |b| !k.include?(b) } && k.include?(filter)
|
|
27
|
+
end
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
# overwritten to only return inconsitent data
|
|
27
31
|
def self.apply_consistency data
|
|
28
32
|
diff = get_difference(data)
|
|
29
|
-
data.each_with_object({})
|
|
30
|
-
|(
|
|
31
|
-
|
|
32
|
-
|(test, info), new_diagnostic|
|
|
33
|
-
new_diagnostic[test] = info + {'consistent' => false} if
|
|
33
|
+
data.each_with_object({}) do |(node, diagnostic), new_data|
|
|
34
|
+
new_data[node] = diagnostic.each_with_object({}) do |(test, info), new_diagnostic|
|
|
35
|
+
new_diagnostic[test] = info + { 'consistent' => false } if
|
|
34
36
|
diff.include?(test)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
end
|
|
38
|
+
end
|
|
37
39
|
end
|
|
38
40
|
end
|
|
39
41
|
end
|
|
@@ -2,7 +2,7 @@ module Marty::Diagnostic; class Fatal < Base
|
|
|
2
2
|
def self.message msg, opts = {}
|
|
3
3
|
node = opts[:node] || Node.my_ip
|
|
4
4
|
type = opts[:type] || 'RuntimeError'
|
|
5
|
-
{name.demodulize => {node => {type => error(msg)}}}
|
|
5
|
+
{ name.demodulize => { node => { type => error(msg) } } }
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
module Marty::Diagnostic::Node
|
|
2
2
|
def self.my_ip
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
rescue => e
|
|
3
|
+
Socket.ip_address_list.detect(&:ipv4_private?).ip_address
|
|
4
|
+
rescue StandardError => e
|
|
6
5
|
e.message
|
|
7
|
-
end
|
|
8
6
|
end
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
8
|
def self.get_target_connections target
|
|
13
|
-
Marty::Diagnostic::Database.current_connections.select
|
|
9
|
+
Marty::Diagnostic::Database.current_connections.select do |conn|
|
|
14
10
|
conn['application_name'].include?(target)
|
|
15
|
-
|
|
11
|
+
end.map do |conn|
|
|
16
12
|
conn['client_addr'] == '127.0.0.1' ? my_ip :
|
|
17
13
|
conn['client_addr'] || '127.0.0.1'
|
|
18
|
-
|
|
14
|
+
end
|
|
19
15
|
end
|
|
20
16
|
|
|
21
17
|
def self.get_nodes
|
|
@@ -4,7 +4,7 @@ module Marty::Diagnostic; class Nodes < Base
|
|
|
4
4
|
diagnostic_fn aggregatable: false do
|
|
5
5
|
begin
|
|
6
6
|
pg_nodes = Node.get_nodes.sort
|
|
7
|
-
rescue => e
|
|
7
|
+
rescue StandardError => e
|
|
8
8
|
next error(e.message)
|
|
9
9
|
end
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@ module Marty::Diagnostic; class Nodes < Base
|
|
|
13
13
|
|
|
14
14
|
begin
|
|
15
15
|
instance_data = Marty::Diagnostic::Aws::Ec2Instance.new
|
|
16
|
-
rescue => e
|
|
16
|
+
rescue StandardError => e
|
|
17
17
|
next error(pg_nodes.join("\n") +
|
|
18
18
|
"\nAws Communication Error: #{e.message}")
|
|
19
19
|
end
|
|
@@ -25,7 +25,7 @@ module Marty::Diagnostic; class Nodes < Base
|
|
|
25
25
|
# generate instance information when there is an issue
|
|
26
26
|
# between aws and postgres
|
|
27
27
|
instances = instance_data.instances
|
|
28
|
-
{'nodes' => error(
|
|
28
|
+
{ 'nodes' => error('There is a discrepancy between nodes connected to '\
|
|
29
29
|
"Postgres and those discovered through AWS EC2.\n"\
|
|
30
30
|
"Postgres: \n#{pg_nodes.join("\n")}\n"\
|
|
31
31
|
"AWS: \n#{a_nodes.join("\n")}"),
|
|
@@ -35,19 +35,21 @@ module Marty::Diagnostic; class Nodes < Base
|
|
|
35
35
|
'terminated' => error_if(instances.terminated),
|
|
36
36
|
'stopping' => error_if(instances.stopping),
|
|
37
37
|
'stopped' => error_if(instances.stopped),
|
|
38
|
-
}.delete_if{|k,v| v.empty?}
|
|
39
|
-
rescue => e
|
|
38
|
+
}.delete_if { |k, v| v.empty? }
|
|
39
|
+
rescue StandardError => e
|
|
40
40
|
error(e.message)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def self.valid_if arr
|
|
45
45
|
return arr.join("\n") unless arr.empty?
|
|
46
|
+
|
|
46
47
|
error('---')
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
def self.error_if arr
|
|
50
51
|
return arr if arr.empty?
|
|
52
|
+
|
|
51
53
|
error(arr.join("\n"))
|
|
52
54
|
end
|
|
53
55
|
end
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
module Marty::Diagnostic; module Packer
|
|
2
|
-
def pack include_ip=true
|
|
2
|
+
def pack include_ip = true
|
|
3
3
|
info = process(yield)
|
|
4
|
-
include_ip ? {Node.my_ip => info} : info
|
|
4
|
+
include_ip ? { Node.my_ip => info } : info
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def process obj
|
|
8
8
|
obj.is_a?(Hash) ? process_hash(obj) :
|
|
9
|
-
{name.demodulize => create_info(obj.to_s)}
|
|
9
|
+
{ name.demodulize => create_info(obj.to_s) }
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def process_hash data
|
|
13
|
-
return {name.demodulize => data} if is_valid_info?(data)
|
|
13
|
+
return { name.demodulize => data } if is_valid_info?(data)
|
|
14
14
|
|
|
15
|
-
data.each_with_object({}) do
|
|
16
|
-
|(k, v), h|
|
|
15
|
+
data.each_with_object({}) do |(k, v), h|
|
|
17
16
|
if v.is_a?(Hash)
|
|
18
17
|
raise "Invalid Diagnostic Info #{v}" unless is_valid_info?(v)
|
|
18
|
+
|
|
19
19
|
h[k] = v
|
|
20
20
|
else
|
|
21
21
|
h[k] = create_info(v)
|
|
@@ -23,7 +23,7 @@ module Marty::Diagnostic; module Packer
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def create_info description, status=true, consistent=nil
|
|
26
|
+
def create_info description, status = true, consistent = nil
|
|
27
27
|
{
|
|
28
28
|
'description' => description.to_s,
|
|
29
29
|
'status' => status,
|
|
@@ -9,24 +9,26 @@ module Marty::Diagnostic; class Reporter < Request
|
|
|
9
9
|
self.request = request
|
|
10
10
|
|
|
11
11
|
ops = op.split(/,\s*/).uniq - [unresolve_diagnostic(self)]
|
|
12
|
-
reps = ops.select{|o| reports.keys.include?(o)}
|
|
12
|
+
reps = ops.select { |o| reports.keys.include?(o) }
|
|
13
13
|
|
|
14
|
-
self.diagnostics = ((ops - reps) + reps.map{|r| reports[r]}.flatten).uniq.
|
|
15
|
-
map{|d| resolve_diagnostic(d)}
|
|
14
|
+
self.diagnostics = ((ops - reps) + reps.map { |r| reports[r] }.flatten).uniq.
|
|
15
|
+
map { |d| resolve_diagnostic(d) }
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
scope == 'local' ? generate : aggregate
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
private
|
|
21
|
+
|
|
21
22
|
def self.resolve_diagnostic diag_name
|
|
22
23
|
diag_name = diag_name.camelize
|
|
23
24
|
klass = nil
|
|
24
|
-
|
|
25
|
+
namespaces.each do |n|
|
|
25
26
|
klass = (n + '::Diagnostic::' + diag_name).constantize rescue nil
|
|
26
27
|
break if klass
|
|
27
28
|
end
|
|
28
29
|
raise NameError.new("#{diag_name} could not be resolved by #{name}") if
|
|
29
30
|
klass.nil?
|
|
31
|
+
|
|
30
32
|
klass
|
|
31
33
|
end
|
|
32
34
|
|
|
@@ -35,50 +37,45 @@ module Marty::Diagnostic; class Reporter < Request
|
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
def self.generate
|
|
38
|
-
diagnostics.each_with_object({})
|
|
39
|
-
|d, h|
|
|
40
|
+
diagnostics.each_with_object({}) do |d, h|
|
|
40
41
|
begin
|
|
41
42
|
h[d.name.demodulize] = d.generate
|
|
42
|
-
rescue => e
|
|
43
|
+
rescue StandardError => e
|
|
43
44
|
h.deep_merge!(Fatal.message(e.message, type: d.name.demodulize))
|
|
44
45
|
end
|
|
45
|
-
|
|
46
|
+
end
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def self.aggregate
|
|
49
50
|
data = consistency([generate, get_remote_diagnostics].reduce(:deep_merge))
|
|
50
|
-
{'data' => data, 'errors' => errors(data)}
|
|
51
|
+
{ 'data' => data, 'errors' => errors(data) }
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
def self.consistency data
|
|
54
|
-
data.each_with_object({})
|
|
55
|
-
|(klass, result), h|
|
|
55
|
+
data.each_with_object({}) do |(klass, result), h|
|
|
56
56
|
h[klass] = resolve_diagnostic(klass).apply_consistency(result)
|
|
57
|
-
|
|
57
|
+
end
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def self.errors data
|
|
61
|
-
data.each_with_object({})
|
|
62
|
-
|(
|
|
63
|
-
|
|
64
|
-
|(node, diagnostic), new_result|
|
|
65
|
-
new_result[node] = diagnostic.each_with_object({}){
|
|
66
|
-
|(test, info), new_diagnostic|
|
|
61
|
+
data.each_with_object({}) do |(klass, result), new_data|
|
|
62
|
+
new_data[klass] = result.each_with_object({}) do |(node, diagnostic), new_result|
|
|
63
|
+
new_result[node] = diagnostic.each_with_object({}) do |(test, info), new_diagnostic|
|
|
67
64
|
new_diagnostic[test] = info unless
|
|
68
65
|
info['status'] && (scope == 'local' || info['consistent'])
|
|
69
|
-
|
|
66
|
+
end
|
|
70
67
|
new_result.delete(node) if new_result[node].empty?
|
|
71
|
-
|
|
68
|
+
end
|
|
72
69
|
new_data.delete(klass) if new_data[klass].empty?
|
|
73
|
-
|
|
70
|
+
end
|
|
74
71
|
end
|
|
75
72
|
|
|
76
73
|
def self.displays result
|
|
77
|
-
result.map{|d, r| resolve_diagnostic(d).display(r)}.sum
|
|
74
|
+
result.map { |d, r| resolve_diagnostic(d).display(r) }.sum
|
|
78
75
|
end
|
|
79
76
|
|
|
80
77
|
def self.get_remote_diagnostics
|
|
81
|
-
ops = diagnostics.map{|d| unresolve_diagnostic(d) if d.aggregatable}.compact
|
|
78
|
+
ops = diagnostics.map { |d| unresolve_diagnostic(d) if d.aggregatable }.compact
|
|
82
79
|
return {} if ops.empty?
|
|
83
80
|
|
|
84
81
|
nodes = Node.get_nodes - [Node.my_ip]
|
|
@@ -97,11 +94,11 @@ module Marty::Diagnostic; class Reporter < Request
|
|
|
97
94
|
req.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
98
95
|
|
|
99
96
|
begin
|
|
100
|
-
response = req.start {|http| http.get(uri.to_s)}
|
|
101
|
-
next JSON.parse(response.body) if response.code ==
|
|
97
|
+
response = req.start { |http| http.get(uri.to_s) }
|
|
98
|
+
next JSON.parse(response.body) if response.code == '200'
|
|
102
99
|
|
|
103
100
|
Fatal.message(response.body, type: response.message, node: uri.host)
|
|
104
|
-
rescue => e
|
|
101
|
+
rescue StandardError => e
|
|
105
102
|
Fatal.message(e.message, type: e.class, node: uri.host)
|
|
106
103
|
end
|
|
107
104
|
end
|
|
@@ -2,8 +2,8 @@ module Marty::Diagnostic; class Version < Base
|
|
|
2
2
|
diagnostic_fn do
|
|
3
3
|
begin
|
|
4
4
|
message = `cd #{Rails.root.to_s}; git describe --tags --always;`.strip
|
|
5
|
-
rescue
|
|
6
|
-
message = error(
|
|
5
|
+
rescue StandardError
|
|
6
|
+
message = error('Failed accessing git')
|
|
7
7
|
end
|
|
8
8
|
rbv = "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})"
|
|
9
9
|
{
|
|
@@ -22,11 +22,9 @@ module Marty::Diagnostic; class Version < Base
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def self.db_schema
|
|
25
|
-
begin
|
|
26
25
|
Database.db_schema
|
|
27
|
-
|
|
26
|
+
rescue StandardError => e
|
|
28
27
|
error(e.message)
|
|
29
|
-
end
|
|
30
28
|
end
|
|
31
29
|
end
|
|
32
30
|
end
|
data/script/rails
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
-
# This command will automatically be run when you run "rails"
|
|
2
|
+
# This command will automatically be run when you run "rails"
|
|
3
|
+
# with Rails 3 gems installed from the root of your application.
|
|
3
4
|
|
|
4
5
|
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
5
6
|
ENGINE_PATH = File.expand_path('../../lib/marty/engine', __FILE__)
|
|
@@ -8,7 +8,7 @@ module Marty
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
describe 'authentication' do
|
|
11
|
-
it
|
|
11
|
+
it 'should allow a registered user to log in' do
|
|
12
12
|
allow(Rails.configuration.marty).to receive(:auth_source).
|
|
13
13
|
and_return('local')
|
|
14
14
|
|
|
@@ -20,8 +20,8 @@ module Marty
|
|
|
20
20
|
expect(Marty::User.current).to be_nil
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
it
|
|
24
|
-
|
|
23
|
+
it 'should allow a registered user to log in when the database ' +
|
|
24
|
+
'is in recovery mode' do
|
|
25
25
|
allow(Marty::Util).to receive(:db_in_recovery?).and_return(true)
|
|
26
26
|
allow(Rails.configuration.marty).to receive(:auth_source).
|
|
27
27
|
and_return('local')
|
|
@@ -34,14 +34,14 @@ module Marty
|
|
|
34
34
|
expect(Marty::User.current).to be_nil
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
it
|
|
37
|
+
it 'should prevent a non-registered user from logging in' do
|
|
38
38
|
user = Marty::User.try_to_login('unknown_marty', 'invalid_password')
|
|
39
39
|
expect(user).to be_nil
|
|
40
40
|
expect(Marty::User.current).to be_nil
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
it
|
|
44
|
-
|
|
43
|
+
it 'should prevent a non-registered user from logging in when the ' +
|
|
44
|
+
'database is in recovery mode' do
|
|
45
45
|
allow(Marty::Util).to receive(:db_in_recovery?).and_return(true)
|
|
46
46
|
user = Marty::User.try_to_login('unknown_marty', 'invalid_password')
|
|
47
47
|
expect(user).to be_nil
|
|
@@ -8,25 +8,25 @@ require 'support/empty_job'
|
|
|
8
8
|
describe Marty::DelayedJobController, slow: false do
|
|
9
9
|
before(:each) { @routes = Marty::Engine.routes }
|
|
10
10
|
|
|
11
|
-
describe
|
|
11
|
+
describe '#trigger' do
|
|
12
12
|
before do
|
|
13
13
|
@job = ::Delayed::Job.enqueue EmptyJob.new
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
it
|
|
16
|
+
it 'should be able to execute existing job' do
|
|
17
17
|
expect(::Delayed::Job.exists?(@job.id)).to be true
|
|
18
18
|
post :trigger, params: { id: @job.id }
|
|
19
19
|
expect(response).to have_http_status(:ok)
|
|
20
20
|
expect(::Delayed::Job.exists?(@job.id)).to be false
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
it
|
|
23
|
+
it 'should return ok if triggered job is locked' do
|
|
24
24
|
@job.update!(locked_at: Time.zone.now)
|
|
25
25
|
post :trigger, params: { id: @job.id }
|
|
26
26
|
expect(response).to have_http_status(:ok)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
it
|
|
29
|
+
it 'should return ok if triggered job is missing' do
|
|
30
30
|
@job.destroy!
|
|
31
31
|
post :trigger, params: { id: @job.id }
|
|
32
32
|
expect(response).to have_http_status(:ok)
|
|
@@ -16,28 +16,27 @@ module Marty::Diagnostic
|
|
|
16
16
|
|
|
17
17
|
def git
|
|
18
18
|
`cd #{Rails.root.to_s}; git describe --tags --always;`.
|
|
19
|
-
strip rescue
|
|
19
|
+
strip rescue 'Failed accessing git'
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
describe 'GET #op' do
|
|
23
23
|
it 'returns http success' do
|
|
24
|
-
get :op, params: {format: :json, op: 'version'}
|
|
24
|
+
get :op, params: { format: :json, op: 'version' }
|
|
25
25
|
expect(response).to have_http_status(:success)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it 'a request injects the request object into Diagnostic classes' do
|
|
29
|
-
get :op, params: {format: :json, op: 'version'}
|
|
29
|
+
get :op, params: { format: :json, op: 'version' }
|
|
30
30
|
expect(Reporter.request).not_to eq(nil)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it 'returns the current version JSON' do
|
|
34
|
-
get :op, params: {format: :json, op: 'version', data: 'true'}
|
|
34
|
+
get :op, params: { format: :json, op: 'version', data: 'true' }
|
|
35
35
|
|
|
36
36
|
# generate version data and declare all values consistent
|
|
37
|
-
versions = Version.generate.each_with_object({})
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
37
|
+
versions = Version.generate.each_with_object({}) do |(n, v), h|
|
|
38
|
+
h[n] = v.each { |t, r| r['consistent'] = true }
|
|
39
|
+
end
|
|
41
40
|
|
|
42
41
|
expected = {
|
|
43
42
|
'data' => {
|
|
@@ -50,77 +49,77 @@ module Marty::Diagnostic
|
|
|
50
49
|
|
|
51
50
|
it 'returns the expected cummulative diagnostic' do
|
|
52
51
|
expected = {
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
'data' => {
|
|
53
|
+
'Version' => {
|
|
55
54
|
my_ip => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
'Marty' => {
|
|
56
|
+
'description' => Marty::VERSION,
|
|
57
|
+
'status' => true,
|
|
58
|
+
'consistent' => true
|
|
60
59
|
},
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
'Delorean' => {
|
|
61
|
+
'description' => Delorean::VERSION,
|
|
62
|
+
'status' => true,
|
|
63
|
+
'consistent' => true
|
|
65
64
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
'Mcfly' => {
|
|
66
|
+
'description' => Mcfly::VERSION,
|
|
67
|
+
'status' => true,
|
|
68
|
+
'consistent' => true
|
|
70
69
|
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
'Git' => {
|
|
71
|
+
'description' => git,
|
|
72
|
+
'status' => true,
|
|
73
|
+
'consistent' => true
|
|
75
74
|
},
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
'Rails' => {
|
|
76
|
+
'description' => Rails.version,
|
|
77
|
+
'status' => true,
|
|
78
|
+
'consistent' => true
|
|
80
79
|
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
'Netzke Core' => {
|
|
81
|
+
'description' => Netzke::Core::VERSION,
|
|
82
|
+
'status' => true,
|
|
83
|
+
'consistent' => true
|
|
85
84
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
'Netzke Basepack' => {
|
|
86
|
+
'description' => Netzke::Basepack::VERSION,
|
|
87
|
+
'status' => true,
|
|
88
|
+
'consistent' => true
|
|
90
89
|
},
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
'Ruby' => {
|
|
91
|
+
'description' => "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} "\
|
|
93
92
|
"(#{RUBY_PLATFORM})",
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
'status' => true,
|
|
94
|
+
'consistent' => true
|
|
96
95
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
'RubyGems' => {
|
|
97
|
+
'description' => Gem::VERSION,
|
|
98
|
+
'status' => true,
|
|
99
|
+
'consistent' => true
|
|
101
100
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
'Database Schema Version' => {
|
|
102
|
+
'description' => Database.db_schema,
|
|
103
|
+
'status' => true,
|
|
104
|
+
'consistent' => true
|
|
106
105
|
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
'Environment' => {
|
|
107
|
+
'description' => Rails.env,
|
|
108
|
+
'status' => true,
|
|
109
|
+
'consistent' => true
|
|
111
110
|
}
|
|
112
111
|
}
|
|
113
112
|
},
|
|
114
|
-
|
|
113
|
+
'EnvironmentVariables' => {
|
|
115
114
|
my_ip => {
|
|
116
115
|
}
|
|
117
116
|
},
|
|
118
|
-
|
|
117
|
+
'Nodes' => {
|
|
119
118
|
my_ip => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
'Nodes' => {
|
|
120
|
+
'description' => my_ip,
|
|
121
|
+
'status' => true,
|
|
122
|
+
'consistent' => true
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
}
|