sky_zabbix 2.2.0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +10 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/Guardfile +16 -0
- data/LICENSE +21 -0
- data/README.md +133 -0
- data/Rakefile +49 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/build.php +193 -0
- data/lib/sky_zabbix.rb +8 -0
- data/lib/sky_zabbix/client.rb +35 -0
- data/lib/sky_zabbix/client/target_base.rb +52 -0
- data/lib/sky_zabbix/client/target_gen.rb +38 -0
- data/lib/sky_zabbix/jsonrpc.rb +149 -0
- data/lib/sky_zabbix/jsonrpc/errors.rb +50 -0
- data/lib/sky_zabbix/version.rb +7 -0
- data/sky_zabbix.gemspec +30 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ff08074897921a6aa9e27e47e9dca24e1bfbb526
|
4
|
+
data.tar.gz: 398e775d5b49ce049629daf25524f47f3336ae4c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dc0e9f1bfa5fd50ba218a29804ca4de24c9b60a41fd8e295258cb53af14b4a7e7517c13e545d42cd7d0ab9da8f3e23ff8e309d109169f4c1b97f7338785b1a0d
|
7
|
+
data.tar.gz: 9bc57cbb795d2040e20755aa6433288341dc9a21f53959b2e2ae5124b2206852da920b1d8fceab688c2c2444fb8a202887353b3ae7ccc9d96783fef7da3e5351
|
data/.editorconfig
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
5
|
+
# rspec may be run, below are examples of the most common uses.
|
6
|
+
# * bundler: 'bundle exec rspec'
|
7
|
+
# * bundler binstubs: 'bin/rspec'
|
8
|
+
# * spring: 'bin/rsspec' (This will use spring if running and you have
|
9
|
+
# installed the spring binstubs per the docs)
|
10
|
+
# * zeus: 'zeus rspec' (requires the server to be started separetly)
|
11
|
+
# * 'just' rspec: 'rspec'
|
12
|
+
guard :rspec, cmd: 'rspec --profile' do
|
13
|
+
watch(%r{^spec/.+_spec\.rb$})
|
14
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
15
|
+
watch('spec/spec_helper.rb') { "spec" }
|
16
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 SKYARCH NETWORKS INC.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
# SkyZabbix
|
2
|
+
|
3
|
+
SkyZabbix is a Zabbix API Wrapper written by Ruby.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
# If you use Zabbix 2.2
|
11
|
+
gem 'sky_zabbix', '~> 2.2.0'
|
12
|
+
# If you use Zabbix 2.4
|
13
|
+
gem 'sky_zabbix', '~> 2.4.0'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install sky_zabbix
|
23
|
+
|
24
|
+
## Version Policy
|
25
|
+
|
26
|
+
sky_zabbix version is composed of two parts.
|
27
|
+
|
28
|
+
The first two digits is a Zabbix version.
|
29
|
+
The last three digits is a Library version.
|
30
|
+
|
31
|
+
Library version conforms to [Semantic Versioning](http://semver.org/).
|
32
|
+
|
33
|
+
For example.
|
34
|
+
|
35
|
+
- If version is `2.4.0.1.0`
|
36
|
+
- Zabbix version is `2.4`
|
37
|
+
- Library version is `0.1.0`
|
38
|
+
|
39
|
+
## Supported Zabbix Version
|
40
|
+
|
41
|
+
2.2 or later.
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
### Initialize client and Authenticate
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
require 'sky_zabbix'
|
49
|
+
|
50
|
+
zabbix_url = 'http://zabbix.example.com/zabbix/api_jsonrpc.php'
|
51
|
+
zabbix_user = 'admin'
|
52
|
+
zabbix_pass = 'zabbix'
|
53
|
+
|
54
|
+
client = SkyZabbix::Client.new(zabbix_url)
|
55
|
+
client.login(zabbix_user, zabbix_pass)
|
56
|
+
```
|
57
|
+
|
58
|
+
### Basic Usage
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
client.host.get()
|
62
|
+
# => [{"hostid" => "10000"}, {"hostid" => "10001"}, ...]
|
63
|
+
|
64
|
+
client.host.create(
|
65
|
+
host: "HostName",
|
66
|
+
interfaces: [{
|
67
|
+
type: 1,
|
68
|
+
main: 1,
|
69
|
+
ip: "192.0.2.1",
|
70
|
+
dns: "hoge.example.com",
|
71
|
+
port: 10050,
|
72
|
+
useip: 0
|
73
|
+
}],
|
74
|
+
groups: [
|
75
|
+
groupid: "1",
|
76
|
+
]
|
77
|
+
)
|
78
|
+
# => {"hostids"=>["10119"]}
|
79
|
+
# and Created a new host to zabbix.
|
80
|
+
```
|
81
|
+
|
82
|
+
### Batch Request
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
requests = []
|
86
|
+
requests.push client.host.build_get()
|
87
|
+
requests.push client.user.build_get()
|
88
|
+
requests.push client.hostgroup.build_get()
|
89
|
+
host_resp, user_resp, hostgroup_resp = cleint.batch(*requests)
|
90
|
+
```
|
91
|
+
|
92
|
+
## Development
|
93
|
+
|
94
|
+
### Building
|
95
|
+
|
96
|
+
Required PHP.
|
97
|
+
|
98
|
+
Get [Zabbix](https://github.com/zabbix/zabbix) source code.
|
99
|
+
|
100
|
+
```sh
|
101
|
+
cd ~
|
102
|
+
get clone https://github.com/zabbix/zabbix
|
103
|
+
```
|
104
|
+
|
105
|
+
Generate list of API method as JSON.
|
106
|
+
|
107
|
+
```sh
|
108
|
+
export PATH_ZABBIX=~/zabbix/frontends/php/
|
109
|
+
rake generate:methods
|
110
|
+
```
|
111
|
+
|
112
|
+
Build gem.
|
113
|
+
|
114
|
+
```sh
|
115
|
+
rake build
|
116
|
+
```
|
117
|
+
|
118
|
+
### Testing
|
119
|
+
|
120
|
+
```sh
|
121
|
+
export ZABBIX_URL='http://zabbix.example.com/zabbix/api_jsonrpc.php'
|
122
|
+
export ZABBIX_USER='admin'
|
123
|
+
ZABBIX_PASS='zabbix'
|
124
|
+
rake spec
|
125
|
+
```
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
1. Fork it ( https://github.com/skyarch-networks/sky_zabbix/fork )
|
130
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
131
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
132
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
133
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require 'open3'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
require_relative 'lib/sky_zabbix/version'
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
|
10
|
+
task :default => :spec
|
11
|
+
|
12
|
+
namespace :generate do
|
13
|
+
#TODO: clone zabbix/zabbix, version
|
14
|
+
desc "Generate list of method"
|
15
|
+
task :methods do |task, args|
|
16
|
+
out, err, status = Open3.capture3("php", "build.php")
|
17
|
+
unless status.success?
|
18
|
+
puts err
|
19
|
+
exit(1)
|
20
|
+
end
|
21
|
+
File.write('lib/sky_zabbix/methods.json', JSON.pretty_generate(JSON.parse(out)))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
namespace :release do
|
26
|
+
desc "Release all version"
|
27
|
+
task :all do |task, args|
|
28
|
+
exec = -> (cmd) {
|
29
|
+
print '> '; puts cmd.join(' ')
|
30
|
+
system(*cmd)
|
31
|
+
}
|
32
|
+
|
33
|
+
versions = %w[2.2 2.4]
|
34
|
+
path = ENV['PATH_ZABBIX']
|
35
|
+
|
36
|
+
versions.each do |v|
|
37
|
+
Dir.chdir(path) do
|
38
|
+
latest_tag = `git tag`.split("\n").select{|x|x =~ /^#{Regexp.escape(v)}/}.sort{|a, b|a[/\.(\d+)$/, 1].to_i <=> b[/\.(\d+)$/, 1].to_i}.last
|
39
|
+
exec.(%W[git checkout #{latest_tag}])
|
40
|
+
end
|
41
|
+
Rake::Task['generate:methods'].execute
|
42
|
+
Rake::Task['build'].execute
|
43
|
+
end
|
44
|
+
pkgs = Dir.glob(File.join(File.expand_path('../pkg/', __FILE__), "sky_zabbix-*#{SkyZabbix::LIB_VERSION}.gem"))
|
45
|
+
pkgs.each do |p|
|
46
|
+
exec.(%W[gem push #{p}])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "sky_zabbix"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/build.php
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* This file based PhpZabbixApi/build.php.
|
4
|
+
*
|
5
|
+
* @file build.php
|
6
|
+
*
|
7
|
+
* @brief PHP script to build the PhpZabbixApi class(es).
|
8
|
+
*
|
9
|
+
* This file is part of PhpZabbixApi.
|
10
|
+
*
|
11
|
+
* PhpZabbixApi is free software: you can redistribute it and/or modify
|
12
|
+
* it under the terms of the GNU General Public License as published by
|
13
|
+
* the Free Software Foundation, either version 3 of the License, or
|
14
|
+
* (at your option) any later version.
|
15
|
+
*
|
16
|
+
* PhpZabbixApi is distributed in the hope that it will be useful,
|
17
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
* GNU General Public License for more details.
|
20
|
+
*
|
21
|
+
* You should have received a copy of the GNU General Public License
|
22
|
+
* along with PhpZabbixApi. If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
*
|
24
|
+
* @copyright GNU General Public License
|
25
|
+
* @author Skyarch Networks inc., confirm IT solutions GmbH, Rathausstrase 14, CH-6340 Baar
|
26
|
+
*/
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
// helper functions
|
31
|
+
function getProp($class, $prop_name) {
|
32
|
+
$ref = new ReflectionClass($class);
|
33
|
+
$refProp = new ReflectionProperty($class, $prop_name);
|
34
|
+
|
35
|
+
$obj = $ref->newInstance();
|
36
|
+
$refProp->setAccessible(true);
|
37
|
+
return $refProp->getValue($obj);
|
38
|
+
}
|
39
|
+
|
40
|
+
function assert_path($path, $name) {
|
41
|
+
if (is_dir($path) || file_exists($path)) { return; }
|
42
|
+
|
43
|
+
fputs(STDERR, 'ERROR: "' .$path. '" is not a directory! Please check the ' .$name);
|
44
|
+
die(1);
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
/*
|
49
|
+
* Define some pathes and do some sanity checks for existence of the pathes.
|
50
|
+
*/
|
51
|
+
|
52
|
+
define('PATH_ZABBIX', getenv('PATH_ZABBIX'));
|
53
|
+
assert_path(PATH_ZABBIX, 'PATH_ZABBIX environment');
|
54
|
+
|
55
|
+
// load Zabbix internal constants, to access ZABBIX_API_VERSION
|
56
|
+
require PATH_ZABBIX . '/include/defines.inc.php';
|
57
|
+
$is_2_4_or_later = version_compare(ZABBIX_API_VERSION, '2.4') >= 0 ;
|
58
|
+
|
59
|
+
/**
|
60
|
+
* @brief Path to the API.php class file of the Zabbix PHP front-end.
|
61
|
+
*
|
62
|
+
* This class file will be used, to determine all available API classes.
|
63
|
+
*/
|
64
|
+
define('PATH_ZABBIX_API_CLASS_FILE', PATH_ZABBIX.'/include/classes/api/API.php');
|
65
|
+
assert_path(PATH_ZABBIX_API_CLASS_FILE, 'PATH_ZABBIX_API_CLASS_FILE');
|
66
|
+
|
67
|
+
|
68
|
+
/**
|
69
|
+
* @brief Path to the api/classes/ directory of the Zabbix PHP front-end.
|
70
|
+
*
|
71
|
+
* This directory and the contained class files will be used, to determine all
|
72
|
+
* available methods for each API class.
|
73
|
+
*/
|
74
|
+
if($is_2_4_or_later) {
|
75
|
+
define('PATH_ZABBIX_API_CLASSES_DIRECTORY', PATH_ZABBIX.'/include/classes/api/services');
|
76
|
+
} else {
|
77
|
+
define('PATH_ZABBIX_API_CLASSES_DIRECTORY', PATH_ZABBIX.'/api/classes');
|
78
|
+
}
|
79
|
+
|
80
|
+
assert_path(PATH_ZABBIX_API_CLASSES_DIRECTORY, 'PATH_ZABBIX_API_CLASSES_DIRECTORY');
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
/*
|
85
|
+
* Create class-map class.
|
86
|
+
*
|
87
|
+
* Create a new class and extend it from the origin Zabbix classes, so that we
|
88
|
+
* can fetch the class map directly from the Zabbix classes without defining
|
89
|
+
* it here.
|
90
|
+
*
|
91
|
+
* There are some differences between the Zabbix versions:
|
92
|
+
*
|
93
|
+
* < 2.4: The class map is stored as a static property directly in the
|
94
|
+
* origin API class.
|
95
|
+
*
|
96
|
+
* >= 2.4: The class map is stored as an instance property in the
|
97
|
+
* origin CApiServiceFactory class.
|
98
|
+
*/
|
99
|
+
|
100
|
+
// load API
|
101
|
+
require PATH_ZABBIX_API_CLASS_FILE;
|
102
|
+
if ($is_2_4_or_later) {
|
103
|
+
require PATH_ZABBIX.'/include/classes/core/CRegistryFactory.php';
|
104
|
+
require PATH_ZABBIX.'/include/classes/api/CApiServiceFactory.php';
|
105
|
+
require PATH_ZABBIX.'/include/classes/api/CApiService.php';
|
106
|
+
|
107
|
+
|
108
|
+
class ZabbixApiClassMap extends CApiServiceFactory {
|
109
|
+
public function getClassMap() {
|
110
|
+
$classMap = $this->objects;
|
111
|
+
return $classMap;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
} else {
|
115
|
+
require PATH_ZABBIX.'/include/classes/api/CZBXAPI.php';
|
116
|
+
class ZabbixApiClassMap extends API
|
117
|
+
{
|
118
|
+
public function getClassMap()
|
119
|
+
{
|
120
|
+
return self::$classMap;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
|
126
|
+
/*
|
127
|
+
* Register SPL autoloader.
|
128
|
+
*
|
129
|
+
* The API class files always inherit from other classes. Most of the classes
|
130
|
+
* inherit from the CZBXAPI class, but there are a bunch of classes which
|
131
|
+
* are extended by other API classes.
|
132
|
+
*
|
133
|
+
* So that we don't have to "follow" the right order on loading API class files,
|
134
|
+
* we're register an API autoloader right here.
|
135
|
+
*
|
136
|
+
* Later the get_class_methods() function will automatically invoke this
|
137
|
+
* autoloader.
|
138
|
+
*/
|
139
|
+
|
140
|
+
function __autoload($className) {
|
141
|
+
require PATH_ZABBIX_API_CLASSES_DIRECTORY.'/'.$className.'.php';
|
142
|
+
}
|
143
|
+
|
144
|
+
// require needed files for get properteis.
|
145
|
+
require PATH_ZABBIX.'/include/classes/db/DB.php';
|
146
|
+
require PATH_ZABBIX.'/include/gettextwrapper.inc.php';
|
147
|
+
require PATH_ZABBIX.'/include/events.inc.php';
|
148
|
+
require PATH_ZABBIX.'/include/func.inc.php';
|
149
|
+
|
150
|
+
// initialze API array
|
151
|
+
$apiArray = array();
|
152
|
+
// Create new instance for API class map.
|
153
|
+
$apiClassMap = new ZabbixApiClassMap();
|
154
|
+
|
155
|
+
// loop through class map
|
156
|
+
foreach($apiClassMap->getClassMap() as $resource => $class) {
|
157
|
+
if ($class == 'CZBXAPI' || $class == 'CAPI' || $class == 'CApiService') { continue; }
|
158
|
+
|
159
|
+
// add resource to API array
|
160
|
+
$apiArray[$resource] = array();
|
161
|
+
|
162
|
+
$apiArray[$resource]['getOptions'] = array_keys(getProp($class, 'getOptions'));
|
163
|
+
$apiArray[$resource]['pk'] = getProp($class, 'pk');
|
164
|
+
|
165
|
+
|
166
|
+
// create new reflection class
|
167
|
+
$ref = new ReflectionClass($class);
|
168
|
+
// loop through defined methods
|
169
|
+
$apiArray[$resource]['methods'] = array();
|
170
|
+
foreach($ref->getMethods(ReflectionMethod::IS_PUBLIC & ~ReflectionMethod::IS_STATIC) as $method) {
|
171
|
+
// add action to API array
|
172
|
+
if( $method->name != 'pk'
|
173
|
+
&& $method->name != 'pkOption'
|
174
|
+
&& $method->name != 'tableName'
|
175
|
+
&& !$method->isConstructor()
|
176
|
+
&& !$method->isDestructor()
|
177
|
+
&& !$method->isAbstract()
|
178
|
+
) {
|
179
|
+
$apiArray[$resource]['methods'][] = strtolower($method->name);
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
$matches = array();
|
185
|
+
preg_match("/^(\d+\.\d+)\..+$/", ZABBIX_API_VERSION, $matches);
|
186
|
+
$version = $matches[1];
|
187
|
+
|
188
|
+
// Output APIs.
|
189
|
+
printf("%s\n", json_encode(array(
|
190
|
+
'methods' => $apiArray,
|
191
|
+
'version' => $version,
|
192
|
+
)));
|
193
|
+
?>
|
data/lib/sky_zabbix.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# @example
|
2
|
+
# z = SkyZabbix::Client.new('http://example.com/zabbix/api_jsonrpc.php')
|
3
|
+
# z.login('admin', 'zabbix')
|
4
|
+
# z.host.get
|
5
|
+
class SkyZabbix::Client
|
6
|
+
|
7
|
+
# @param [String] uri is URI of Zabbix Server API endpoint.
|
8
|
+
# @param [Logger] logger is a Logger.
|
9
|
+
def initialize(uri, logger: nil)
|
10
|
+
@uri = uri
|
11
|
+
@client = SkyZabbix::Jsonrpc.new(@uri, logger: logger)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Login to Zabbix Server.
|
15
|
+
# @param [String] user is Zabbix user name.
|
16
|
+
# @param [String] pass is Zabbix password.
|
17
|
+
def login(user, pass)
|
18
|
+
@client.token = self.user.login(user: user, password: pass)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Logout from Zabbix Server.
|
22
|
+
def logout
|
23
|
+
self.user.logout()
|
24
|
+
@client.token = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
# Send Batch Request.
|
28
|
+
# @param [Array<Hash>] requests are Hash created by build_* method.
|
29
|
+
def batch(*requests)
|
30
|
+
return @client.batch(requests)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require_relative 'client/target_base'
|
35
|
+
require_relative 'client/target_gen'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# @abstract
|
2
|
+
class SkyZabbix::Client::TargetBase
|
3
|
+
# @return [String]
|
4
|
+
def self._zbx_class
|
5
|
+
return @class
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
# @param [String] uri is URI of Zabbix Server.
|
10
|
+
# @param [SkyZabbix::Jsonrpc] client
|
11
|
+
def initialize(uri, client)
|
12
|
+
raise "Should use method of sub class!" unless _zbx_class
|
13
|
+
@uri = uri
|
14
|
+
@client = client
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param [Hash] filter
|
18
|
+
# @return [Array<String>] List of ID
|
19
|
+
def get_ids(filter)
|
20
|
+
params = {
|
21
|
+
filter: filter,
|
22
|
+
output: 'extend',
|
23
|
+
}
|
24
|
+
return _query('get', params).map{|x|x[pk]}
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param [Hash] filter
|
28
|
+
# @return [Array<String>] ID of founded first.
|
29
|
+
def get_id(filter)
|
30
|
+
return get_ids(filter).first
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
# @param [String] method is method name. ex) get, create, delete ...
|
35
|
+
# @param [Any] params is parameters.
|
36
|
+
def _query(method, params)
|
37
|
+
raise "Should use method of sub class!" unless _zbx_class
|
38
|
+
@client.post("#{_zbx_class}.#{method}", params)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [String] method is method name. ex) get, create, delete ...
|
42
|
+
# @param [Any] params is parameters.
|
43
|
+
def _build(method, params)
|
44
|
+
raise "Should use method of sub class!" unless _zbx_class
|
45
|
+
@client.build("#{_zbx_class}.#{method}", params)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String]
|
49
|
+
def _zbx_class
|
50
|
+
return self.class._zbx_class
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
methods = JSON.parse(File.read(File.expand_path('../../methods.json', __FILE__)), symbolize_names: true)[:methods]
|
4
|
+
|
5
|
+
methods.each do |name, v|
|
6
|
+
class_name = name[0].upcase + name[1..-1] # host => Host
|
7
|
+
|
8
|
+
# Generate Class
|
9
|
+
SkyZabbix::Client.const_set(class_name, Class.new(SkyZabbix::Client::TargetBase) do |klass|
|
10
|
+
@class = name
|
11
|
+
|
12
|
+
# TODO: getOptions
|
13
|
+
v[:methods].each do |method|
|
14
|
+
# Generate query method.
|
15
|
+
# Example: user.login()
|
16
|
+
define_method(method) do |params={}|
|
17
|
+
_query(method, params)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Generate build method. For batch request
|
21
|
+
# Example: user.build_login()
|
22
|
+
define_method("build_#{method}") do |params={}|
|
23
|
+
_build(method, params)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# primary key
|
28
|
+
define_method(:pk) do
|
29
|
+
return v[:pk]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Generate getter method.
|
33
|
+
# Example: client.user
|
34
|
+
SkyZabbix::Client.__send__(:define_method, name) do
|
35
|
+
klass.new(@url, @client)
|
36
|
+
end
|
37
|
+
end)
|
38
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
class SkyZabbix::Jsonrpc
|
6
|
+
VERSION = '2.0' # json-rpc version
|
7
|
+
|
8
|
+
def initialize(uri, logger: nil)
|
9
|
+
@uri = uri
|
10
|
+
@logger = logger
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :token
|
14
|
+
|
15
|
+
# @param [String] method is json-rpc method name.
|
16
|
+
# @param [Any?] params is json-rpc parameters.
|
17
|
+
# @param [Boolean] notification
|
18
|
+
def post(method, params, notification: false)
|
19
|
+
request(build(method, params, notification: notification))
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param [Hash{String => Any}] builded is result of 'build' method.
|
23
|
+
# @return [Any?] return result of response
|
24
|
+
def request(builded)
|
25
|
+
uri = URI.parse(@uri)
|
26
|
+
|
27
|
+
resp = do_req(uri, builded)
|
28
|
+
|
29
|
+
return nil unless builded[:id] # when notification
|
30
|
+
|
31
|
+
# Parse and error handling
|
32
|
+
body = JSON.parse(resp.body)
|
33
|
+
raise Error.create(body) if body['error']
|
34
|
+
|
35
|
+
return body['result']
|
36
|
+
end
|
37
|
+
|
38
|
+
# XXX: エラー処理はこれでいい?
|
39
|
+
# @example Return values.
|
40
|
+
# rpc.batch(
|
41
|
+
# rpc.build('a', 'A'),
|
42
|
+
# rpc.build('b', 'B', notification: true),
|
43
|
+
# rpc.build('c', 'C'),
|
44
|
+
# ) # => [{value: 'response of A'}, nil, {value: 'response of A'}]
|
45
|
+
# @example Raise error.
|
46
|
+
# rpc.batch(
|
47
|
+
# rpc.build('a', 'A'),
|
48
|
+
# rpc.build('b', 'B', notification: true),
|
49
|
+
# rpc.build('c', 'Invalid Params'),
|
50
|
+
# ) # => Error::BatchError.
|
51
|
+
# # Can get response of 'a' from ex.result
|
52
|
+
# @param [Array<Hash>] buildeds is Array of result of 'build' method.
|
53
|
+
# @return [Array<Any|Error|nil>]
|
54
|
+
def batch(buildeds)
|
55
|
+
uri = URI.parse(@uri)
|
56
|
+
resp = do_req(uri, buildeds)
|
57
|
+
body = JSON.parse(resp.body)
|
58
|
+
|
59
|
+
result = []
|
60
|
+
errors = []
|
61
|
+
buildeds.each do |b|
|
62
|
+
id = b[:id]
|
63
|
+
a = body.find{|x|x['id'] == id}
|
64
|
+
|
65
|
+
r =
|
66
|
+
if a.nil?
|
67
|
+
nil
|
68
|
+
elsif a['error']
|
69
|
+
errors.push(Error.new(a))
|
70
|
+
nil
|
71
|
+
else
|
72
|
+
a['result']
|
73
|
+
end
|
74
|
+
result.push(r)
|
75
|
+
end
|
76
|
+
|
77
|
+
unless errors.empty?
|
78
|
+
raise Error::BatchError.new(errors, result)
|
79
|
+
end
|
80
|
+
return result
|
81
|
+
end
|
82
|
+
|
83
|
+
# @param [String] method is json-rpc method name.
|
84
|
+
# @param [Any?] params is json-rpc parameters.
|
85
|
+
# @param [Boolean] notification
|
86
|
+
def build(method, params, notification: false)
|
87
|
+
res = {
|
88
|
+
jsonrpc: VERSION,
|
89
|
+
method: method,
|
90
|
+
params: params,
|
91
|
+
auth: @token,
|
92
|
+
}
|
93
|
+
res[:id] = id_gen unless notification
|
94
|
+
|
95
|
+
return res
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# @return [Integer] random ID.
|
102
|
+
def id_gen
|
103
|
+
return rand(10**12)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @param [URI::HTTP] uri is a URI of Zabbix Server.
|
107
|
+
# @param [Hash|Array] body is a request body.
|
108
|
+
def do_req(uri, body)
|
109
|
+
start_time = Time.now # for logging
|
110
|
+
|
111
|
+
# Create request
|
112
|
+
req = Net::HTTP::Post.new(uri.path)
|
113
|
+
req['Content-Type'] = 'application/json-rpc'
|
114
|
+
req.body = JSON.generate(body)
|
115
|
+
|
116
|
+
# Do HTTP Request
|
117
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
118
|
+
http.use_ssl = uri.scheme == 'https'
|
119
|
+
resp = http.request(req) # TODO: ここでのエラーハンドリング
|
120
|
+
unless resp.is_a? Net::HTTPSuccess
|
121
|
+
raise Error(resp.body)
|
122
|
+
end
|
123
|
+
return resp
|
124
|
+
|
125
|
+
ensure
|
126
|
+
logging_request(start_time, body, resp)
|
127
|
+
end
|
128
|
+
|
129
|
+
# TODO: log level
|
130
|
+
# @param [Time] start_time
|
131
|
+
# @param [Hash|Array] body is request body.
|
132
|
+
# @param [Net::HTTPResponse] resp
|
133
|
+
def logging_request(start_time, body, resp)
|
134
|
+
return unless @logger
|
135
|
+
|
136
|
+
sec = Time.now - start_time
|
137
|
+
msg_body =
|
138
|
+
if body.is_a? Array # when batch
|
139
|
+
y = body.map{|x| "#{x[:method]}(#{x[:params]})"}
|
140
|
+
"Batch Request [#{y.join(', ')}]"
|
141
|
+
else
|
142
|
+
"#{body[:method]}(#{body[:params]})"
|
143
|
+
end
|
144
|
+
|
145
|
+
@logger.info("[SkyZabbix #{resp.code} #{sec}] #{msg_body}")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
require_relative 'jsonrpc/errors'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class SkyZabbix::Jsonrpc::Error < StandardError
|
2
|
+
def initialize(body)
|
3
|
+
@error = body['error']
|
4
|
+
msg = "#{@error['message']} #{@error['data']}"
|
5
|
+
super(msg)
|
6
|
+
end
|
7
|
+
attr_reader :error
|
8
|
+
|
9
|
+
class ParseError < self; end # Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.
|
10
|
+
class InvalidRequest < self; end # The JSON sent is not a valid Request object.
|
11
|
+
class MethodNotFound < self; end # The method does not exist / is not available.
|
12
|
+
class InvalidParams < self; end # Invalid method parameter(s).
|
13
|
+
class InternalError < self; end # Internal JSON-RPC error.
|
14
|
+
class ServerError < self; end # Reserved for implementation-defined server-errors.
|
15
|
+
|
16
|
+
def self.create(body)
|
17
|
+
klass =
|
18
|
+
case body['code']
|
19
|
+
when -32700; ParseError
|
20
|
+
when -32600; InvalidRequest
|
21
|
+
when -32601; MethodNotFound
|
22
|
+
when -32602; InvalidParams
|
23
|
+
when -32603; InternalError
|
24
|
+
when -32099..-32000; ServerError
|
25
|
+
else; self
|
26
|
+
end
|
27
|
+
klass.new(body)
|
28
|
+
end
|
29
|
+
|
30
|
+
class BatchError < StandardError
|
31
|
+
# @param [Array<Error>] errors is list of error.
|
32
|
+
# @param [Array<Any>] result is list of response.
|
33
|
+
def initialize(errors, result)
|
34
|
+
@errors = errors
|
35
|
+
@result = result
|
36
|
+
end
|
37
|
+
attr_reader :errors, :result
|
38
|
+
|
39
|
+
# @return [String] error message
|
40
|
+
def message
|
41
|
+
return errors.map(&:message).join(', ')
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param [Array<Hash<String => Any>] body is response body.
|
45
|
+
# @return [Boolean]
|
46
|
+
def self.error?(body)
|
47
|
+
return body.any?{|x|x['error']}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/sky_zabbix.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sky_zabbix/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sky_zabbix"
|
8
|
+
spec.version = SkyZabbix::VERSION
|
9
|
+
spec.authors = ["Skyarch Networks Inc."]
|
10
|
+
spec.email = ['skyhopper@skyarch.net']
|
11
|
+
spec.licenses = ['MIT']
|
12
|
+
|
13
|
+
spec.summary = %q{An API Wrapper of Zabbix}
|
14
|
+
spec.description = %q{SkyZabbix is an API wrapper of Zabbix. All API methods are defined, Because method list is generated by Zabbix source code!}
|
15
|
+
spec.homepage = "https://github.com/skyarch-networks/sky_zabbix"
|
16
|
+
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
spec.required_ruby_version = '>= 2.0.0'
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "guard-rspec"
|
28
|
+
spec.add_development_dependency "pry"
|
29
|
+
spec.add_development_dependency "yard"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sky_zabbix
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.2.0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Skyarch Networks Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: SkyZabbix is an API wrapper of Zabbix. All API methods are defined, Because
|
98
|
+
method list is generated by Zabbix source code!
|
99
|
+
email:
|
100
|
+
- skyhopper@skyarch.net
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".editorconfig"
|
106
|
+
- ".gitignore"
|
107
|
+
- ".rspec"
|
108
|
+
- ".travis.yml"
|
109
|
+
- Gemfile
|
110
|
+
- Guardfile
|
111
|
+
- LICENSE
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/console
|
115
|
+
- bin/setup
|
116
|
+
- build.php
|
117
|
+
- lib/sky_zabbix.rb
|
118
|
+
- lib/sky_zabbix/client.rb
|
119
|
+
- lib/sky_zabbix/client/target_base.rb
|
120
|
+
- lib/sky_zabbix/client/target_gen.rb
|
121
|
+
- lib/sky_zabbix/jsonrpc.rb
|
122
|
+
- lib/sky_zabbix/jsonrpc/errors.rb
|
123
|
+
- lib/sky_zabbix/version.rb
|
124
|
+
- sky_zabbix.gemspec
|
125
|
+
homepage: https://github.com/skyarch-networks/sky_zabbix
|
126
|
+
licenses:
|
127
|
+
- MIT
|
128
|
+
metadata: {}
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options: []
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: 2.0.0
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 2.4.5
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
148
|
+
summary: An API Wrapper of Zabbix
|
149
|
+
test_files: []
|
150
|
+
has_rdoc:
|