sky_zabbix 2.2.0.1.0
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 +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:
|