zabby 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ &mdash; 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> &raquo;
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
@@ -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
@@ -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