pomelo-citrus-admin 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +20 -0
- data/Rakefile +0 -0
- data/citrus-admin.gemspec +34 -0
- data/lib/citrus-admin.rb +21 -0
- data/lib/citrus-admin/client/client.rb +142 -0
- data/lib/citrus-admin/console_service.rb +374 -0
- data/lib/citrus-admin/master_agent.rb +607 -0
- data/lib/citrus-admin/modules/console_module.rb +35 -0
- data/lib/citrus-admin/modules/monitor_log.rb +45 -0
- data/lib/citrus-admin/modules/process_info.rb +45 -0
- data/lib/citrus-admin/modules/system_info.rb +45 -0
- data/lib/citrus-admin/modules/watch_server.rb +45 -0
- data/lib/citrus-admin/monitor_agent.rb +166 -0
- data/lib/citrus-admin/util/protocol.rb +83 -0
- data/lib/citrus-admin/util/utils.rb +63 -0
- data/lib/citrus-admin/version.rb +7 -0
- data/spec/agent_spec.rb +424 -0
- data/spec/console_service_spec.rb +246 -0
- data/spec/spec_helper.rb +18 -0
- metadata +178 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a3cf2960e29ed5e8afa845d8d11e7e19ed7ab69c
|
4
|
+
data.tar.gz: f06a63aa30a903d6781370a7bbae0848d5b44c52
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5afb2d8016d05f06e079407be8565b0636fe155ac4164764b3236bd3c89ff673668ee53d1156fff3d16a9fcb26aea7715ddc0da1a97e510e1d13e0445854bd93
|
7
|
+
data.tar.gz: fead007deb6e5bcdae62f3b19ce7b9a499919f35607ca8f79c3b53deae53301f19e3f9277b0a96341c2a1ce2c67c6bab15514799c2289f6f830378be1bbf5e94
|
data/README.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
## Welcome to pomelo-citrus-admin
|
2
|
+
|
3
|
+
pomelo-citrus-admin is a simple clone of pomelo-admin written in Ruby using EventMachine.
|
4
|
+
|
5
|
+
## Motivation
|
6
|
+
|
7
|
+
Since NodeJS is influenced by Ruby EventMachine and Python's Twisted model, Ruby should also be able to have its own game server framework like pomelo.
|
8
|
+
|
9
|
+
Ruby is a very expressive and eloquent programming language. I was an RoR programmer before and I really like Ruby, When developing this project, I have used many skills like meta-programming and they give me the real pleasures.
|
10
|
+
|
11
|
+
Recently, I would focus on my daily work, so I open source this project and hope to have more people participate in this project.
|
12
|
+
|
13
|
+
## Todo
|
14
|
+
|
15
|
+
This gem is the very first gem I have done in my whole work, it needs to be improved but it already has the ablity to provide the basic infrastructure to other gems, other gems exist in my own repository.
|
16
|
+
|
17
|
+
## Links
|
18
|
+
|
19
|
+
* [EventMachine](https://github.com/eventmachine/eventmachine)
|
20
|
+
* [pomelo-admin](https://github.com/NetEase/pomelo-admin)
|
data/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 8 July 2014
|
4
|
+
|
5
|
+
$:.push File.expand_path('../lib', __FILE__)
|
6
|
+
|
7
|
+
require 'citrus-admin/version'
|
8
|
+
|
9
|
+
Gem::Specification.new do |spec|
|
10
|
+
spec.name = 'pomelo-citrus-admin'
|
11
|
+
spec.version = CitrusAdmin::VERSION
|
12
|
+
spec.platform = Gem::Platform::RUBY
|
13
|
+
spec.authors = ['MinixLi']
|
14
|
+
spec.email = 'MinixLi1986@gmail.com'
|
15
|
+
spec.description = %q{pomelo-citrus-admin is a simple clone of pomelo-admin, it provides an admin module for pomelo monitor system}
|
16
|
+
spec.summary = %q{pomelo-admin clone written in Ruby using EventMachine}
|
17
|
+
spec.homepage = 'https://github.com/minixli/pomelo-citrus-admin'
|
18
|
+
spec.license = 'MIT'
|
19
|
+
|
20
|
+
spec.files = `git ls-files`.split($/)
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
|
25
|
+
spec.add_dependency('eventmachine', '~> 0')
|
26
|
+
spec.add_dependency('json', '~> 0')
|
27
|
+
spec.add_dependency('websocket-eventmachine-client', '~> 0')
|
28
|
+
spec.add_dependency('websocket-eventmachine-server', '~> 0')
|
29
|
+
|
30
|
+
spec.add_dependency('pomelo-citrus-loader', '~> 0')
|
31
|
+
spec.add_dependency('pomelo-citrus-logger', '~> 0')
|
32
|
+
spec.add_dependency('pomelo-citrus-monitor', '~> 0')
|
33
|
+
spec.add_dependency('pomelo-citrus-scheduler', '~> 0')
|
34
|
+
end
|
data/lib/citrus-admin.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 8 July 2014
|
4
|
+
|
5
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
6
|
+
|
7
|
+
require 'eventmachine'
|
8
|
+
require 'json'
|
9
|
+
require 'websocket-eventmachine-client'
|
10
|
+
require 'websocket-eventmachine-server'
|
11
|
+
|
12
|
+
require 'pomelo-citrus-monitor'
|
13
|
+
|
14
|
+
require 'citrus-admin/util/protocol'
|
15
|
+
require 'citrus-admin/util/utils'
|
16
|
+
require 'citrus-admin/console_service'
|
17
|
+
|
18
|
+
# Load all the console modules
|
19
|
+
Dir.glob(File.expand_path('../citrus-admin/modules/*.rb', __FILE__)).each { |filepath|
|
20
|
+
require filepath
|
21
|
+
}
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 12 July 2014
|
4
|
+
|
5
|
+
module CitrusAdmin
|
6
|
+
# Client
|
7
|
+
#
|
8
|
+
#
|
9
|
+
class Client
|
10
|
+
include Protocol
|
11
|
+
include Utils::EventEmitter
|
12
|
+
|
13
|
+
# Create a new client
|
14
|
+
#
|
15
|
+
# @param [Hash] args Options
|
16
|
+
#
|
17
|
+
# @option args [String] :username
|
18
|
+
# @option args [String] :password
|
19
|
+
# @option args [Boolean] :md5
|
20
|
+
def initialize args={}
|
21
|
+
@client_id = ''
|
22
|
+
@req_id = 1
|
23
|
+
@callbacks = {}
|
24
|
+
@state = :state_inited
|
25
|
+
@username = args[:username] || ''
|
26
|
+
@password = args[:password] || ''
|
27
|
+
@md5 = args[:md5] || false
|
28
|
+
end
|
29
|
+
|
30
|
+
# Connect to master server
|
31
|
+
#
|
32
|
+
# @param [String] client_id
|
33
|
+
# @param [String] host
|
34
|
+
# @param [String] port
|
35
|
+
def connect client_id, host, port, &block
|
36
|
+
@client_id = client_id
|
37
|
+
@ws = WebSocket::EventMachine::Client.connect :uri => 'ws://' + host + ':' + port.to_s
|
38
|
+
@ws.onopen {
|
39
|
+
@state = :state_connected
|
40
|
+
@password = Utils.md5 @password if @md5
|
41
|
+
@ws.send ['register', {
|
42
|
+
:type => 'client',
|
43
|
+
:client_id => @client_id,
|
44
|
+
:username => @username,
|
45
|
+
:password => @password,
|
46
|
+
:md5 => @md5
|
47
|
+
}].to_json
|
48
|
+
}
|
49
|
+
@ws.onmessage { |msg, type|
|
50
|
+
begin
|
51
|
+
event, msg = parse msg
|
52
|
+
case event
|
53
|
+
when 'register'
|
54
|
+
process_register_msg msg, &block
|
55
|
+
when 'client'
|
56
|
+
process_client_msg msg
|
57
|
+
else
|
58
|
+
end
|
59
|
+
rescue => err
|
60
|
+
end
|
61
|
+
}
|
62
|
+
@ws.onclose { |code, reason|
|
63
|
+
@state = :state_closed
|
64
|
+
emit 'close'
|
65
|
+
}
|
66
|
+
@ws.onerror { |err|
|
67
|
+
if @state == :state_inited
|
68
|
+
block_given? and yield err
|
69
|
+
end
|
70
|
+
emit 'error', err
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
# Request master server with callback
|
75
|
+
#
|
76
|
+
# @param [String] module_id
|
77
|
+
# @param [Object] msg
|
78
|
+
def request module_id, msg, &block
|
79
|
+
req_id = @req_id
|
80
|
+
@req_id += 1
|
81
|
+
@callbacks[req_id] = block
|
82
|
+
msg[:client_id] = @client_id
|
83
|
+
msg[:username] = @username
|
84
|
+
@ws.send ['client', compose_request(req_id, module_id, msg)].to_json
|
85
|
+
end
|
86
|
+
|
87
|
+
# Notify master server without callback
|
88
|
+
#
|
89
|
+
# @param [String] module_id
|
90
|
+
# @param [Object] msg
|
91
|
+
def notify module_id, msg
|
92
|
+
msg[:client_id] = @client_id
|
93
|
+
msg[:username] = @username
|
94
|
+
@ws.send ['client', compose_request(nil, module_id, msg)].to_json
|
95
|
+
end
|
96
|
+
|
97
|
+
# Command
|
98
|
+
#
|
99
|
+
# @param [String] command
|
100
|
+
# @param [String] module_id
|
101
|
+
# @param [Object] msg
|
102
|
+
def command command, module_id, msg, &block
|
103
|
+
req_id = @req_id
|
104
|
+
@req_id += 1
|
105
|
+
@callbacks[req_id] = block
|
106
|
+
msg[:client_id] = @client_id
|
107
|
+
msg[:username] = @username
|
108
|
+
@ws.send ['client', compose_command(req_id, command, module_id, msg)].to_json
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
# Process register message
|
114
|
+
#
|
115
|
+
# @param [Object] msg
|
116
|
+
#
|
117
|
+
# @private
|
118
|
+
def process_register_msg msg, &block
|
119
|
+
if msg[:code] != PRO_OK
|
120
|
+
block_given? and yield msg[:msg]
|
121
|
+
return
|
122
|
+
end
|
123
|
+
@state = :state_registered
|
124
|
+
block_given? and yield
|
125
|
+
end
|
126
|
+
|
127
|
+
# Process client message
|
128
|
+
#
|
129
|
+
# @param [Object] msg
|
130
|
+
#
|
131
|
+
# @private
|
132
|
+
def process_client_msg msg
|
133
|
+
if resp_id = msg[:resp_id]
|
134
|
+
callback = @callbacks[resp_id]
|
135
|
+
@callbacks.delete resp_id
|
136
|
+
callback.call msg[:err], msg[:body]
|
137
|
+
elsif module_id = msg[:module_id]
|
138
|
+
emit module_id, msg
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,374 @@
|
|
1
|
+
# Author:: MinixLi (gmail: MinixLi1986)
|
2
|
+
# Homepage:: http://citrus.inspawn.com
|
3
|
+
# Date:: 8 July 2014
|
4
|
+
|
5
|
+
require 'citrus-admin/master_agent'
|
6
|
+
require 'citrus-admin/monitor_agent'
|
7
|
+
|
8
|
+
module CitrusAdmin
|
9
|
+
# ConsoleService
|
10
|
+
#
|
11
|
+
#
|
12
|
+
class ConsoleService
|
13
|
+
include Protocol
|
14
|
+
include Utils; include Utils::EventEmitter
|
15
|
+
|
16
|
+
attr_reader :env, :master, :agent, :auth_user, :auth_server
|
17
|
+
|
18
|
+
# Create a new console service
|
19
|
+
#
|
20
|
+
# @param [Hash] args Options
|
21
|
+
#
|
22
|
+
# @option args [Boolean] :master
|
23
|
+
# @option args [String] :host
|
24
|
+
# @option args [Integer] :port
|
25
|
+
# @option args [String] :server_id
|
26
|
+
# @option args [String] :server_type
|
27
|
+
# @option args [Object] :server_info
|
28
|
+
# @option args [#call] :auth_user
|
29
|
+
# @option args [#call] :auth_server
|
30
|
+
def initialize args={}
|
31
|
+
@env = args[:env]
|
32
|
+
@master = args[:master]
|
33
|
+
@port = args[:port]
|
34
|
+
@console_modules = {}
|
35
|
+
@commands = {
|
36
|
+
:list => methods(:list_command),
|
37
|
+
:enable => methods(:enable_command),
|
38
|
+
:disable => methods(:disable_command)
|
39
|
+
}
|
40
|
+
if @master
|
41
|
+
@auth_user = args[:auth_user] || method(:df_auth_user)
|
42
|
+
@auth_server = args[:auth_server] || method(:df_auth_server_master)
|
43
|
+
args[:console_service] = self
|
44
|
+
@agent = MasterAgent.new args
|
45
|
+
else
|
46
|
+
@host = args[:host]
|
47
|
+
@server_id = args[:server_id]
|
48
|
+
@server_type = args[:server_type]
|
49
|
+
@auth_server = args[:auth_server] || method(:df_auth_server_monitor)
|
50
|
+
@agent = MonitorAgent.new({
|
51
|
+
:console_service => self,
|
52
|
+
:server_id => @server_id,
|
53
|
+
:server_type => @server_type,
|
54
|
+
:server_info => args[:server_info]
|
55
|
+
})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Start master agent or monitor agent
|
60
|
+
def start &block
|
61
|
+
if @master
|
62
|
+
@agent.listen(@port) { |err|
|
63
|
+
if err
|
64
|
+
block_given? and yield err
|
65
|
+
return
|
66
|
+
end
|
67
|
+
|
68
|
+
@agent.on('register') { |*args| emit 'register', *args }
|
69
|
+
@agent.on('disconnect') { |*args| emit 'disconnect', *args }
|
70
|
+
@agent.on('reconnect') { |*args| emit 'reconnect', *args }
|
71
|
+
|
72
|
+
EM.next_tick {
|
73
|
+
block_given? and yield
|
74
|
+
}
|
75
|
+
}
|
76
|
+
else
|
77
|
+
@agent.connect @port, @host, &block
|
78
|
+
end
|
79
|
+
@console_modules.each { |module_id, console_module|
|
80
|
+
enable_module module_id
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
# Stop master agent or monitor agent
|
85
|
+
def stop
|
86
|
+
@console_modules.each { |module_id, console_module|
|
87
|
+
disable_module module_id
|
88
|
+
}
|
89
|
+
@agent.close
|
90
|
+
end
|
91
|
+
|
92
|
+
# Register console module
|
93
|
+
#
|
94
|
+
# @param [String] module_id
|
95
|
+
# @param [Object] module_entity
|
96
|
+
def register module_id, module_entity
|
97
|
+
console_module = {
|
98
|
+
:module_id => module_id,
|
99
|
+
:module_entity => module_entity,
|
100
|
+
:enable => false
|
101
|
+
}
|
102
|
+
|
103
|
+
if type = module_entity.type
|
104
|
+
if @master && type == 'pull' || !@master && type == 'push'
|
105
|
+
delay = module_entity.delay
|
106
|
+
interval = module_entity.interval
|
107
|
+
console_module[:delay] = delay ? (delay > 0 ? delay : 0) : 0
|
108
|
+
console_module[:interval] = interval ? (interval > 0 ? interval : 0) : 1
|
109
|
+
console_module[:schedule] = true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
@console_modules[module_id] = console_module
|
114
|
+
end
|
115
|
+
|
116
|
+
# Enable console module
|
117
|
+
#
|
118
|
+
# @param [String] module_id
|
119
|
+
def enable_module module_id
|
120
|
+
console_module = @console_modules[module_id]
|
121
|
+
if console_module && !console_module[:enable]
|
122
|
+
console_module[:enable] = true
|
123
|
+
if console_module[:schedule]
|
124
|
+
add_to_scheduler console_module
|
125
|
+
end
|
126
|
+
return true
|
127
|
+
end
|
128
|
+
return false
|
129
|
+
end
|
130
|
+
|
131
|
+
# Disable console module
|
132
|
+
#
|
133
|
+
# @param [String] module_id
|
134
|
+
def disable_module module_id
|
135
|
+
console_module = @console_modules[module_id]
|
136
|
+
if console_module && console_module[:enable]
|
137
|
+
console_module[:enable] = false
|
138
|
+
if console_module[:schedule] && console_module[:job_id]
|
139
|
+
remove_from_scheduler console_module
|
140
|
+
end
|
141
|
+
return true
|
142
|
+
end
|
143
|
+
return false
|
144
|
+
end
|
145
|
+
|
146
|
+
# Execute console module's handler (monitor_handler, master_handler, client_handler)
|
147
|
+
#
|
148
|
+
# @param [String] module_id
|
149
|
+
# @param [String] method
|
150
|
+
# @param [Object] msg
|
151
|
+
def execute module_id, method, msg, &block
|
152
|
+
if !block_given?
|
153
|
+
raise ArgumentError 'expected a code block'
|
154
|
+
end
|
155
|
+
|
156
|
+
console_module = @console_modules[module_id]
|
157
|
+
if !console_module
|
158
|
+
yield 'unknown module id: ' + module_id
|
159
|
+
return
|
160
|
+
end
|
161
|
+
if !console_module[:enable]
|
162
|
+
yield 'module ' + module_id + ' is disabled'
|
163
|
+
return
|
164
|
+
end
|
165
|
+
module_entity = console_module[:module_entity]
|
166
|
+
if !module_entity
|
167
|
+
yield 'module ' + module_id + ' does not exist'
|
168
|
+
return
|
169
|
+
end
|
170
|
+
if !module_entity.respond_to? method
|
171
|
+
yield 'module ' + module_id + ' does not have such method: ' + method
|
172
|
+
return
|
173
|
+
end
|
174
|
+
acl_msg = acl_control 'execute', method, module_id, msg
|
175
|
+
if acl_msg != 0 && acl_msg != 1
|
176
|
+
yield Exception.new acl_msg
|
177
|
+
return
|
178
|
+
end
|
179
|
+
module_entity.send method, @agent, msg, &block
|
180
|
+
end
|
181
|
+
|
182
|
+
# Execute command
|
183
|
+
#
|
184
|
+
# @param [String] command
|
185
|
+
# @param [String] module_id
|
186
|
+
# @param [Object] msg
|
187
|
+
def command command, module_id, msg, &block
|
188
|
+
if !block_given?
|
189
|
+
raise ArgumentError 'expected a code block'
|
190
|
+
end
|
191
|
+
|
192
|
+
method = @commands[command.to_sym]
|
193
|
+
if !method
|
194
|
+
yield 'unknown command: ' + command
|
195
|
+
return
|
196
|
+
end
|
197
|
+
if !method.respond_to? :call
|
198
|
+
yield 'unknown command: ' + command
|
199
|
+
return
|
200
|
+
end
|
201
|
+
|
202
|
+
acl_msg = acl_control 'command', nil, module_id, msg
|
203
|
+
if acl_msg != 0 && acl_msg != 1
|
204
|
+
yield Exception.new acl_msg
|
205
|
+
return
|
206
|
+
end
|
207
|
+
|
208
|
+
method.call module_id, msg, &block
|
209
|
+
end
|
210
|
+
|
211
|
+
private
|
212
|
+
|
213
|
+
# Add console module to scheduler
|
214
|
+
#
|
215
|
+
# @param [Object] console_module
|
216
|
+
#
|
217
|
+
# @private
|
218
|
+
def add_to_scheduler console_module
|
219
|
+
args = [
|
220
|
+
# job_cb
|
221
|
+
method(:schedule_job_cb),
|
222
|
+
# job_cb_args
|
223
|
+
{ :console_module => console_module },
|
224
|
+
# trigger_args
|
225
|
+
{
|
226
|
+
:start_time => Time.now.to_f + console_module[:delay],
|
227
|
+
:interval => console_module[:interval]
|
228
|
+
}
|
229
|
+
]
|
230
|
+
console_module[:job_id] = CitrusScheduler.schedule_job *args
|
231
|
+
end
|
232
|
+
|
233
|
+
# Remove console module from scheduler
|
234
|
+
#
|
235
|
+
# @param [Object] console_module
|
236
|
+
#
|
237
|
+
# @private
|
238
|
+
def remove_from_scheduler console_module
|
239
|
+
CitrusScheduler.cancel_job console_module[:job_id]
|
240
|
+
console_module[:job_id] = nil
|
241
|
+
end
|
242
|
+
|
243
|
+
# Schedule job callback
|
244
|
+
#
|
245
|
+
# @param [Hash] args Options
|
246
|
+
#
|
247
|
+
# @option args [Object] :console_module
|
248
|
+
#
|
249
|
+
# @private
|
250
|
+
def schedule_job_cb args={}
|
251
|
+
console_module = args[:console_module]
|
252
|
+
return if !console_module || !console_module[:enable]
|
253
|
+
|
254
|
+
module_entity = console_module[:module_entity]
|
255
|
+
return if !module_entity
|
256
|
+
|
257
|
+
if @master
|
258
|
+
module_entity.master_handler(@agent, nil) { |err| }
|
259
|
+
else
|
260
|
+
module_entity.monitor_handler(@agent, nil) { |err| }
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# List console modules
|
265
|
+
#
|
266
|
+
# @param [String] module_id
|
267
|
+
# @param [Object] msg
|
268
|
+
#
|
269
|
+
# @private
|
270
|
+
def list_command module_id, msg, &block
|
271
|
+
block.call nil, @console_modules.select { |module_id, console_module|
|
272
|
+
!(module_id =~ /^__\w+__$/)
|
273
|
+
}
|
274
|
+
end
|
275
|
+
|
276
|
+
# Enable console module
|
277
|
+
#
|
278
|
+
# @param [String] module_id
|
279
|
+
# @param [Object] msg
|
280
|
+
#
|
281
|
+
# @private
|
282
|
+
def enable_command module_id, msg, &block
|
283
|
+
if !block_given?
|
284
|
+
raise ArgumentError 'expected a code block'
|
285
|
+
end
|
286
|
+
if !@console_modules[module_id]
|
287
|
+
yield nil, PRO_FAIL
|
288
|
+
return
|
289
|
+
end
|
290
|
+
enable_module module_id
|
291
|
+
if @master
|
292
|
+
@agent.broadcast_command 'enable', module_id, msg
|
293
|
+
end
|
294
|
+
yield nil, PRO_OK
|
295
|
+
end
|
296
|
+
|
297
|
+
# Disable console module
|
298
|
+
#
|
299
|
+
# @param [String] module_id
|
300
|
+
# @param [Object] msg
|
301
|
+
#
|
302
|
+
# @private
|
303
|
+
def disable_command module_id, msg, &block
|
304
|
+
if !block_given?
|
305
|
+
raise ArgumentError 'expected a code block'
|
306
|
+
end
|
307
|
+
if !@console_modules[module_id]
|
308
|
+
yield nil, PRO_FAIL
|
309
|
+
return
|
310
|
+
end
|
311
|
+
disable_module module_id
|
312
|
+
if @master
|
313
|
+
@agent.broadcast_command 'disable', module_id, msg
|
314
|
+
end
|
315
|
+
yield nil, PRO_OK
|
316
|
+
end
|
317
|
+
|
318
|
+
# ACL control
|
319
|
+
#
|
320
|
+
# @param [String] action
|
321
|
+
# @param [String] method
|
322
|
+
# @param [String] module_id
|
323
|
+
# @param [Object] msg
|
324
|
+
#
|
325
|
+
# @private
|
326
|
+
def acl_control action, method, module_id, msg
|
327
|
+
if action == 'execute'
|
328
|
+
if method != 'client_handler' || module_id != '__console__'
|
329
|
+
return 0
|
330
|
+
end
|
331
|
+
signal = msg[:signal]
|
332
|
+
if !signal || !(['stop', 'add', 'kill'].include? signal)
|
333
|
+
return 0
|
334
|
+
end
|
335
|
+
end
|
336
|
+
if !client_id = msg[:client_id]
|
337
|
+
return 'unknown client id'
|
338
|
+
end
|
339
|
+
client = @agent.get_client_by_id client_id
|
340
|
+
if client && client[:user_info] && client[:user_info][:level]
|
341
|
+
level = client[:user_info][:level]
|
342
|
+
if level > 1
|
343
|
+
return 'command permission denied'
|
344
|
+
end
|
345
|
+
else
|
346
|
+
return 'unknown client info'
|
347
|
+
end
|
348
|
+
return 1
|
349
|
+
end
|
350
|
+
|
351
|
+
# Create master console service
|
352
|
+
#
|
353
|
+
# @param [Hash] args Options
|
354
|
+
#
|
355
|
+
# @option args [Integer] :port
|
356
|
+
def self.create_master_console args={}
|
357
|
+
args[:master] = true
|
358
|
+
ConsoleService.new args
|
359
|
+
end
|
360
|
+
|
361
|
+
# Create monitor console service
|
362
|
+
#
|
363
|
+
# @param [Hash] args Options
|
364
|
+
#
|
365
|
+
# @option args [String] :host
|
366
|
+
# @option args [Integer] :port
|
367
|
+
# @option args [String] :server_id
|
368
|
+
# @option args [String] :server_type
|
369
|
+
# @option args [Object] :server_info
|
370
|
+
def self.create_monitor_console args={}
|
371
|
+
ConsoleService.new args
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|