zabby 0.0.2
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.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/LICENSE +49 -0
- data/README.rdoc +137 -0
- data/Rakefile +8 -0
- data/bin/zabbyrb +86 -0
- data/bin/zabbysh +68 -0
- data/doc/Zabby.html +208 -0
- data/doc/Zabby/AuthenticationError.html +116 -0
- data/doc/Zabby/Config.html +414 -0
- data/doc/Zabby/ConfigurationError.html +116 -0
- data/doc/Zabby/Connection.html +1617 -0
- data/doc/Zabby/ResponseCodeError.html +116 -0
- data/doc/Zabby/Runner.html +1116 -0
- data/doc/_index.html +175 -0
- data/doc/class_list.html +47 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +55 -0
- data/doc/css/style.css +322 -0
- data/doc/file.LICENSE.html +132 -0
- data/doc/file.README.html +234 -0
- data/doc/file_list.html +52 -0
- data/doc/frames.html +13 -0
- data/doc/index.html +234 -0
- data/doc/js/app.js +205 -0
- data/doc/js/full_list.js +167 -0
- data/doc/js/jquery.js +16 -0
- data/doc/method_list.html +358 -0
- data/doc/top-level-namespace.html +103 -0
- data/lib/zabby.rb +25 -0
- data/lib/zabby/config.rb +38 -0
- data/lib/zabby/connection.rb +131 -0
- data/lib/zabby/exceptions.rb +10 -0
- data/lib/zabby/runner.rb +152 -0
- data/lib/zabby/version.rb +8 -0
- data/lib/zabby/zobject.rb +27 -0
- data/spec/spec_helper.rb +5 -0
- data/zabby.gemspec +31 -0
- metadata +170 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=fr_fr" />
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.7.4
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
|
16
|
+
|
17
|
+
<script type="text/javascript" charset="utf-8">
|
18
|
+
relpath = '';
|
19
|
+
if (relpath != '') relpath += '/';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
23
|
+
|
24
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
25
|
+
|
26
|
+
|
27
|
+
</head>
|
28
|
+
<body>
|
29
|
+
<script type="text/javascript" charset="utf-8">
|
30
|
+
if (window.top.frames.main) document.body.className = 'frames';
|
31
|
+
</script>
|
32
|
+
|
33
|
+
<div id="header">
|
34
|
+
<div id="menu">
|
35
|
+
|
36
|
+
<a href="_index.html">Index</a> »
|
37
|
+
|
38
|
+
|
39
|
+
<span class="title">Top Level Namespace</span>
|
40
|
+
|
41
|
+
|
42
|
+
<div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<div id="search">
|
46
|
+
|
47
|
+
<a id="class_list_link" href="#">Class List</a>
|
48
|
+
|
49
|
+
<a id="method_list_link" href="#">Method List</a>
|
50
|
+
|
51
|
+
<a id="file_list_link" href="#">File List</a>
|
52
|
+
|
53
|
+
</div>
|
54
|
+
<div class="clear"></div>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<iframe id="search_frame"></iframe>
|
58
|
+
|
59
|
+
<div id="content"><h1>Top Level Namespace
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
</h1>
|
64
|
+
|
65
|
+
<dl class="box">
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
</dl>
|
75
|
+
<div class="clear"></div>
|
76
|
+
|
77
|
+
<h2>Defined Under Namespace</h2>
|
78
|
+
<p class="children">
|
79
|
+
|
80
|
+
|
81
|
+
<strong class="modules">Modules:</strong> <span class='object_link'><a href="Zabby.html" title="Zabby (module)">Zabby</a></span>
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
</p>
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
</div>
|
95
|
+
|
96
|
+
<div id="footer">
|
97
|
+
Generated on Mon Dec 19 13:31:47 2011 by
|
98
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
99
|
+
0.7.4 (ruby-1.8.7).
|
100
|
+
</div>
|
101
|
+
|
102
|
+
</body>
|
103
|
+
</html>
|
data/lib/zabby.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Author:: Farzad FARID (<ffarid@pragmatic-source.com>)
|
3
|
+
# Copyright:: Copyright (c) 2011 Farzad FARID
|
4
|
+
# License:: Simplified BSD License
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'json'
|
8
|
+
require 'net/http'
|
9
|
+
require 'net/https'
|
10
|
+
require 'openssl'
|
11
|
+
require 'uri'
|
12
|
+
require 'pp'
|
13
|
+
|
14
|
+
require 'zabby/version'
|
15
|
+
require 'zabby/exceptions'
|
16
|
+
require 'zabby/config'
|
17
|
+
require 'zabby/zobject'
|
18
|
+
require 'zabby/connection'
|
19
|
+
require 'zabby/runner'
|
20
|
+
|
21
|
+
module Zabby
|
22
|
+
def self.init &block
|
23
|
+
Zabby::Runner.instance &block
|
24
|
+
end
|
25
|
+
end
|
data/lib/zabby/config.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Author:: Farzad FARID (<ffarid@pragmatic-source.com>)
|
3
|
+
# Copyright:: Copyright (c) 2011 Farzad FARID
|
4
|
+
# License:: Simplified BSD License
|
5
|
+
|
6
|
+
# Configuration setting
|
7
|
+
module Zabby
|
8
|
+
class Config
|
9
|
+
SETTING_LIST = %w{server user password proxy_host proxy_user proxy_password}
|
10
|
+
|
11
|
+
def initialize &block
|
12
|
+
setup(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup &block
|
16
|
+
instance_eval(&block) if block_given?
|
17
|
+
end
|
18
|
+
|
19
|
+
def list
|
20
|
+
SETTING_LIST.each do |k|
|
21
|
+
puts "#{k} = #{instance_variable_get("@#{k}")}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def method_missing(name, *args, &block)
|
26
|
+
name = name.to_s.gsub(/=$/, '')
|
27
|
+
raise ConfigurationError.new("Unknown setting '#{name}'") if !SETTING_LIST.include?(name.to_s)
|
28
|
+
|
29
|
+
if args.empty?
|
30
|
+
instance_variable_get("@#{name}")
|
31
|
+
elsif args.size != 1
|
32
|
+
raise ConfigurationError.new("Too many values for '#{name}'")
|
33
|
+
else
|
34
|
+
instance_variable_set("@#{name}", args.first)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Author:: Farzad FARID (<ffarid@pragmatic-source.com>)
|
3
|
+
# Copyright:: Copyright (c) 2011 Farzad FARID
|
4
|
+
# License:: Simplified BSD License
|
5
|
+
|
6
|
+
module Zabby
|
7
|
+
class Connection
|
8
|
+
attr_reader :uri, :request_path, :user, :password, :proxy_host, :proxy_user, :proxy_password
|
9
|
+
attr_reader :auth
|
10
|
+
attr_reader :request_id
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
reset
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset
|
17
|
+
@uri = @user = @password = @proxy_host = @proxy_user = @proxy_password = nil
|
18
|
+
@request_id = 0
|
19
|
+
@auth = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def login(config)
|
23
|
+
return @auth if @auth
|
24
|
+
|
25
|
+
@uri = URI.parse(config.server)
|
26
|
+
@user = config.user
|
27
|
+
@password = config.password
|
28
|
+
if config.proxy_host
|
29
|
+
@proxy_host = URI.parse(config.proxy_host)
|
30
|
+
@proxy_user = config.proxy_user
|
31
|
+
@proxy_password = config.proxy_password
|
32
|
+
end
|
33
|
+
@request_path = @uri.path.empty? ? "/api_jsonrpc.php" : @uri.path
|
34
|
+
authenticate
|
35
|
+
end
|
36
|
+
|
37
|
+
def logout
|
38
|
+
reset
|
39
|
+
end
|
40
|
+
|
41
|
+
def logged_in?
|
42
|
+
!@auth.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def next_request_id
|
46
|
+
@request_id += 1
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Authentication key]
|
50
|
+
def authenticate
|
51
|
+
auth_message = format_message('user', 'login',
|
52
|
+
'user' => @user,
|
53
|
+
'password' => @password)
|
54
|
+
@auth = query_zabbix_rpc(auth_message)
|
55
|
+
rescue Exception => e
|
56
|
+
@auth = nil
|
57
|
+
raise e
|
58
|
+
end
|
59
|
+
|
60
|
+
def format_message(element, action, params = {})
|
61
|
+
{
|
62
|
+
'jsonrpc' => '2.0',
|
63
|
+
'id' => next_request_id,
|
64
|
+
'method' => "#{element}.#{action}",
|
65
|
+
'params' => params,
|
66
|
+
'auth' => @auth
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def perform_request(element, action, params)
|
71
|
+
raise AuthenticationError.new("Not logged in") if !logged_in?
|
72
|
+
|
73
|
+
message = format_message(element, action, params)
|
74
|
+
query_zabbix_rpc(message)
|
75
|
+
end
|
76
|
+
|
77
|
+
def request(message)
|
78
|
+
req = Net::HTTP::Post.new(@request_path)
|
79
|
+
req.add_field('Content-Type', 'application/json-rpc')
|
80
|
+
req.body = JSON.generate(message)
|
81
|
+
req
|
82
|
+
end
|
83
|
+
|
84
|
+
# Prepare http object
|
85
|
+
def http
|
86
|
+
if @proxy_host
|
87
|
+
http = Net::HTTP::Proxy(@proxy_host.host, @proxy_host.port, @proxy_user, @proxy_password).new(@uri.host, @uri.port)
|
88
|
+
else
|
89
|
+
http = Net::HTTP.new(@uri.host, @uri.port)
|
90
|
+
end
|
91
|
+
if @uri.scheme == "https"
|
92
|
+
http.use_ssl = true
|
93
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
94
|
+
end
|
95
|
+
http
|
96
|
+
end
|
97
|
+
|
98
|
+
def query_zabbix_rpc(message)
|
99
|
+
# Send the request!
|
100
|
+
response = http.request(request(message))
|
101
|
+
|
102
|
+
if response.code != "200" then
|
103
|
+
raise ResponseCodeError.new("Response code from [#{@uri}] is #{response.code}): #{response.body}")
|
104
|
+
end
|
105
|
+
|
106
|
+
zabbix_response = JSON.parse(response.body)
|
107
|
+
|
108
|
+
#if not ( responce_body_hash['id'] == id ) then
|
109
|
+
# raise Zabbix::InvalidAnswerId.new("Wrong ID in zabbix answer")
|
110
|
+
#end
|
111
|
+
|
112
|
+
# Check errors in zabbix answer. If error exist - raise exception Zabbix::Error
|
113
|
+
if (error = zabbix_response['error']) then
|
114
|
+
error_message = error['message']
|
115
|
+
error_data = error['data']
|
116
|
+
error_code = error['code']
|
117
|
+
|
118
|
+
e_message = "Code: [" + error_code.to_s + "]. Message: [" + error_message +
|
119
|
+
"]. Data: [" + error_data + "]."
|
120
|
+
|
121
|
+
if error_data == "Login name or password is incorrect"
|
122
|
+
raise AuthenticationError.new(e_message)
|
123
|
+
else
|
124
|
+
raise StandardError.new(e_message)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
zabbix_response['result']
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Author:: Farzad FARID (<ffarid@pragmatic-source.com>)
|
3
|
+
# Copyright:: Copyright (c) 2011 Farzad FARID
|
4
|
+
# License:: Simplified BSD License
|
5
|
+
|
6
|
+
module Zabby
|
7
|
+
class ResponseCodeError < StandardError; end
|
8
|
+
class AuthenticationError < StandardError; end
|
9
|
+
class ConfigurationError < StandardError; end
|
10
|
+
end
|
data/lib/zabby/runner.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Author:: Farzad FARID (<ffarid@pragmatic-source.com>)
|
3
|
+
# Copyright:: Copyright (c) 2011 Farzad FARID
|
4
|
+
# License:: Simplified BSD License
|
5
|
+
|
6
|
+
require 'singleton'
|
7
|
+
begin
|
8
|
+
require 'readline'
|
9
|
+
rescue LoadError
|
10
|
+
# No readline
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
module Zabby
|
15
|
+
class Runner
|
16
|
+
include Singleton
|
17
|
+
|
18
|
+
attr_reader :config, :connection
|
19
|
+
|
20
|
+
# Meta-create methods with the same name as the configuration settings.
|
21
|
+
# This way we can write:
|
22
|
+
# set host "http://my.zabbix.server"
|
23
|
+
# instead of:
|
24
|
+
# set :host => "http://my.zabbix.server"
|
25
|
+
# or "set host" instead of "set :host"
|
26
|
+
# All the created method does is return the second form which will be
|
27
|
+
# used by "set".
|
28
|
+
Zabby::Config::SETTING_LIST.each { |setting|
|
29
|
+
# TODO: Ruby 1.8 does not support default values for block arguments..
|
30
|
+
# Writing "... do |value = nil|" would be more elegant.
|
31
|
+
define_method(setting) do |*args|
|
32
|
+
if args.empty?
|
33
|
+
setting.intern
|
34
|
+
else
|
35
|
+
{ setting.intern => args.first }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
}
|
39
|
+
|
40
|
+
def self.create_zobject(name, zmethods)
|
41
|
+
define_method(name) do
|
42
|
+
@zobject[name] ||= Zabby::ZObject.new(name, zmethods)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
create_zobject(:host, [ :get, :exists, :create, :update, :delete ])
|
47
|
+
create_zobject(:item, [ :get, :exists, :create, :update, :delete ])
|
48
|
+
create_zobject(:apiinfo, [ :version ])
|
49
|
+
|
50
|
+
def initialize &block
|
51
|
+
@config = Zabby::Config.new &block
|
52
|
+
@connection = Zabby::Connection.new
|
53
|
+
@pure_binding = instance_eval "binding"
|
54
|
+
@zobject = {} # List of Zabbix Object
|
55
|
+
|
56
|
+
if Object.const_defined?(:Readline)
|
57
|
+
@readline = true
|
58
|
+
Readline.basic_word_break_characters = ""
|
59
|
+
Readline.completion_append_character = nil
|
60
|
+
#Readline.completion_proc = completion_proc
|
61
|
+
|
62
|
+
$last_res = nil
|
63
|
+
else
|
64
|
+
@readline = false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def setup &block
|
69
|
+
@config.setup &block
|
70
|
+
end
|
71
|
+
|
72
|
+
def set(key_value = nil)
|
73
|
+
if key_value.nil?
|
74
|
+
@config.list
|
75
|
+
elsif [ String, Symbol ].include?(key_value.class)
|
76
|
+
puts "#{key_value} = #{@config.send(key_value)}"
|
77
|
+
elsif key_value.instance_of? Hash
|
78
|
+
key = key_value.keys.first
|
79
|
+
value = key_value[key]
|
80
|
+
@config.send(key, value)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def login
|
85
|
+
@connection.login(@config)
|
86
|
+
end
|
87
|
+
|
88
|
+
def logout
|
89
|
+
@connection.logout
|
90
|
+
end
|
91
|
+
|
92
|
+
def logged_in?
|
93
|
+
@connection.logged_in?
|
94
|
+
end
|
95
|
+
|
96
|
+
def version
|
97
|
+
Zabby::VERSION
|
98
|
+
end
|
99
|
+
|
100
|
+
# @param command_file [String] Filename containing commands to execute.
|
101
|
+
# @param block [Proc] A block containing commands to execute.
|
102
|
+
def run(command_file = nil, &block)
|
103
|
+
unless command_file.nil?
|
104
|
+
commands = File.read(command_file)
|
105
|
+
instance_eval(commands)
|
106
|
+
end
|
107
|
+
instance_eval(&block) if block_given?
|
108
|
+
end
|
109
|
+
|
110
|
+
# Execute an irb like shell in which we can type Zabby commands.
|
111
|
+
def shell
|
112
|
+
raise RuntimeError.new("Shell cannot run because 'readline' is missing.") if !@readline
|
113
|
+
|
114
|
+
puts "Zabby Shell #{Zabby::VERSION}"
|
115
|
+
puts
|
116
|
+
puts "** This is a simple irb like Zabbix Shell. Multiline commands do not work for e.g. **"
|
117
|
+
loop do
|
118
|
+
cmd = Readline.readline('zabby> ')
|
119
|
+
|
120
|
+
exit(0) if cmd.nil? or cmd == 'exit'
|
121
|
+
next if cmd == ""
|
122
|
+
Readline::HISTORY.push(cmd)
|
123
|
+
|
124
|
+
execute(cmd)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
# Run a single command.
|
131
|
+
# @param cmd [String] A command to execute in the object's context.
|
132
|
+
def execute(cmd)
|
133
|
+
res = eval(cmd, @pure_binding)
|
134
|
+
$last_res = res
|
135
|
+
eval("_ = $last_res", @pure_binding)
|
136
|
+
print_result res
|
137
|
+
rescue ::Exception => e
|
138
|
+
puts "Exception #{e.class} -> #{e.message}"
|
139
|
+
e.backtrace.each do |t|
|
140
|
+
puts " #{::File.expand_path(t)}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def print_result(res)
|
145
|
+
if res.kind_of? String
|
146
|
+
puts res
|
147
|
+
else
|
148
|
+
puts "=> #{res.inspect}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|