marty 2.5.7 → 2.5.8
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 +1 -1
- data/app/components/marty/promise_view.rb +22 -12
- data/app/controllers/marty/rpc_controller.rb +43 -45
- data/app/models/marty/user.rb +18 -14
- data/lib/marty/version.rb +1 -1
- data/other/marty/api/base.rb +16 -13
- data/other/marty/diagnostic/delayed_job_workers.rb +12 -1
- data/spec/other/diagnostic/delayed_job_workers_spec.rb +12 -9
- metadata +1 -2
- data/other/marty/diagnostic/delayed_job_worker_total_count.rb +0 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 17d4c8cca5e227120b347328f76f6b5c2844a3662fe4fa31c186d4ac5b422f9b
|
|
4
|
+
data.tar.gz: 5ae6f1ec90da4b1543ed781e2bd9b9ef88224d9b51bde8257f9e9188dc44b82c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5705fbd63836311b4f6b2847d9b2b2fe998a413980a5a795a98494f94e8dc0dda78dc0a3a05d994c821102e8bf8320afe6465393dd663674cb22b5cfa2b63a52
|
|
7
|
+
data.tar.gz: 806137fda06674d6d4fa937689a0da78898f1c4589ee1f52833030aea10537e48a76037ebbe2acc7a1c90eaccee1bb4d2af7ea325a09f93dbbc35028af5f37e9
|
data/Gemfile.lock
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
class Marty::PromiseView < Netzke::Tree::Base
|
|
2
2
|
extend ::Marty::Permissions
|
|
3
|
+
has_marty_permissions read: :any
|
|
3
4
|
|
|
4
5
|
client_styles do |config|
|
|
5
6
|
config.require :promise_view
|
|
@@ -15,11 +16,17 @@ class Marty::PromiseView < Netzke::Tree::Base
|
|
|
15
16
|
c.include :promise_view
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
######################################################################
|
|
20
|
+
|
|
21
|
+
def class_can?(op)
|
|
22
|
+
self.class.can_perform_action?(op)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def configure(c)
|
|
19
26
|
super
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
c.title = I18n.t('jobs.promise_view')
|
|
28
|
+
c.model = 'Marty::VwPromise'
|
|
29
|
+
c.attributes = [
|
|
23
30
|
{ name: :title, xtype: :treecolumn },
|
|
24
31
|
:user__login,
|
|
25
32
|
:job_id,
|
|
@@ -29,14 +36,17 @@ class Marty::PromiseView < Netzke::Tree::Base
|
|
|
29
36
|
:cformat,
|
|
30
37
|
:error,
|
|
31
38
|
]
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
c.root_visible = false
|
|
40
|
+
c.paging = :none
|
|
41
|
+
c.bbar = bbar
|
|
42
|
+
c.read_only = true
|
|
43
|
+
c.permissions = {
|
|
44
|
+
create: class_can?(:create),
|
|
45
|
+
read: class_can?(:read),
|
|
46
|
+
update: class_can?(:update),
|
|
47
|
+
delete: class_can?(:delete)
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
# garbage collect old promises (hacky to do this here)
|
|
41
51
|
Marty::Promise.cleanup(false)
|
|
42
52
|
end
|
|
@@ -1,56 +1,54 @@
|
|
|
1
1
|
class Marty::RpcController < ActionController::Base
|
|
2
|
+
INTERNAL_SERVER_ERROR = { error: 'internal server error' }
|
|
3
|
+
PERMISSION_DENIED_ERROR = { error: 'Permission denied' }
|
|
4
|
+
|
|
2
5
|
def evaluate
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# default to base class if no config is present
|
|
21
|
-
api = api_config.present? ? api_config[:api_class].constantize :
|
|
22
|
-
Marty::Api::Base
|
|
23
|
-
|
|
24
|
-
return result = massaged_params if massaged_params.include?(:error)
|
|
25
|
-
|
|
26
|
-
api_params = api.process_params(massaged_params)
|
|
27
|
-
auth = api.is_authorized?(api_params)
|
|
28
|
-
return result = { error: 'Permission denied' } unless auth
|
|
29
|
-
|
|
30
|
-
start_time = Time.zone.now
|
|
31
|
-
api.before_evaluate(api_params)
|
|
32
|
-
result = api.evaluate(api_params, request, api_config)
|
|
33
|
-
api.after_evaluate(api_params, result)
|
|
34
|
-
rescue StandardError => e
|
|
35
|
-
# log unexpected failures in rpc controller and respond with
|
|
36
|
-
# generic server error
|
|
37
|
-
Marty::Logger.log('rpc_controller', 'failure', e.message)
|
|
38
|
-
result = { error: 'internal server error' }
|
|
39
|
-
ensure
|
|
40
|
-
# if logging is enabled, always log the result even on error
|
|
41
|
-
if api_config && api_config[:logged] && api
|
|
42
|
-
api.log(result,
|
|
43
|
-
api_params + { start_time: start_time, auth: auth },
|
|
44
|
-
request)
|
|
45
|
-
end
|
|
6
|
+
massaged_params = massage_params(params)
|
|
7
|
+
|
|
8
|
+
# resolve api config in order to determine api class and settings
|
|
9
|
+
api_config = get_api_config(massaged_params) || {}
|
|
10
|
+
|
|
11
|
+
# default to base class if no config is present
|
|
12
|
+
api = api_config[:api_class].try(:constantize) || Marty::Api::Base
|
|
13
|
+
|
|
14
|
+
api.respond_to(self) do
|
|
15
|
+
begin
|
|
16
|
+
next massaged_params if massaged_params.include?(:error)
|
|
17
|
+
|
|
18
|
+
api_params = api.process_params(massaged_params)
|
|
19
|
+
auth = api.is_authorized?(api_params)
|
|
20
|
+
|
|
21
|
+
next PERMISSION_DENIED_ERROR unless auth
|
|
46
22
|
|
|
47
|
-
|
|
48
|
-
|
|
23
|
+
# allow api classes to return hashes with error key for custom responses
|
|
24
|
+
next auth if auth.is_a?(Hash) && auth[:error]
|
|
25
|
+
|
|
26
|
+
start_time = Time.zone.now
|
|
27
|
+
api.before_evaluate(api_params)
|
|
28
|
+
|
|
29
|
+
result = api.evaluate(api_params, request, api_config)
|
|
30
|
+
api.after_evaluate(api_params, result)
|
|
31
|
+
|
|
32
|
+
if api_config[:logged]
|
|
33
|
+
log_params = api_params + { start_time: start_time, auth: auth }
|
|
34
|
+
api.log(result, log_params, request)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
result
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
Marty::Logger.log('rpc_controller', 'failure', e.message)
|
|
40
|
+
INTERNAL_SERVER_ERROR
|
|
49
41
|
end
|
|
42
|
+
end
|
|
50
43
|
end
|
|
51
44
|
|
|
52
45
|
private
|
|
53
46
|
|
|
47
|
+
def get_api_config params
|
|
48
|
+
config_attrs = params.values_at(:script, :node, :attr)
|
|
49
|
+
Marty::ApiConfig.lookup(*config_attrs)
|
|
50
|
+
end
|
|
51
|
+
|
|
54
52
|
def process_active_params params
|
|
55
53
|
# must permit params before conversion to_h
|
|
56
54
|
# convert hash to json and parse to get expected hash (not indifferent)
|
data/app/models/marty/user.rb
CHANGED
|
@@ -53,6 +53,23 @@ class Marty::User < Marty::Base
|
|
|
53
53
|
authenticate_with?(login, password) || nil
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def self.ldap_login(login, password)
|
|
57
|
+
# IMPORTANT NOTE: if server allows anonymous LDAP access, empty
|
|
58
|
+
# passwords will succeed! i.e. if a valid user with empty
|
|
59
|
+
# password is sent in, ldap.bind will return OK.
|
|
60
|
+
cf = Rails.configuration.marty.ldap
|
|
61
|
+
ldap = Net::LDAP.new(host: cf.host,
|
|
62
|
+
port: cf.port,
|
|
63
|
+
base: cf.base_dn,
|
|
64
|
+
encryption: cf.encryption,
|
|
65
|
+
auth: {
|
|
66
|
+
method: :simple,
|
|
67
|
+
username: cf.domain + '\\' + login,
|
|
68
|
+
password: password,
|
|
69
|
+
})
|
|
70
|
+
ldap.bind
|
|
71
|
+
end
|
|
72
|
+
|
|
56
73
|
def self.authenticate_with?(login, password)
|
|
57
74
|
cf = Rails.configuration.marty
|
|
58
75
|
|
|
@@ -61,20 +78,7 @@ class Marty::User < Marty::Base
|
|
|
61
78
|
if auth_source == 'local'
|
|
62
79
|
ok = password == cf.local_password
|
|
63
80
|
elsif auth_source == 'ldap'
|
|
64
|
-
|
|
65
|
-
# passwords will succeed! i.e. if a valid user with empty
|
|
66
|
-
# password is sent in, ldap.bind will return OK.
|
|
67
|
-
cf = Rails.configuration.marty.ldap
|
|
68
|
-
ldap = Net::LDAP.new(host: cf.host,
|
|
69
|
-
port: cf.port,
|
|
70
|
-
base: cf.base_dn,
|
|
71
|
-
encryption: cf.encryption,
|
|
72
|
-
auth: {
|
|
73
|
-
method: :simple,
|
|
74
|
-
username: cf.domain + '\\' + login,
|
|
75
|
-
password: password,
|
|
76
|
-
})
|
|
77
|
-
ok = ldap.bind
|
|
81
|
+
ok = ldap_login(login, password)
|
|
78
82
|
else
|
|
79
83
|
raise "bad auth_source: #{auth_source.inspect}"
|
|
80
84
|
end
|
data/lib/marty/version.rb
CHANGED
data/other/marty/api/base.rb
CHANGED
|
@@ -168,25 +168,28 @@ class Marty::Api::Base
|
|
|
168
168
|
return unless hash
|
|
169
169
|
|
|
170
170
|
pf = ActionDispatch::Http::ParameterFilter.new(filter_params)
|
|
171
|
-
pf.filter(hash)
|
|
171
|
+
pf.filter(hash.stringify_keys)
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
def self.log_hash result, params, request
|
|
175
|
-
res = result.is_a?(Hash) ? result.stringify_keys : result
|
|
176
175
|
ret_arr = params[:return_array]
|
|
176
|
+
|
|
177
|
+
# filter sensitive information from input/output
|
|
178
|
+
is_hash = result.is_a?(Hash)
|
|
179
|
+
res = is_hash ? filter_hash(result, engine_params_filter) : result
|
|
177
180
|
input = filter_hash(params[:params], engine_params_filter)
|
|
181
|
+
error = res['error'] if is_hash && res.include?('error')
|
|
182
|
+
|
|
178
183
|
{ script: params[:script],
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
remote_ip: request.remote_ip,
|
|
189
|
-
auth_name: params[:auth]
|
|
184
|
+
node: params[:node],
|
|
185
|
+
attrs: ret_arr ? [params[:attr]] : params[:attr],
|
|
186
|
+
input: input,
|
|
187
|
+
output: error ? nil : res,
|
|
188
|
+
start_time: params[:start_time],
|
|
189
|
+
end_time: Time.zone.now,
|
|
190
|
+
error: error,
|
|
191
|
+
remote_ip: request.remote_ip,
|
|
192
|
+
auth_name: params[:auth]
|
|
190
193
|
}
|
|
191
194
|
end
|
|
192
195
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
module Marty::Diagnostic; class DelayedJobWorkers < Base
|
|
2
|
+
DIAG_NAME = 'Delayed Workers / Node'
|
|
3
|
+
DIAG_CONFIG_TARGET = 'DIAG_DELAYED_TARGET'
|
|
2
4
|
diagnostic_fn do
|
|
3
5
|
my_ip = Node.my_ip
|
|
4
6
|
workers = Database.current_connections.map do |c|
|
|
@@ -6,7 +8,16 @@ module Marty::Diagnostic; class DelayedJobWorkers < Base
|
|
|
6
8
|
name = c['application_name']
|
|
7
9
|
name if name.include?('delayed') && (ip == my_ip || ip == '127.0.0.1')
|
|
8
10
|
end.compact.uniq.count
|
|
9
|
-
|
|
11
|
+
|
|
12
|
+
target_count = Marty::Config[DIAG_CONFIG_TARGET]
|
|
13
|
+
|
|
14
|
+
next { DIAG_NAME => workers.zero? ? error(workers) : workers } unless
|
|
15
|
+
target_count
|
|
16
|
+
|
|
17
|
+
next { DIAG_NAME => error("invalid type for #{DIAG_CONFIG_TARGET}") } unless
|
|
18
|
+
target_count.is_a?(Integer)
|
|
19
|
+
|
|
20
|
+
{ DIAG_NAME => workers == target_count ? workers : error(workers) }
|
|
10
21
|
end
|
|
11
22
|
end
|
|
12
23
|
end
|
|
@@ -2,12 +2,13 @@ require 'spec_helper'
|
|
|
2
2
|
require 'job_helper'
|
|
3
3
|
|
|
4
4
|
describe Marty::Diagnostic::DelayedJobWorkers do
|
|
5
|
-
def sample_data
|
|
5
|
+
def sample_data opts={}
|
|
6
|
+
ip, error, status = opts.values_at(:ip, :error, :status)
|
|
6
7
|
{
|
|
7
8
|
ip || Marty::Helper.my_ip => {
|
|
8
9
|
'Delayed Workers / Node' => {
|
|
9
10
|
'description' => error ? '3' : '4',
|
|
10
|
-
'status' =>
|
|
11
|
+
'status' => status,
|
|
11
12
|
'consistent' => nil
|
|
12
13
|
},
|
|
13
14
|
}
|
|
@@ -16,10 +17,10 @@ describe Marty::Diagnostic::DelayedJobWorkers do
|
|
|
16
17
|
|
|
17
18
|
def sample_aggregate error = false
|
|
18
19
|
[
|
|
19
|
-
sample_data(ip
|
|
20
|
-
sample_data(ip
|
|
21
|
-
sample_data(ip
|
|
22
|
-
sample_data(ip
|
|
20
|
+
sample_data(ip: '0.0.0.0'),
|
|
21
|
+
sample_data(ip: '0.0.0.1'),
|
|
22
|
+
sample_data(ip: '0.0.0.2', error: error),
|
|
23
|
+
sample_data(ip: '0.0.0.3'),
|
|
23
24
|
].reduce(:merge)
|
|
24
25
|
end
|
|
25
26
|
|
|
@@ -37,8 +38,10 @@ describe Marty::Diagnostic::DelayedJobWorkers do
|
|
|
37
38
|
expect(described_class.consistent?(inconsistent)).to eq(false)
|
|
38
39
|
end
|
|
39
40
|
|
|
40
|
-
it '
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
it 'allows a config to set the target workers' do
|
|
42
|
+
Marty::Config['DIAG_DELAYED_TARGET'] = 2
|
|
43
|
+
start_delayed_job
|
|
44
|
+
expect(described_class.generate).to eq(sample_data(status: false))
|
|
45
|
+
stop_delayed_job
|
|
43
46
|
end
|
|
44
47
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: marty
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.5.
|
|
4
|
+
version: 2.5.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Arman Bostani
|
|
@@ -429,7 +429,6 @@ files:
|
|
|
429
429
|
- other/marty/diagnostic/connections.rb
|
|
430
430
|
- other/marty/diagnostic/database.rb
|
|
431
431
|
- other/marty/diagnostic/delayed_job_version.rb
|
|
432
|
-
- other/marty/diagnostic/delayed_job_worker_total_count.rb
|
|
433
432
|
- other/marty/diagnostic/delayed_job_workers.rb
|
|
434
433
|
- other/marty/diagnostic/environment_variables.rb
|
|
435
434
|
- other/marty/diagnostic/fatal.rb
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
module Marty::Diagnostic; class DelayedJobWorkerTotalCount < Base
|
|
2
|
-
diagnostic_fn(aggregatable: false) do
|
|
3
|
-
count = Database.current_connections.map do |c|
|
|
4
|
-
[c['application_name'], c['client_addr'] || '127.0.0.1'] if
|
|
5
|
-
c['application_name'].include?('delayed')
|
|
6
|
-
end.compact.uniq.count
|
|
7
|
-
{ 'Delayed Workers' => count.zero? ? error(count) : count }
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
end
|