├── .rspec ├── Jenkinsfile ├── lib └── zabbixapi │ ├── version.rb │ ├── classes │ ├── unusable.rb │ ├── events.rb │ ├── maintenance.rb │ ├── server.rb │ ├── hostgroups.rb │ ├── errors.rb │ ├── scripts.rb │ ├── actions.rb │ ├── configurations.rb │ ├── applications.rb │ ├── valuemaps.rb │ ├── drules.rb │ ├── httptests.rb │ ├── proxies.rb │ ├── users.rb │ ├── proxygroup.rb │ ├── hosts.rb │ ├── items.rb │ ├── usergroups.rb │ ├── screens.rb │ ├── problems.rb │ ├── graphs.rb │ ├── roles.rb │ ├── templates.rb │ ├── triggers.rb │ └── mediatypes.rb │ └── basic │ ├── basic_init.rb │ ├── basic_alias.rb │ └── basic_func.rb ├── spec ├── basic_func.rb ├── query.rb ├── server.rb ├── zabbixapi │ ├── classes │ │ ├── actions_spec.rb │ │ ├── maintenance_spec.rb │ │ ├── hostgroups_spec.rb │ │ ├── server_spec.rb │ │ ├── problems_spec.rb │ │ ├── unusable_spec.rb │ │ ├── mediatypes_spec.rb │ │ ├── scripts_spec.rb │ │ ├── configurations_spec.rb │ │ ├── errors_spec.rb │ │ ├── valuemap_spec.rb │ │ ├── proxies_spec.rb │ │ ├── users_spec.rb │ │ ├── roles_spec.rb │ │ ├── httptests_spec.rb │ │ ├── hosts_spec.rb │ │ ├── applications_spec.rb │ │ ├── items_spec.rb │ │ └── screens_spec.rb │ └── basic │ │ ├── basic_alias_spec.rb │ │ ├── basic_init_spec.rb │ │ └── basic_func_spec.rb ├── spec_helper.rb ├── valuemap.rb ├── mediatype.rb ├── drule.rb ├── problem.rb ├── hostgroup.rb ├── event.rb ├── screen.rb ├── application.rb ├── action.rb ├── maintenance.rb ├── usergroup.rb ├── trigger.rb ├── user.rb ├── configuration.rb ├── script.rb ├── graph.rb ├── item.rb ├── httptest.rb └── template.rb ├── json-1.x.Gemfile ├── Gemfile ├── examples ├── Hostgroups.md ├── Applications.md ├── Usermacros.md ├── Users.md ├── Valuemaps.md ├── Maintenance.md ├── Proxies.md ├── Screens.md ├── DiscoveryRule.md ├── Usergroups.md ├── MediaTypes.md ├── Templates.md ├── Triggers.md ├── Items.md ├── Graphs.md ├── Httptests.md ├── Problems.md ├── Actions.md ├── README.md ├── Hosts.md ├── Configurations.md └── Queries with Filters.md ├── Rakefile ├── json-1.x.Gemfile.lock ├── test ├── bin │ └── local_docker_stack └── docker_compose │ └── test_docker_stack.yml ├── .gitignore ├── zabbixapi.gemspec ├── LICENSE.md ├── .rubocop.yml ├── CHANGELOG.md ├── .github └── workflows │ └── main.yml └── README.md /.rspec: -------------------------------------------------------------------------------- 1 | --color --format documentation 2 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | library 'ets_shared' 4 | 5 | etsTestRubyUnit() 6 | -------------------------------------------------------------------------------- /lib/zabbixapi/version.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | VERSION = '6.0.0-alpha4'.freeze 3 | end 4 | -------------------------------------------------------------------------------- /spec/basic_func.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe ZabbixApi::Basic do 4 | end 5 | -------------------------------------------------------------------------------- /json-1.x.Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'json', '~> 2.0' 4 | gem 'rspec' 5 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/unusable.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Triggers < Basic 3 | def create_or_update(data) 4 | log "[DEBUG] Call create_or_update with parameters: #{data.inspect}" 5 | get_or_create(data) 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'jruby-openssl', platforms: :jruby 4 | gem 'rake', '~> 13.0' 5 | gem 'yard', '>= 0.9' 6 | 7 | group :development do 8 | gem 'irb' 9 | gem 'pry' 10 | end 11 | 12 | group :test do 13 | gem 'rspec', '~> 3.10' 14 | gem 'rubocop', '~> 1.7' 15 | end 16 | 17 | gemspec 18 | -------------------------------------------------------------------------------- /spec/query.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'query' do 4 | it 'should works' do 5 | expect( 6 | zbx.query( 7 | method: 'host.get', 8 | params: { 9 | filter: { 10 | host: 'asdf' 11 | }, 12 | selectInterfaces: 'refer' 13 | } 14 | ) 15 | ).to be_kind_of(Array) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/server.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'server' do 4 | describe 'version' do 5 | it 'should be string' do 6 | expect(zbx.server.version).to be_kind_of(String) 7 | end 8 | 9 | it 'should be 2.4.x, 3.2.x, 3.4.x, 4.0.x, 5.0.x, or 5.2.x' do 10 | expect(zbx.server.version).to match(/(2\.4|3\.[024]|4\.0|5\.[02])\.\d+/) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/events.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Events < Basic 3 | # The method name used for interacting with Events via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'event' 8 | end 9 | 10 | # The id field name used for identifying specific Event objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/maintenance.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Maintenance < Basic 3 | # The method name used for interacting with Maintenances via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'maintenance' 8 | end 9 | 10 | # The id field name used for identifying specific Maintenance objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/actions_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Actions' do 4 | let(:actions_mock) { ZabbixApi::Actions.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { actions_mock.method_name } 9 | 10 | it { is_expected.to eq 'action' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { actions_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /examples/Hostgroups.md: -------------------------------------------------------------------------------- 1 | # Hostgroups 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Hostgroups: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/hostgroup](https://www.zabbix.com/documentation/4.0/manual/api/reference/hostgroup) 7 | 8 | ## Create Hostgroup 9 | ```ruby 10 | zbx.hostgroups.create(:name => "hostgroup") 11 | ``` 12 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/server.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Server 3 | # @return [String] 4 | attr_reader :version 5 | 6 | # Initializes a new Server object with ZabbixApi Client and fetches Zabbix Server API version 7 | # 8 | # @param client [ZabbixApi::Client] 9 | # @return [ZabbixApi::Client] 10 | # @return [String] Zabbix API version number 11 | def initialize(client) 12 | @client = client 13 | @version = @client.api_version() 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/maintenance_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Maintenance' do 4 | let(:maintenance_mock) { ZabbixApi::Maintenance.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { maintenance_mock.method_name } 9 | 10 | it { is_expected.to eq 'maintenance' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { maintenance_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /examples/Applications.md: -------------------------------------------------------------------------------- 1 | # Applications 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Applications: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/application](https://www.zabbix.com/documentation/4.0/manual/api/reference/application) 7 | 8 | ## Create Application 9 | ```ruby 10 | zbx.applications.create( 11 | :name => application, 12 | :hostid => zbx.templates.get_id(:host => "template") 13 | ) 14 | ``` 15 | -------------------------------------------------------------------------------- /examples/Usermacros.md: -------------------------------------------------------------------------------- 1 | # Usermacros 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Usermacros: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/usermacro](https://www.zabbix.com/documentation/4.0/manual/api/reference/usermacro) 7 | 8 | ### User and global macros 9 | ```ruby 10 | zbx.usermacros.create( 11 | :hostid => zbx.hosts.get_id( :host => "Zabbix server" ), 12 | :macro => "{$ZZZZ}", 13 | :value => 1.1.1.1 14 | ) 15 | ``` 16 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'zabbixapi' 2 | 3 | def zbx 4 | # settings 5 | @api_url = ENV['ZABBIX_HOST_URL'] || 'http://localhost:8080/api_jsonrpc.php' 6 | @api_login = ENV['ZABBIX_USERNAME'] || 'Admin' 7 | @api_password = ENV['ZABBIX_PASSWORD'] || 'zabbix' 8 | 9 | @zbx ||= ZabbixApi.connect( 10 | url: @api_url, 11 | user: @api_login, 12 | password: @api_password, 13 | debug: ENV['ZABBIX_DEBUG'] ? true : false 14 | ) 15 | end 16 | 17 | def gen_id 18 | rand(1_000_000_000) 19 | end 20 | 21 | def gen_name(prefix) 22 | suffix = rand(1_000_000_000) 23 | "#{prefix}_#{suffix}" 24 | end 25 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/hostgroups_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::HostGroups' do 4 | let(:actions_mock) { ZabbixApi::HostGroups.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { actions_mock.method_name } 9 | 10 | it { is_expected.to eq 'hostgroup' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { actions_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.key' do 20 | subject { actions_mock.key } 21 | 22 | it { is_expected.to eq 'groupid' } 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/hostgroups.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class HostGroups < Basic 3 | # The method name used for interacting with HostGroups via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'hostgroup' 8 | end 9 | 10 | # The id field name used for identifying specific HostGroup objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # The key field name used for HostGroup objects via Zabbix API 18 | # 19 | # @return [String] 20 | def key 21 | 'groupid' 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | require 'rspec/core/rake_task' 5 | RSpec::Core::RakeTask.new(:spec) 6 | 7 | task test: :spec 8 | 9 | require 'rubocop/rake_task' 10 | RuboCop::RakeTask.new 11 | 12 | require 'yard' 13 | YARD::Rake::YardocTask.new 14 | 15 | require 'yardstick/rake/measurement' 16 | Yardstick::Rake::Measurement.new do |measurement| 17 | measurement.output = 'measurement/report.txt' 18 | end 19 | 20 | require 'yardstick/rake/verify' 21 | Yardstick::Rake::Verify.new do |verify| 22 | verify.threshold = 67.1 23 | end 24 | 25 | task default: [:spec, :rubocop, :verify_measurements] 26 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/errors.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class BaseError < RuntimeError 3 | attr_accessor :response, :error, :error_message 4 | 5 | def initialize(message, response = nil) 6 | super(message) 7 | @response = response 8 | 9 | set_error! if @response 10 | end 11 | 12 | private 13 | 14 | def set_error! 15 | @error = @response['error'] 16 | @error_message = "#{@error['message']}: #{@error['data']}" 17 | rescue StandardError 18 | @error = nil 19 | @error_message = nil 20 | end 21 | end 22 | 23 | class ApiError < BaseError 24 | end 25 | 26 | class HttpError < BaseError 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /json-1.x.Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | diff-lcs (1.2.5) 5 | json (1.8.5) 6 | rspec (3.5.0) 7 | rspec-core (~> 3.5.0) 8 | rspec-expectations (~> 3.5.0) 9 | rspec-mocks (~> 3.5.0) 10 | rspec-core (3.5.4) 11 | rspec-support (~> 3.5.0) 12 | rspec-expectations (3.5.0) 13 | diff-lcs (>= 1.2.0, < 2.0) 14 | rspec-support (~> 3.5.0) 15 | rspec-mocks (3.5.0) 16 | diff-lcs (>= 1.2.0, < 2.0) 17 | rspec-support (~> 3.5.0) 18 | rspec-support (3.5.0) 19 | 20 | PLATFORMS 21 | ruby 22 | 23 | DEPENDENCIES 24 | json (~> 1.8) 25 | rspec 26 | 27 | BUNDLED WITH 28 | 1.12.5 29 | -------------------------------------------------------------------------------- /examples/Users.md: -------------------------------------------------------------------------------- 1 | # Users 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Users: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/user](https://www.zabbix.com/documentation/4.0/manual/api/reference/user) 7 | 8 | ## Create User 9 | ```ruby 10 | zbx.users.create( 11 | :alias => "Test user", 12 | :name => "username", 13 | :surname => "usersername", 14 | :passwd => "password" 15 | ) 16 | ``` 17 | 18 | ## Update User 19 | ```ruby 20 | zbx.users.update(:userid => zbx.users.get_id(:alias => "user"), :name => "user2") 21 | ``` 22 | -------------------------------------------------------------------------------- /examples/Valuemaps.md: -------------------------------------------------------------------------------- 1 | # Valuemaps 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Users: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/valuemap](https://www.zabbix.com/documentation/4.0/manual/api/reference/valuemap) 7 | 8 | ## Create Valuemap 9 | ```ruby 10 | zbx.valuemaps.create_or_update( 11 | :name => "Test valuemap", 12 | "mappings" => [ 13 | "newvalue" => "newvalue", 14 | "value" => "value" 15 | ] 16 | ) 17 | ``` 18 | 19 | ## Delete Valuemap 20 | ```ruby 21 | zbx_client.valuemaps.delete( 22 | zbx.valuemaps.get_id(:name => "Test valuemap") 23 | ) 24 | ``` -------------------------------------------------------------------------------- /test/bin/local_docker_stack: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | echo '## Use the following commands to bring up a fully provisioned' 4 | echo '## Zabbix Server & Zabbix Frontend, backed by PostgreSQL' 5 | echo 6 | echo 'docker-compose -p zabbixapi -f test/docker_compose/test_docker_stack.yml up -d' 7 | echo 'docker-compose -p zabbixapi -f test/docker_compose/test_docker_stack.yml down' 8 | echo 'docker network inspect zabbixapi_zabbix' 9 | echo 'docker container ls | grep zabbixapi_' 10 | echo 'docker logs ${container_name}' 11 | echo 12 | echo 'export ZABBIX_HOST_URL="http://localhost:8080/api_jsonrpc.php"' 13 | echo 'bundle exec rspec spec/*' 14 | echo 15 | echo 'open browser: http://localhost:8080' 16 | echo ' Username: Admin' 17 | echo ' Password: zabbix' 18 | -------------------------------------------------------------------------------- /examples/Maintenance.md: -------------------------------------------------------------------------------- 1 | # Maintenance 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Maintenance: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/maintenance](https://www.zabbix.com/documentation/4.0/manual/api/reference/maintenance) 7 | 8 | ## Create Maintenance 9 | ```ruby 10 | zbx.maintenance.create( 11 | :name => @maintenance, 12 | :groupids => [ zbx.hostgroups.get_id(:name => "hostgroup") ], 13 | :active_since => 1358844540, 14 | :active_till => 1390466940, 15 | :timeperiods => [ :timeperiod_type => 3, :every => 1, :dayofweek => 64, :start_time => 64800, :period => 3600 ] 16 | ) 17 | ``` 18 | -------------------------------------------------------------------------------- /examples/Proxies.md: -------------------------------------------------------------------------------- 1 | # Proxies 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Proxies: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/proxy](https://www.zabbix.com/documentation/4.0/manual/api/reference/proxy) 7 | 8 | ## Create Proxy 9 | 10 | ### Active Proxy 11 | ```ruby 12 | zbx.proxies.create( 13 | :host => "Proxy 1", 14 | :status => 5 15 | ) 16 | ``` 17 | 18 | ### Passive Proxy 19 | ```ruby 20 | zbx.proxies.create( 21 | :host => "Passive proxy", 22 | :status => 6, 23 | :interfaces => [ 24 | :ip => "127.0.0.1", 25 | :dns => "", 26 | :useip => 1, 27 | :port => 10051 28 | ] 29 | ) 30 | ``` 31 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/server_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Server' do 4 | let(:server_mock) { ZabbixApi::Server.new(client) } 5 | let(:client) { double('mock_client', api_version: 'testresult') } 6 | let(:result) { 'testresult' } 7 | 8 | before do 9 | allow(client).to receive(:api_request).with( 10 | method: 'apiinfo.version', 11 | params: {} 12 | ).and_return(result) 13 | end 14 | 15 | describe '.initialize' do 16 | subject { server_mock } 17 | 18 | it 'sets client class variable' do 19 | expect(subject.instance_variable_get(:@client)).to eq client 20 | end 21 | 22 | it 'sets api_version class variable' do 23 | expect(subject.instance_variable_get(:@version)).to eq result 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /examples/Screens.md: -------------------------------------------------------------------------------- 1 | # Screens 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Screens: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/screen](https://www.zabbix.com/documentation/4.0/manual/api/reference/screen) 7 | 8 | ## Create Screen for Host 9 | ```ruby 10 | zbx.screens.get_or_create_for_host( 11 | :screen_name => "screen_name", 12 | :graphids => zbx.graphs.get_ids_by_host(:host => "hostname") 13 | ) 14 | ``` 15 | 16 | ## Delete Screen 17 | ```ruby 18 | zbx.screens.delete( 19 | :screen_id => 1, # or screen_id => [1, 2] 20 | ) 21 | ``` 22 | 23 | or 24 | 25 | ```ruby 26 | zbx.screens.delete( 27 | :screen_name => "foo screen", # or screen_name => ["foo screen", "bar screen"] 28 | ) 29 | ```` 30 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/problems_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Problems' do 4 | let(:problems_mock) { ZabbixApi::Problems.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { problems_mock.method_name } 9 | 10 | it { is_expected.to eq 'problem' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { problems_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | # Problem object does not have a unique identifier 20 | describe '.key' do 21 | subject { problems_mock.key } 22 | 23 | it { is_expected.to eq 'problemid' } 24 | end 25 | 26 | # Problem object does not have a unique identifier 27 | describe '.keys' do 28 | subject { problems_mock.keys } 29 | 30 | it { is_expected.to eq 'problemids' } 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/unusable_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Triggers' do 4 | let(:unusable_mock) { ZabbixApi::Triggers.new(client) } 5 | 6 | let(:client) { double } 7 | 8 | describe '.create_or_update' do 9 | subject { unusable_mock.create_or_update(data) } 10 | 11 | let(:data) { { description: 'testdesc', hostid: 'hostid' } } 12 | 13 | before do 14 | allow(unusable_mock).to receive(:log) 15 | allow(unusable_mock).to receive(:get_or_create) 16 | end 17 | 18 | it 'logs debug message' do 19 | expect(unusable_mock).to receive(:log).with("[DEBUG] Call create_or_update with parameters: #{data.inspect}") 20 | end 21 | 22 | it 'calls get_or_create' do 23 | expect(unusable_mock).to receive(:get_or_create).with(data) 24 | end 25 | 26 | after { subject } 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Based on the templates from https://github.com/github/gitignore 2 | 3 | ## Ruby 4 | *.gem 5 | *.rbc 6 | /.config 7 | /coverage/ 8 | /InstalledFiles 9 | /measurement/ 10 | /pkg/ 11 | /spec/reports/ 12 | /spec/examples.txt 13 | /test/tmp/ 14 | /test/version_tmp/ 15 | /tmp/ 16 | Gemfile.lock 17 | 18 | ## Specific to RubyMotion: 19 | .dat* 20 | .repl_history 21 | build/ 22 | 23 | ## Documentation cache and generated files: 24 | /.yardoc/ 25 | /_yardoc/ 26 | /doc/ 27 | /rdoc/ 28 | 29 | ## Environment normalization: 30 | /.bundle/ 31 | /vendor/bundle 32 | /lib/bundler/man/ 33 | 34 | # for a library or gem, you might want to ignore these files since the code is 35 | # intended to run in multiple environments; otherwise, check them in: 36 | #Gemfile.lock 37 | .ruby-version 38 | .ruby-gemset 39 | 40 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 41 | .rvmrc 42 | -------------------------------------------------------------------------------- /examples/DiscoveryRule.md: -------------------------------------------------------------------------------- 1 | # Discovery Rule 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Actions: 6 | [https://www.zabbix.com/documentation/3.2/manual/api/reference/drule](https://www.zabbix.com/documentation/3.2/manual/api/reference/drule) 7 | 8 | ## Create Discovery Rule 9 | ```ruby 10 | zbx.drules.create( 11 | :name => 'zabbix agent discovery', 12 | :delay => '1800', # discover new machines every 30min 13 | :status => '0', # action is enabled 14 | :iprange => '192.168.0.0/24', # iprange to discover zabbix agents in 15 | :dchecks => [{ 16 | :type => '9', # zabbix agent 17 | :uniq => '0', # (default) do not use this check as a uniqueness criteria 18 | :key_ => 'system.hostname', 19 | :ports => '10050', 20 | }], 21 | ) 22 | ``` 23 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/scripts.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Scripts < Basic 3 | def method_name 4 | 'script' 5 | end 6 | 7 | # The id field name used for identifying specific Screen objects via Zabbix API 8 | # 9 | # @return [String] 10 | def identify 11 | 'name' 12 | end 13 | 14 | # Submits a request to the zabbix api 15 | # data - A Hash containing the scriptid and hostid 16 | # 17 | # Example: 18 | # execute({ scriptid: '12', hostid: '32 }) 19 | # 20 | # Returns nothing 21 | def execute(data) 22 | @client.api_request( 23 | method: 'script.execute', 24 | params: { 25 | scriptid: data[:scriptid], 26 | hostid: data[:hostid] 27 | } 28 | ) 29 | end 30 | 31 | def getscriptsbyhost(data) 32 | @client.api_request(method: 'script.getscriptsbyhosts', params: data) 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/mediatypes_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Mediatypes' do 4 | let(:mediatypes_mock) { ZabbixApi::Mediatypes.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { mediatypes_mock.method_name } 9 | 10 | it { is_expected.to eq 'mediatype' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { mediatypes_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.default_options' do 20 | subject { mediatypes_mock.default_options } 21 | 22 | let(:result) do 23 | { 24 | name: '', 25 | description: '', 26 | type: 0, 27 | smtp_server: '', 28 | smtp_helo: '', 29 | smtp_email: '', 30 | exec_path: '', 31 | gsm_modem: '', 32 | username: '', 33 | passwd: '' 34 | } 35 | end 36 | 37 | it { is_expected.to eq result } 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /examples/Usergroups.md: -------------------------------------------------------------------------------- 1 | # Usergroups 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Usergroups: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/usergroup](https://www.zabbix.com/documentation/4.0/manual/api/reference/usergroup) 7 | 8 | ## Create UserGroup, add User and set permission 9 | ```ruby 10 | zbx.usergroups.get_or_create(:name => "Some user group") 11 | 12 | zbx.usergroups.add_user( 13 | :usrgrpids => [zbx.usergroups.get_id(:name => "Some user group")], 14 | :userids => [zbx.users.get_id(:alias => "user")] 15 | ) 16 | 17 | # set write and read permissions for UserGroup on all Hostgroups 18 | zbx.usergroups.permissions( 19 | :usrgrpid => zbx.usergroups.get_or_create(:name => "Some user group"), 20 | :hostgroupids => zbx.hostgroups.all.values, # kind_of Array 21 | :permission => 3 # 2- read (by default) and 3 - write and read 22 | ) 23 | ``` 24 | -------------------------------------------------------------------------------- /examples/MediaTypes.md: -------------------------------------------------------------------------------- 1 | # MediaTypes 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for MediaTypes: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/mediatype](https://www.zabbix.com/documentation/4.0/manual/api/reference/mediatype) 7 | 8 | ## Create MediaType and add it to user ### 9 | ```ruby 10 | zbx.mediatypes.create_or_update( 11 | :description => "mediatype", 12 | :type => 0, # 0 - Email, 1 - External script, 2 - SMS, 3 - Jabber, 100 - EzTexting, 13 | :smtp_server => "127.0.0.1", 14 | :smtp_email => "zabbix@test.com" 15 | ) 16 | 17 | zbx.users.update( 18 | :userid => zbx.users.get_id(:alias => "user"), 19 | :user_medias => [ 20 | { 21 | :mediatypeid => zbx.mediatypes.get_id(:description => "mediatype"), 22 | :sendto => "test@test", 23 | :active => 0, 24 | :period => "1-7,00:00-24:00", # 1-7 days and 00:00-24:00 hours 25 | :severity => "56" 26 | } 27 | ] 28 | ) 29 | ``` 30 | -------------------------------------------------------------------------------- /zabbixapi.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | lib = File.expand_path('../lib', __FILE__) 4 | 5 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 6 | 7 | require 'zabbixapi/version' 8 | 9 | Gem::Specification.new do |spec| 10 | spec.add_dependency 'http', '~> 5.0' 11 | spec.add_dependency 'json', '~> 2.6' 12 | spec.add_development_dependency 'bundler' 13 | 14 | spec.name = 'zabbixapi' 15 | spec.version = ZabbixApi::VERSION 16 | spec.authors = ['Vasiliev D.V.', 'Ivan Evtuhovich'] 17 | spec.email = ['vadv.mkn@gmail.com', 'evtuhovich@gmail.com'] 18 | 19 | spec.summary = 'Simple and lightweight ruby module for working with the Zabbix API' 20 | spec.description = 'Allows you to work with zabbix api from ruby.' 21 | spec.homepage = 'https://github.com/express42/zabbixapi' 22 | spec.licenses = 'MIT' 23 | 24 | spec.rubyforge_project = 'zabbixapi' 25 | 26 | spec.files = ['CHANGELOG.md', 'LICENSE.md', 'README.md', 'zabbixapi.gemspec'] + Dir['lib/**/*.rb'] 27 | spec.require_paths = 'lib' 28 | spec.required_ruby_version = '>= 2.0.0' 29 | end 30 | -------------------------------------------------------------------------------- /examples/Templates.md: -------------------------------------------------------------------------------- 1 | # Templates 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Templates: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/template](https://www.zabbix.com/documentation/4.0/manual/api/reference/template) 7 | 8 | ## Create Template 9 | ```ruby 10 | zbx.templates.create( 11 | :host => "template", 12 | :groups => [:groupid => zbx.hostgroups.get_id(:name => "hostgroup")] 13 | ) 14 | ``` 15 | 16 | ## Mass (Un)Link Host with Templates 17 | ```ruby 18 | zbx.templates.mass_add( 19 | :hosts_id => [zbx.hosts.get_id(:host => "hostname")], 20 | :templates_id => [111, 214] 21 | ) 22 | 23 | zbx.templates.mass_remove( 24 | :hosts_id => [zbx.hosts.get_id(:host => "hostname")], 25 | :templates_id => [111, 214] 26 | ) 27 | ``` 28 | 29 | ## Get all Templates linked with Host 30 | ```ruby 31 | zbx.templates.get_ids_by_host( :hostids => [zbx.hosts.get_id(:host => "hostname")] ) 32 | #returned array: 33 | #[ 34 | # "10", 35 | # "1021" 36 | #] 37 | ``` 38 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2018 Express 42 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /examples/Triggers.md: -------------------------------------------------------------------------------- 1 | # Triggers 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Triggers: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/trigger](https://www.zabbix.com/documentation/4.0/manual/api/reference/trigger) 7 | 8 | ## Create Trigger 9 | ```ruby 10 | zbx.triggers.create( 11 | :description => "trigger", 12 | :expression => "{template:proc.num[aaa].last(0)}<1", 13 | :comments => "Bla-bla is faulty (disaster)", 14 | :priority => 5, 15 | :status => 0, 16 | :hostid => zbx.templates.get_id(:host => "template"), 17 | :type => 0, 18 | :tags => [ 19 | { 20 | :tag => "process", 21 | :value => "aaa" 22 | }, 23 | { 24 | :tag => "error", 25 | :value => "" 26 | } 27 | ] 28 | ) 29 | ``` 30 | 31 | ## Get Trigger with certain filter 32 | ```ruby 33 | triggers = zbx.query( 34 | :method => "trigger.get", 35 | :params => { 36 | :filter => { 37 | :url => "" 38 | }, 39 | :templated => true, 40 | :output => "extend" 41 | } 42 | ) 43 | ``` 44 | -------------------------------------------------------------------------------- /spec/zabbixapi/basic/basic_alias_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Basic' do 4 | let(:basic_mock) { ZabbixApi::Basic.new(client) } 5 | let(:client) { double('mock_client', options: {}, api_request: {} ) } 6 | let(:data) { {} } 7 | 8 | after { subject } 9 | 10 | describe '.get' do 11 | subject { basic_mock.get(data) } 12 | 13 | before do 14 | allow(basic_mock).to receive(:get_full_data).with(data) 15 | allow(basic_mock).to receive(:method_name) 16 | end 17 | 18 | it 'calls get_full_data' do 19 | expect(basic_mock).to receive(:get_full_data).with(data) 20 | end 21 | end 22 | 23 | describe '.add' do 24 | subject { basic_mock.add(data) } 25 | 26 | before { allow(basic_mock).to receive(:create).with(data) } 27 | 28 | it 'calls create' do 29 | expect(basic_mock).to receive(:create).with(data) 30 | end 31 | end 32 | 33 | describe '.destroy' do 34 | subject { basic_mock.destroy(data) } 35 | 36 | before { allow(basic_mock).to receive(:delete).with(data) } 37 | 38 | it 'calls delete' do 39 | expect(basic_mock).to receive(:delete).with(data) 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | DisplayCopNames: true 3 | 4 | Metrics/AbcSize: 5 | Max: 58 # TODO: Lower to 15 6 | 7 | Metrics/BlockLength: 8 | Max: 35 9 | Exclude: 10 | - spec/**/*.rb 11 | 12 | Metrics/BlockNesting: 13 | Max: 2 14 | 15 | Metrics/CyclomaticComplexity: 16 | Max: 10 17 | 18 | Metrics/LineLength: 19 | AllowURI: true 20 | Enabled: false 21 | 22 | Metrics/MethodLength: 23 | CountComments: false 24 | Max: 35 # TODO: Lower to 15 25 | 26 | Metrics/ModuleLength: 27 | Max: 150 # TODO: Lower to 100 28 | 29 | Metrics/ParameterLists: 30 | Max: 4 31 | CountKeywordArgs: true 32 | 33 | Metrics/PerceivedComplexity: 34 | Max: 10 35 | 36 | Layout/AccessModifierIndentation: 37 | EnforcedStyle: outdent 38 | 39 | Style/Documentation: 40 | Enabled: false 41 | 42 | Style/DoubleNegation: 43 | Enabled: false 44 | 45 | Style/FrozenStringLiteralComment: 46 | Enabled: false 47 | 48 | Style/HashSyntax: 49 | Enabled: false 50 | 51 | Style/RaiseArgs: 52 | EnforcedStyle: compact 53 | 54 | Style/SymbolArray: 55 | EnforcedStyle: brackets 56 | 57 | Style/TrailingCommaInArrayLiteral: 58 | EnforcedStyleForMultiline: 'comma' 59 | 60 | Style/TrailingCommaInHashLiteral: 61 | EnforcedStyleForMultiline: 'comma' 62 | -------------------------------------------------------------------------------- /examples/Items.md: -------------------------------------------------------------------------------- 1 | # Items 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Items: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/item](https://www.zabbix.com/documentation/4.0/manual/api/reference/item) 7 | 8 | ## Create Item 9 | ```ruby 10 | zbx.items.create( 11 | :name => "item", 12 | :description => "item", 13 | :key_ => "proc.num[aaa]", 14 | :type => 6, 15 | :value_type => 6, 16 | :hostid => zbx.templates.get_id(:host => "template"), 17 | :applications => [zbx.applications.get_id(:name => "application")] 18 | ) 19 | 20 | # or use (lib merge json): 21 | zbx.items.create_or_update( 22 | :name => "item", 23 | :description => "item", 24 | :key_ => "proc.num[aaa]", 25 | :type => 6, 26 | :value_type => 4, 27 | :hostid => zbx.templates.get_id(:host => "template"), 28 | :applications => [zbx.applications.get_id(:name => "application")] 29 | ) 30 | ``` 31 | 32 | ## Update Item 33 | ```ruby 34 | zbx.items.update( 35 | :itemid => zbx.items.get_id(:name => "item"), 36 | :status => 0 37 | ) 38 | 39 | #You can check Item: 40 | puts zbx.items.get_full_data(:name => "item") 41 | ``` 42 | -------------------------------------------------------------------------------- /test/docker_compose/test_docker_stack.yml: -------------------------------------------------------------------------------- 1 | # Postgres, Zabbix Server and Zabbix Frontend stack deployment for testing spec tests locally 2 | # https://www.zabbix.com/container_images 3 | 4 | version: '3.8' 5 | 6 | services: 7 | db: 8 | image: postgres:13-alpine 9 | restart: always 10 | environment: 11 | POSTGRES_PASSWORD: password 12 | POSTGRES_USER: zabbix 13 | POSTGRES_DB: zabbix 14 | networks: 15 | zabbix: 16 | ports: 17 | - "5432:5432" 18 | server: 19 | image: zabbix/zabbix-server-pgsql:alpine-5.2-latest 20 | depends_on: 21 | - db 22 | environment: 23 | DB_SERVER_HOST: db 24 | POSTGRES_USER: zabbix 25 | POSTGRES_PASSWORD: password 26 | networks: 27 | zabbix: 28 | ports: 29 | - 10051:10051 30 | frontend: 31 | image: zabbix/zabbix-web-apache-pgsql:alpine-5.2-latest 32 | depends_on: 33 | - db 34 | - server 35 | environment: 36 | DB_SERVER_HOST: db 37 | POSTGRES_USER: zabbix 38 | POSTGRES_PASSWORD: password 39 | ZBX_SERVER_HOST: server 40 | PHP_TZ: "US/Eastern" 41 | networks: 42 | zabbix: 43 | ports: 44 | - "8080:8080" 45 | networks: 46 | zabbix: 47 | ipam: 48 | driver: default 49 | config: 50 | - subnet: "172.16.238.0/24" 51 | -------------------------------------------------------------------------------- /spec/valuemap.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'valuemap' do 4 | before :all do 5 | @valuemap = gen_name 'valuemap' 6 | end 7 | 8 | context 'when not exists' do 9 | describe 'create' do 10 | it 'should return an integer id' do 11 | valuemapid = zbx.valuemaps.create_or_update( 12 | name: @valuemap, 13 | mappings: [ 14 | 'newvalue' => 'test', 15 | 'value' => 'test' 16 | ] 17 | ) 18 | expect(valuemapid).to be_kind_of(Integer) 19 | end 20 | end 21 | end 22 | 23 | context 'when exists' do 24 | before do 25 | @valuemapid = zbx.valuemaps.create_or_update( 26 | name: @valuemap, 27 | mappings: [ 28 | 'newvalue' => 'test', 29 | 'value' => 'test' 30 | ] 31 | ) 32 | end 33 | 34 | describe 'create_or_update' do 35 | it 'should return id' do 36 | expect( 37 | zbx.valuemaps.create_or_update( 38 | name: @valuemap, 39 | mappings: [ 40 | 'newvalue' => 'test', 41 | 'value' => 'test' 42 | ] 43 | ) 44 | ).to eq @valuemapid 45 | end 46 | 47 | it 'should return id' do 48 | expect(@valuemapid).to eq @valuemapid 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /spec/mediatype.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'mediatype' do 4 | before do 5 | @mediatype = gen_name 'mediatype' 6 | end 7 | 8 | context 'when not exists' do 9 | describe 'create' do 10 | it 'should return integer id' do 11 | mediatypeid = zbx.mediatypes.create( 12 | name: @mediatype, 13 | type: 0, 14 | smtp_server: '127.0.0.1', 15 | smtp_email: 'zabbix@test.com', 16 | smtp_helo: 'test.com' 17 | ) 18 | expect(mediatypeid).to be_kind_of(Integer) 19 | end 20 | end 21 | end 22 | 23 | context 'when exists' do 24 | before do 25 | @mediatypeid = zbx.mediatypes.create( 26 | name: @mediatype, 27 | type: 0, 28 | smtp_server: '127.0.0.1', 29 | smtp_email: 'zabbix@test.com', 30 | smtp_helo: 'test.com' 31 | ) 32 | end 33 | 34 | describe 'create_or_update' do 35 | it 'should return id' do 36 | expect( 37 | zbx.mediatypes.create_or_update( 38 | name: @mediatype, 39 | smtp_email: 'zabbix2@test.com', 40 | smtp_helo: 'test.com' 41 | ) 42 | ).to eq @mediatypeid 43 | end 44 | 45 | it 'should return id' do 46 | expect(@mediatypeid).to eq @mediatypeid 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/zabbixapi/basic/basic_init.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Basic 3 | # Initializes a new Basic object with ZabbixApi Client 4 | # 5 | # @param client [ZabbixApi::Client] 6 | # @return [ZabbixApi::Client] 7 | def initialize(client) 8 | @client = client 9 | end 10 | 11 | # Placeholder for inherited objects to provide object-specific method name 12 | # 13 | # @raise [ApiError] Basic object does not directly support method_name 14 | def method_name 15 | raise ApiError.new("Can't call method_name here") 16 | end 17 | 18 | # Placeholder for inherited objects to provide default options 19 | # 20 | # @return [Hash] 21 | def default_options 22 | {} 23 | end 24 | 25 | # Returns the object's plural id field name (identify) based on key 26 | # 27 | # @return [String] 28 | def keys 29 | key + 's' 30 | end 31 | 32 | # Returns the object's id field name (identify) based on method_name + id 33 | # 34 | # @return [String] 35 | def key 36 | method_name + 'id' 37 | end 38 | 39 | # Placeholder for inherited objects to provide object-specific id field name 40 | # 41 | # @raise [ApiError] Basic object does not directly support identify 42 | def identify 43 | raise ApiError.new("Can't call identify here") 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/actions.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Actions < Basic 3 | # The method name used for interacting with Actions via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'action' 8 | end 9 | 10 | # The id field name used for identifying specific Action objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # Get full/extended Action object data from API 18 | # 19 | # @param data [Hash] Should include object's id field name (identify) and id value 20 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 21 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 22 | # @return [Hash] 23 | def get_full_data(data) 24 | log "[DEBUG] Call get_full_data with parameters: #{data.inspect}" 25 | 26 | @client.api_request( 27 | method: "#{method_name}.get", 28 | params: { 29 | filter: { 30 | identify.to_sym => data[identify.to_sym] 31 | }, 32 | output: 'extend', 33 | selectOperations: "extend", 34 | selectRecoveryOperations: "extend", 35 | selectAcknowledgeOperations: "extend", 36 | selectFilter: "extend", 37 | } 38 | ) 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/scripts_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Scripts' do 4 | let(:scripts_mock) { ZabbixApi::Scripts.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { scripts_mock.method_name } 9 | 10 | it { is_expected.to eq 'script' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { scripts_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.execute' do 20 | subject { scripts_mock.execute(data) } 21 | 22 | let(:data) { { scriptid: 222, hostid: 333 } } 23 | let(:result) { 'testresult' } 24 | 25 | before do 26 | allow(client).to receive(:api_request).with( 27 | method: 'script.execute', 28 | params: { 29 | scriptid: 222, 30 | hostid: 333 31 | } 32 | ).and_return(result) 33 | end 34 | 35 | it { is_expected.to eq result } 36 | end 37 | 38 | describe '.getscriptsbyhost' do 39 | subject { scripts_mock.getscriptsbyhost(data) } 40 | 41 | let(:data) { { scriptid: 222, hostid: 333 } } 42 | let(:result) { 'testresult' } 43 | 44 | before do 45 | allow(client).to receive(:api_request).with( 46 | method: 'script.getscriptsbyhosts', 47 | params: data 48 | ).and_return(result) 49 | end 50 | 51 | it { is_expected.to eq result } 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/configurations.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Configurations < Basic 3 | # @return [Boolean] 4 | def array_flag 5 | true 6 | end 7 | 8 | # The method name used for interacting with Configurations via Zabbix API 9 | # 10 | # @return [String] 11 | def method_name 12 | 'configuration' 13 | end 14 | 15 | # The id field name used for identifying specific Configuration objects via Zabbix API 16 | # 17 | # @return [String] 18 | def identify 19 | 'host' 20 | end 21 | 22 | # Export configuration data using Zabbix API 23 | # 24 | # @param data [Hash] 25 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 26 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 27 | # @return [Hash] 28 | def export(data) 29 | @client.api_request(method: 'configuration.export', params: data) 30 | end 31 | 32 | # Import configuration data using Zabbix API 33 | # 34 | # @param data [Hash] 35 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 36 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 37 | # @return [Hash] 38 | def import(data) 39 | @client.api_request(method: 'configuration.import', params: data) 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/drule.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'spec_helper' 4 | 5 | describe 'drule' do 6 | before do 7 | @drulename = gen_name 'drule' 8 | @usergroupid = zbx.usergroups.create(:name => gen_name('usergroup')) 9 | @dcheckdata = [{ 10 | :type => '9', # zabbix agent 11 | :uniq => '0', # (default) do not use this check as a uniqueness criteria 12 | :key_ => 'system.hostname', 13 | :ports => '10050', 14 | }] 15 | @druledata = { 16 | :name => @drulename, 17 | :delay => '60', 18 | :status => '0', # action is enabled 19 | :iprange => '192.168.0.0/24', # iprange to discover zabbix agents in 20 | :dchecks => @dcheckdata, 21 | } 22 | end 23 | 24 | context 'when not exists' do 25 | describe 'create' do 26 | it 'should return integer id' do 27 | druleid = zbx.drules.create(@druledata) 28 | expect(druleid).to be_kind_of(Integer) 29 | end 30 | end 31 | end 32 | 33 | context 'when exists' do 34 | before do 35 | @druleid = zbx.drules.create(@druledata) 36 | end 37 | 38 | describe 'create_or_update' do 39 | it 'should return id' do 40 | expect(zbx.drules.create_or_update(@druledata)).to eq @druleid 41 | end 42 | end 43 | 44 | describe 'delete' do 45 | it 'should return id' do 46 | expect(zbx.drules.delete(@druleid)).to eq @druleid 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/configurations_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Configurations' do 4 | let(:configurations_mock) { ZabbixApi::Configurations.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.array_flag' do 8 | subject { configurations_mock.array_flag } 9 | 10 | it { is_expected.to be_truthy } 11 | end 12 | 13 | describe '.method_name' do 14 | subject { configurations_mock.method_name } 15 | 16 | it { is_expected.to eq 'configuration' } 17 | end 18 | 19 | describe '.identify' do 20 | subject { configurations_mock.identify } 21 | 22 | it { is_expected.to eq 'host' } 23 | end 24 | 25 | describe '.export' do 26 | subject { configurations_mock.export(data) } 27 | 28 | let(:data) { { testdata: 222 } } 29 | let(:result) { { test: 1 } } 30 | 31 | before do 32 | allow(client).to receive(:api_request).with( 33 | method: 'configuration.export', 34 | params: data 35 | ).and_return(result) 36 | end 37 | 38 | it { is_expected.to eq result } 39 | end 40 | 41 | describe '.import' do 42 | subject { configurations_mock.import(data) } 43 | 44 | let(:data) { { testdata: 222 } } 45 | let(:result) { { test: 1 } } 46 | 47 | before do 48 | allow(client).to receive(:api_request).with( 49 | method: 'configuration.import', 50 | params: data 51 | ).and_return(result) 52 | end 53 | 54 | it { is_expected.to eq result } 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /spec/problem.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'problem' do 4 | before do 5 | @problemdata = { 6 | eventid: gen_id.to_s, 7 | source: "0", 8 | object: "0", 9 | objectid: gen_id.to_s, 10 | clock: "1611856476", 11 | ns: "183091100", 12 | r_eventid: "0", 13 | r_clock: "0", 14 | r_ns: "0", 15 | correlationid: "0", 16 | userid: "0", 17 | name: "Zabbix agent is not available (for 3m)", 18 | acknowledged: "0", 19 | severity: "3", 20 | opdata: "", 21 | acknowledges: [], 22 | suppression_data: [], 23 | suppressed: "0", 24 | urls: [], 25 | tags: [] 26 | } 27 | end 28 | 29 | context 'when incorrect method' do 30 | describe 'create' do 31 | it 'should raise ApiError' do 32 | expect{zbx.problems.create({})}. 33 | to raise_error(ZabbixApi::ApiError, /.*\"data\": \"Incorrect method \\\"problem.create\\\"\.\"/) 34 | end 35 | end 36 | 37 | describe 'delete' do 38 | it 'should raise ApiError' do 39 | expect{zbx.problems.delete({})}. 40 | to raise_error(ZabbixApi::ApiError, /.*\"data\": \"Incorrect method \\\"problem.delete\\\"\.\"/) 41 | end 42 | end 43 | 44 | # describe 'update' do 45 | # it 'should raise ApiError' do 46 | # expect{zbx.problems.update({name: gen_name("problem")})}. 47 | # to raise_error(ZabbixApi::ApiError, /.*\"data\": \"Incorrect method \\\"problem.update\\\"\.\"/) 48 | # end 49 | # end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /lib/zabbixapi/basic/basic_alias.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Basic 3 | # Get Zabbix object data from API by id 4 | # 5 | # @param data [Hash] Should include object's id field name (identify) and id value 6 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 7 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 8 | # @return [Hash] 9 | def get(data) 10 | get_full_data(data) 11 | end 12 | 13 | # Add new Zabbix object using API create 14 | # 15 | # @param data [Hash] 16 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 17 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 18 | # @return [Integer] The object id if a single object is created 19 | # @return [Boolean] True/False if multiple objects are created 20 | def add(data) 21 | create(data) 22 | end 23 | 24 | # Destroy Zabbix object using API delete 25 | # 26 | # @param data [Hash] Should include object's id field name (identify) and id value 27 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 28 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 29 | # @return [Integer] The object id if a single object is deleted 30 | # @return [Boolean] True/False if multiple objects are deleted 31 | def destroy(data) 32 | delete(data) 33 | end 34 | 35 | def method_name; end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/zabbixapi/basic/basic_init_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Basic' do 4 | let(:basic_mock) { ZabbixApi::Basic.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.initialize' do 8 | subject { basic_mock } 9 | 10 | it 'sets passed client object as class variable' do 11 | expect(subject.instance_variable_get(:@client)).to eq client 12 | end 13 | end 14 | 15 | describe '.method_name' do 16 | subject { basic_mock.method_name } 17 | 18 | it 'raises an ApiError with message' do 19 | expect { subject }.to raise_error(ZabbixApi::ApiError, "Can't call method_name here") 20 | end 21 | end 22 | 23 | describe '.default_options' do 24 | subject { basic_mock.default_options } 25 | 26 | it { is_expected.to be_empty } 27 | end 28 | 29 | describe '.keys' do 30 | subject { basic_mock.keys } 31 | 32 | let(:key) { 'test-key' } 33 | let(:expected) { 'test-keys' } 34 | 35 | before { allow(basic_mock).to receive(:key).and_return(key) } 36 | 37 | it { is_expected.to eq expected } 38 | end 39 | 40 | describe '.key' do 41 | subject { basic_mock.key } 42 | 43 | let(:key) { 'test-key' } 44 | let(:expected) { 'test-keyid' } 45 | 46 | before { allow(basic_mock).to receive(:method_name).and_return(key) } 47 | 48 | it { is_expected.to eq expected } 49 | end 50 | 51 | describe '.identify' do 52 | subject { basic_mock.identify } 53 | 54 | it 'raises an ApiError with message' do 55 | expect { subject }.to raise_error(ZabbixApi::ApiError, "Can't call identify here") 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /examples/Graphs.md: -------------------------------------------------------------------------------- 1 | # Graphs 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Graphs: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/graph](https://www.zabbix.com/documentation/4.0/manual/api/reference/graph) 7 | 8 | ## Create Graph 9 | ```ruby 10 | gitems = { 11 | :itemid => zbx.items.get_id(:name => "item"), 12 | :calc_fnc => "2", 13 | :type => "0", 14 | :periods_cnt => "5" 15 | } 16 | 17 | zbx.graphs.create( 18 | :gitems => [gitems], 19 | :show_triggers => "0", 20 | :name => "graph", 21 | :width => "900", 22 | :height => "200", 23 | :hostid => zbx.templates.get_id(:host => "template") 24 | ) 25 | ``` 26 | 27 | ## Update Graph 28 | ```ruby 29 | zbx.graphs.update( 30 | :graphid => zbx.graphs.get_id(:name => "graph"), 31 | :ymax_type => 1 32 | ) 33 | 34 | #Also you can use: 35 | gitems = { 36 | :itemid => zbx.items.get_id(:name => "item"), 37 | :calc_fnc => "3", 38 | :type => "0", 39 | :periods_cnt => "5" 40 | } 41 | zbx.graphs.create_or_update( 42 | :gitems => [gitems], 43 | :show_triggers => "1", 44 | :name => graph, 45 | :width => "900", 46 | :height => "200", 47 | :hostid => zbx.templates.get_id(:host => "template") 48 | ) 49 | ``` 50 | 51 | ## Get Graph ids by Host ### 52 | ```ruby 53 | zbx.graphs.get_ids_by_host(:host => "hostname") 54 | 55 | #You can filter graph name: 56 | zbx.graphs.get_ids_by_host(:host => "hostname", filter => "CPU") 57 | ``` 58 | 59 | ## Delete Graph 60 | ```ruby 61 | zbx.graphs.delete(zbx.graphs.get_id(:name => "graph")) 62 | ``` 63 | 64 | -------------------------------------------------------------------------------- /examples/Httptests.md: -------------------------------------------------------------------------------- 1 | # Httptests 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Httptests: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/httptest](https://www.zabbix.com/documentation/4.0/manual/api/reference/httptest) 7 | 8 | ## Create Web Scenario (httptest) 9 | ```ruby 10 | zbx.httptests.create( 11 | :name => "web scenario", 12 | :hostid => zbx.templates.get_id(:host => "template"), 13 | :applicationid => zbx.applications.get_id(:name => "application"), 14 | :steps => [ 15 | { 16 | :name => "step", 17 | :url => "http://localhost/zabbix/", 18 | :status_codes => 200, 19 | :no => 1 20 | } 21 | ] 22 | ) 23 | 24 | # or use (lib merge json): 25 | zbx.httptests.create_or_update( 26 | :name => "web scenario", 27 | :hostid => zbx.templates.get_id(:host => "template"), 28 | :applicationid => zbx.applications.get_id(:name => "application"), 29 | :steps => [ 30 | { 31 | :name => "step", 32 | :url => "http://localhost/zabbix/", 33 | :status_codes => 200, 34 | :no => 1 35 | }, 36 | { 37 | :name => "step 2", 38 | :url => "http://localhost/zabbix/index.php", 39 | :status_codes => 200, 40 | :no => 2 41 | } 42 | ] 43 | ) 44 | ``` 45 | 46 | ## Update Web Scenario (httptest) 47 | ```ruby 48 | zbx.httptests.update( 49 | :httptestid => zbx.httptests.get_id(:name => "web scenario"), 50 | :status => 0 51 | ) 52 | 53 | #You can check web scenario: 54 | puts zbx.httptests.get_full_data(:name => "web scenario") 55 | 56 | -------------------------------------------------------------------------------- /spec/hostgroup.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'hostgroup' do 4 | context 'when not exists' do 5 | describe 'create' do 6 | it 'should return integer id after creation' do 7 | hostgroupid = zbx.hostgroups.create(name: "hostgroup_#{rand(1_000_000)}") 8 | expect(hostgroupid).to be_kind_of(Integer) 9 | end 10 | end 11 | end 12 | 13 | context 'when exists' do 14 | before :all do 15 | @hostgroup = gen_name('hostgroup') 16 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 17 | end 18 | 19 | describe 'get_id' do 20 | it 'should return id' do 21 | expect(zbx.hostgroups.get_id(name: @hostgroup)).to eq @hostgroupid 22 | end 23 | 24 | it 'should return nil for not existing group' do 25 | expect(zbx.hostgroups.get_id(name: "#{@hostgroup}______")).to be_kind_of(NilClass) 26 | end 27 | end 28 | 29 | describe 'get_or_create' do 30 | it 'should return id of existing hostgroup' do 31 | expect(zbx.hostgroups.get_or_create(name: @hostgroup)).to eq @hostgroupid 32 | end 33 | end 34 | 35 | describe 'create_or_update' do 36 | it 'should return id of hostgroup' do 37 | expect(zbx.hostgroups.create_or_update(name: @hostgroup)).to eq @hostgroupid 38 | end 39 | end 40 | 41 | describe 'all' do 42 | it 'should contains created hostgroup' do 43 | expect(zbx.hostgroups.all).to include(@hostgroup => @hostgroupid.to_s) 44 | end 45 | end 46 | 47 | describe 'delete' do 48 | it 'shold return id' do 49 | expect(zbx.hostgroups.delete(@hostgroupid)).to eq @hostgroupid 50 | end 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/errors_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::BaseError' do 4 | let(:error_mock) { ZabbixApi::BaseError.new(message, response) } 5 | let(:message) { 'Test Message' } 6 | let(:response) { { 'error' => { 'data' => error_data, 'message' => error_message } } } 7 | let(:error_data) { 'Program is borked' } 8 | let(:error_message) { 'something has gone wrong' } 9 | 10 | describe '.initialize' do 11 | subject { error_mock } 12 | 13 | it 'calls super with error message' do 14 | expect_any_instance_of(RuntimeError).to receive(:initialize).with(message) 15 | subject 16 | end 17 | 18 | context 'when response is passed in' do 19 | it 'response class variable should be set' do 20 | expect(subject.instance_variable_get(:@response)).to eq response 21 | end 22 | 23 | it 'error class variable should be set' do 24 | expect(subject.instance_variable_get(:@error)).to eq response['error'] 25 | end 26 | 27 | it 'error message class variable should be set' do 28 | expect(subject.instance_variable_get(:@error_message)).to eq "#{error_message}: #{error_data}" 29 | end 30 | end 31 | 32 | context 'when response is not passed in' do 33 | let(:response) { nil } 34 | 35 | it 'should not set response class variable' do 36 | expect(subject.instance_variable_get(:@response)).to be_nil 37 | end 38 | 39 | it 'should not set error class variable' do 40 | expect(subject.instance_variable_get(:@error)).to be_nil 41 | end 42 | 43 | it 'should not set error message class variable' do 44 | expect(subject.instance_variable_get(:@error_message)).to be_nil 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/applications.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Applications < Basic 3 | # The method name used for interacting with Applications via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'application' 8 | end 9 | 10 | # The id field name used for identifying specific Application objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # Get or Create Application object using Zabbix API 18 | # 19 | # @param data [Hash] Needs to include name and hostid to properly identify Applications via Zabbix API 20 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 21 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 22 | # @return [Integer] Zabbix object id 23 | def get_or_create(data) 24 | log "[DEBUG] Call get_or_create with parameters: #{data.inspect}" 25 | 26 | unless (id = get_id(name: data[:name], hostid: data[:hostid])) 27 | id = create(data) 28 | end 29 | id 30 | end 31 | 32 | # Create or update Application object using Zabbix API 33 | # 34 | # @param data [Hash] Needs to include name and hostid to properly identify Applications via Zabbix API 35 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 36 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 37 | # @return [Integer] Zabbix object id 38 | def create_or_update(data) 39 | applicationid = get_id(name: data[:name], hostid: data[:hostid]) 40 | applicationid ? update(data.merge(applicationid: applicationid)) : create(data) 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/valuemaps.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class ValueMaps < Basic 3 | # The method name used for interacting with ValueMaps via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'valuemap' 8 | end 9 | 10 | # The key field name used for ValueMap objects via Zabbix API 11 | # 12 | # @return [String] 13 | def key 14 | 'valuemapid' 15 | end 16 | 17 | # The id field name used for identifying specific ValueMap objects via Zabbix API 18 | # 19 | # @return [String] 20 | def identify 21 | 'name' 22 | end 23 | 24 | # Get or Create ValueMap object using Zabbix API 25 | # 26 | # @param data [Hash] Needs to include valuemapids [List] to properly identify ValueMaps via Zabbix API 27 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 28 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 29 | # @return [Integer] Zabbix object id 30 | def get_or_create(data) 31 | log "[DEBUG] Call get_or_create with parameters: #{data.inspect}" 32 | 33 | unless (id = get_id(valuemapids: data[:valuemapids])) 34 | id = create(data) 35 | end 36 | id 37 | end 38 | 39 | # Create or update Item object using Zabbix API 40 | # 41 | # @param data [Hash] Needs to include valuemapids to properly identify ValueMaps via Zabbix API 42 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 43 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 44 | # @return [Integer] Zabbix object id 45 | def create_or_update(data) 46 | valuemapid = get_id(name: data[:name]) 47 | valuemapid ? update(data.merge(valuemapids: [:valuemapid])) : create(data) 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/drules.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Drules < Basic 3 | # The method name used for interacting with Drules via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'drule' 8 | end 9 | 10 | # The id field name used for identifying specific Drule objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # The default options used when creating Drule objects via Zabbix API 18 | # 19 | # @return [Hash] 20 | def default_options 21 | { 22 | name: nil, 23 | iprange: nil, 24 | delay: 3600, 25 | status: 0, 26 | } 27 | end 28 | 29 | # Get or Create Drule object using Zabbix API 30 | # 31 | # @param data [Hash] Needs to include name to properly identify Drule via Zabbix API 32 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 33 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 34 | # @return [Integer] Zabbix object id 35 | def get_or_create(data) 36 | log "[DEBUG] Call get_or_create with parameters: #{data.inspect}" 37 | 38 | unless (id = get_id(name: data[:name])) 39 | id = create(data) 40 | end 41 | id 42 | end 43 | 44 | # Create or update Drule object using Zabbix API 45 | # 46 | # @param data [Hash] Needs to include name to properly identify Drules via Zabbix API 47 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 48 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 49 | # @return [Integer] Zabbix object id 50 | def create_or_update(data) 51 | druleid = get_id(name: data[:name]) 52 | druleid ? update(data.merge(druleid: druleid)) : create(data) 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/httptests.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class HttpTests < Basic 3 | # The method name used for interacting with HttpTests via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'httptest' 8 | end 9 | 10 | # The id field name used for identifying specific HttpTest objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # The default options used when creating HttpTest objects via Zabbix API 18 | # 19 | # @return [Hash] 20 | def default_options 21 | { 22 | hostid: nil, 23 | name: nil, 24 | steps: [] 25 | } 26 | end 27 | 28 | # Get or Create HttpTest object using Zabbix API 29 | # 30 | # @param data [Hash] Needs to include name and hostid to properly identify HttpTests via Zabbix API 31 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 32 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 33 | # @return [Integer] Zabbix object id 34 | def get_or_create(data) 35 | log "[DEBUG] Call get_or_create with parameters: #{data.inspect}" 36 | 37 | unless (id = get_id(name: data[:name], hostid: data[:hostid])) 38 | id = create(data) 39 | end 40 | id 41 | end 42 | 43 | # Create or update HttpTest object using Zabbix API 44 | # 45 | # @param data [Hash] Needs to include name and hostid to properly identify HttpTests via Zabbix API 46 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 47 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 48 | # @return [Integer] Zabbix object id 49 | def create_or_update(data) 50 | httptestid = get_id(name: data[:name], hostid: data[:hostid]) 51 | httptestid ? update(data.merge(httptestid: httptestid)) : create(data) 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/proxies.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Proxies < Basic 3 | # The method name used for interacting with Proxies via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'proxy' 8 | end 9 | 10 | # The id field name used for identifying specific Proxy objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # Delete Proxy object using Zabbix API 18 | # 19 | # @param data [Array] Should include array of proxyid's 20 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 21 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 22 | # @return [Integer] The Proxy object id that was deleted 23 | def delete(data) 24 | result = @client.api_request(method: 'proxy.delete', params: data) 25 | result.empty? ? nil : result['proxyids'][0].to_i 26 | end 27 | 28 | # Check if a Proxy object is readable using Zabbix API 29 | # 30 | # @param data [Array] Should include array of proxyid's 31 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 32 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 33 | # @return [Boolean] Returns true if the given proxies are readable 34 | def isreadable(data) 35 | @client.api_request(method: 'proxy.isreadable', params: data) 36 | end 37 | 38 | # Check if a Proxy object is writable using Zabbix API 39 | # 40 | # @param data [Array] Should include array of proxyid's 41 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 42 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 43 | # @return [Boolean] Returns true if the given proxies are writable 44 | def iswritable(data) 45 | @client.api_request(method: 'proxy.iswritable', params: data) 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /examples/Problems.md: -------------------------------------------------------------------------------- 1 | # Problems 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for MediaTypes: 6 | [https://www.zabbix.com/documentation/5.2/manual/api/reference/problem](https://www.zabbix.com/documentation/5.2/manual/api/reference/problem) 7 | 8 | ## Get Problems 9 | Problem Zabbix API object does not have unique identifier, but search can be 10 | filtered by `name`, and/or one of the following: 11 | - `eventids`: Return only problems with the given IDs. 12 | - `groupids`: Return only problems created by objects that belong to the given 13 | host groups. 14 | - `hostids`: Return only problems created by objects that belong to the given 15 | hosts. 16 | - `objectids`: Return only problems created by the given objects. 17 | - `applicationids`: Return only problems created by objects that belong to the 18 | given applications. Applies only if object is trigger or item. 19 | - `tags`: Return only problems with given tags. Exact match by tag and 20 | case-insensitive search by value and operator. 21 | - `eventid_from`: Return only problems with IDs greater or equal to the given 22 | ID. 23 | - `eventid_till`: Return only problems with IDs less or equal to the given ID. 24 | - `time_from`: Return only problems that have been created after or at the given 25 | time. 26 | - `time_till`: Return only problems that have been created before or at the 27 | given time. 28 | 29 | See Zabbix API documentation for more details. 30 | 31 | ```ruby 32 | # selecting by name (which is not unique) 33 | zbx.problems.dump_by_id( 34 | name: "Zabbix agent is not available (for 3m)" 35 | ) 36 | 37 | # selecting by source eventids 38 | zbx.problems.get(eventids: "86") 39 | 40 | # selecting by source objectids 41 | zbx.problems.get(objectids: "17884") 42 | 43 | # selecting by timestamp 44 | zbx.problems.get(time_from: 1611928989) 45 | zbx.problems.get(time_till: 1611928989) 46 | ``` 47 | 48 | ## Get all Problems 49 | ```ruby 50 | zbx.problems.all 51 | ``` 52 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/users.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Users < Basic 3 | # The method name used for interacting with Users via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'user' 8 | end 9 | 10 | # The keys field name used for User objects via Zabbix API 11 | # 12 | # @return [String] 13 | def keys 14 | 'userids' 15 | end 16 | 17 | # The key field name used for User objects via Zabbix API 18 | # 19 | # @return [String] 20 | def key 21 | 'userid' 22 | end 23 | 24 | # The id field name used for identifying specific User objects via Zabbix API 25 | # 26 | # @return [String] 27 | def identify 28 | 'alias' 29 | end 30 | 31 | def medias_helper(data, action) 32 | result = @client.api_request( 33 | method: "user.#{action}", 34 | params: data[:userids].map do |t| 35 | { 36 | userid: t, 37 | user_medias: data[:media], 38 | } 39 | end, 40 | ) 41 | result ? result['userids'][0].to_i : nil 42 | end 43 | 44 | # Add media to users using Zabbix API 45 | # 46 | # @param data [Hash] Needs to include userids and media to mass add media to users 47 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 48 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 49 | # @return [Integer] Zabbix object id (media) 50 | def add_medias(data) 51 | medias_helper(data, 'update') 52 | end 53 | 54 | # Update media for users using Zabbix API 55 | # 56 | # @param data [Hash] Needs to include userids and media to mass update media for users 57 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 58 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 59 | # @return [Integer] Zabbix object id (user) 60 | def update_medias(data) 61 | medias_helper(data, 'update') 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | #CHANGELOG 2 | 3 | ## 4.2.0 4 | [PR #102](https://github.com/express42/zabbixapi/pull/102) Add events get method method. Fixed all testing failures. (Thanks @kevin-j-smith) 5 | 6 | ## 4.1.2 7 | [PR #99](https://github.com/express42/zabbixapi/pull/99) Patch addressing log error function not found 8 | 9 | ## 4.1.1 10 | 11 | [PR #97](https://github.com/express42/zabbixapi/pull/97) Bumped version 12 | 13 | [PR #98](https://github.com/express42/zabbixapi/pull/98) Removed strict zabbix versioning error 14 | 15 | ## 4.1.0 16 | 17 | [PR #82](https://github.com/express42/zabbixapi/pull/82) Add logout method (Thanks @baurmatt) 18 | 19 | [PR #86](https://github.com/express42/zabbixapi/pull/86) Feature: add support for Discovery Rules (`drule` API) (Thanks @lehn-etracker) 20 | 21 | ## 4.0.0 22 | 23 | [PR #90](https://github.com/express42/zabbixapi/pull/90) Add 4.0 support (Thanks @svdasein) 24 | 25 | [PR #85](https://github.com/express42/zabbixapi/pull/85) Add 3.4 support (Thanks @ottok) 26 | 27 | ## 3.2.0 28 | 29 | [PR #77](https://github.com/express42/zabbixapi/pull/77) Add support for Valuemap (Thanks @julienlevasseur) 30 | 31 | [PR #80](https://github.com/express42/zabbixapi/pull/80) Hide password then raising error (Thanks @bbaugher) 32 | 33 | ## 3.1.0 34 | 35 | [PR #68](https://github.com/express42/zabbixapi/pull/68) Add support for scripts (Thanx @jrbeilke) 36 | 37 | ## 2.4.9 38 | 39 | [PR #55](https://github.com/express42/zabbixapi/pull/55) Add 3.2.x support (Thanx @jrbeilke) 40 | 41 | [PR #54](https://github.com/express42/zabbixapi/pull/54) Add web scenarios support (Thanx @jrbeilke) 42 | 43 | 44 | ## 2.4.7 45 | 46 | [PR #45](https://github.com/express42/zabbixapi/pull/45) Add support for zabbix 3.0.x (Thanx @wandenberg) 47 | 48 | ## 2.4.6 49 | 50 | [PR #39](https://github.com/express42/zabbixapi/issues/39) Add support for maintenance API 51 | 52 | ## 2.4.5 53 | 54 | [PR #33](https://github.com/express42/zabbixapi/issues/33) Typed exceptions 55 | 56 | ## 2.4.4 57 | 58 | [Issue #32](https://github.com/express42/zabbixapi/issues/32): Force update of objects in zabbix 59 | -------------------------------------------------------------------------------- /spec/event.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'event' do 4 | before do 5 | @eventname = gen_name 'event' 6 | @usergroupid = zbx.usergroups.create(name: gen_name('usergroup')) 7 | @eventdata = { 8 | name: @eventname, 9 | eventsource: '0', # event source is a triggerid 10 | status: '0', # event is enabled 11 | esc_period: '120', # how long each step should take 12 | def_shortdata: 'Email header', 13 | def_longdata: 'Email content', 14 | maintenance_mode: '1', 15 | filter: { 16 | evaltype: '1', # perform 'and' between the conditions 17 | conditions: [ 18 | { 19 | conditiontype: '3', # trigger name 20 | operator: '2', # like 21 | value: 'pattern' # the pattern 22 | }, 23 | { 24 | conditiontype: '4', # trigger severity 25 | operator: '5', # >= 26 | value: '3' # average 27 | } 28 | ] 29 | }, 30 | operations: [ 31 | { 32 | operationtype: '0', # send message 33 | opmessage_grp: [ # who the message will be sent to 34 | { 35 | usrgrpid: @usergroupid 36 | } 37 | ], 38 | opmessage: { 39 | default_msg: '0', # use default message 40 | mediatypeid: '1' # email id 41 | } 42 | } 43 | ], 44 | recovery_operations: [ 45 | { 46 | operationtype: '11', # send recovery message 47 | opmessage_grp: [ # who the message will be sent to 48 | { 49 | usrgrpid: @usergroupid 50 | } 51 | ], 52 | opmessage: { 53 | default_msg: '0', # use default message 54 | mediatypeid: '1' # email id 55 | } 56 | } 57 | ] 58 | } 59 | end 60 | 61 | context 'when incorrect method' do 62 | describe 'create' do 63 | it 'should raise ApiError' do 64 | expect{zbx.events.create(@eventdata)}. 65 | to raise_error(ZabbixApi::ApiError, /.*\"data\": \"Incorrect method \\\"event.create\\\"\.\"/) 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - $default-branch 7 | paths-ignore: 8 | - '**.md' 9 | pull_request: 10 | branches: 11 | - $default-branch 12 | paths-ignore: 13 | - '**.md' 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-20.04 18 | strategy: 19 | matrix: 20 | ruby: 21 | - 2.5 22 | - 2.6 23 | - 2.7 24 | - head 25 | - jruby-9.2.10 26 | - jruby-head 27 | services: 28 | postgres: 29 | image: postgres:13-alpine 30 | # ports: ['5432:5432'] 31 | env: 32 | POSTGRES_DB: zabbix 33 | POSTGRES_USER: zabbix 34 | POSTGRES_PASSWORD: password 35 | options: >- 36 | --health-cmd pg_isready 37 | --health-interval 10s 38 | --health-timeout 5s 39 | --health-retries 5 40 | zabbix-server: 41 | image: zabbix/zabbix-server-pgsql:alpine-5.2-latest 42 | # ports: ['10051:10051'] 43 | env: 44 | DB_SERVER_HOST: postgres 45 | POSTGRES_USER: zabbix 46 | POSTGRES_PASSWORD: password 47 | zabbix-frontend: 48 | image: zabbix/zabbix-web-apache-pgsql:alpine-5.2-latest 49 | ports: ['8080:8080'] 50 | env: 51 | DB_SERVER_HOST: postgres 52 | POSTGRES_USER: zabbix 53 | POSTGRES_PASSWORD: password 54 | ZBX_SERVER_HOST: zabbix-server 55 | PHP_TZ: "US/Eastern" 56 | steps: 57 | - uses: actions/checkout@v2 58 | - uses: ruby/setup-ruby@v1 # actions/setup-ruby@v1 59 | with: 60 | ruby-version: ${{ matrix.ruby }} 61 | - uses: actions/cache@v2 62 | with: 63 | path: vendor/bundle 64 | key: ${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }} 65 | restore-keys: | 66 | ${{ matrix.ruby }}-gems- 67 | - name: Bundle install 68 | run: | 69 | gem list --silent -i bundler -v '~> 2' || gem install bundler -v '~> 2' --no-document 70 | bundle config path vendor/bundle 71 | bundle install --without development --jobs 4 --retry 3 72 | - name: Run tests 73 | run: bundle exec rspec ./spec/* 74 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/proxygroup.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Proxygroup < Basic 3 | # The method name used for interacting with Proxygroup via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'proxygroup' 8 | end 9 | 10 | # The id field name used for identifying specific Proxygroup objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # The key field name used for proxygroup objects via Zabbix API 18 | # 19 | # @return [String] 20 | def key 21 | 'proxy_groupid' 22 | end 23 | 24 | # Delete Proxygroup object using Zabbix API 25 | # 26 | # @param data [Array] Should include array of Proxygroupid's 27 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 28 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 29 | # @return [Integer] The Proxygroup object id that was deleted 30 | def delete(data) 31 | result = @client.api_request(method: 'proxygroup.delete', params: data) 32 | result.empty? ? nil : result['proxyids'][0].to_i 33 | end 34 | 35 | # Check if a Proxygroup object is readable using Zabbix API 36 | # 37 | # @param data [Array] Should include array of Proxygroupid's 38 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 39 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 40 | # @return [Boolean] Returns true if the given Proxygroupgroup are readable 41 | def isreadable(data) 42 | @client.api_request(method: 'proxygroup.isreadable', params: data) 43 | end 44 | 45 | # Check if a Proxygroup object is writable using Zabbix API 46 | # 47 | # @param data [Array] Should include array of Proxygroupid's 48 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 49 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 50 | # @return [Boolean] Returns true if the given Proxygroup are writable 51 | def iswritable(data) 52 | @client.api_request(method: 'proxygroup.iswritable', params: data) 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /spec/screen.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'screen' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 7 | @template = gen_name 'template' 8 | @templateid = zbx.templates.create( 9 | host: @template, 10 | groups: [groupid: @hostgroupid] 11 | ) 12 | @application = gen_name 'application' 13 | @applicationid = zbx.applications.create( 14 | name: @application, 15 | hostid: @templateid 16 | ) 17 | @item = gen_name 'item' 18 | @itemid = zbx.items.create( 19 | name: @item, 20 | key_: "proc.num[#{gen_name 'proc'}]", 21 | status: 0, 22 | hostid: @templateid, 23 | applications: [@applicationid] 24 | ) 25 | 26 | @color = '123456' 27 | 28 | @gitems = { 29 | itemid: @itemid, 30 | calc_fnc: '3', 31 | color: @color, 32 | type: '0', 33 | periods_cnt: '5' 34 | } 35 | 36 | @graph = gen_name 'graph' 37 | 38 | @graphid = zbx.graphs.create( 39 | gitems: [@gitems], 40 | show_triggers: '0', 41 | name: @graph, 42 | width: '900', 43 | height: '200' 44 | ) 45 | 46 | @screen_name = gen_name 'screen' 47 | end 48 | 49 | context 'when not exists' do 50 | describe 'get_or_create_for_host' do 51 | it 'should return id' do 52 | screenid = zbx.screens.get_or_create_for_host( 53 | screen_name: @screen_name, 54 | graphids: [@graphid] 55 | ) 56 | expect(screenid).to be_kind_of(Integer) 57 | end 58 | end 59 | end 60 | 61 | context 'when exists' do 62 | before do 63 | @screen_name = gen_name 'screen' 64 | @screenid = zbx.screens.get_or_create_for_host( 65 | screen_name: @screen_name, 66 | graphids: [@graphid] 67 | ) 68 | end 69 | 70 | describe 'get_or_create_for_host' do 71 | it 'should return id' do 72 | screenid = zbx.screens.get_or_create_for_host( 73 | screen_name: @screen_name, 74 | graphids: [@graphid] 75 | ) 76 | expect(screenid).to eq @screenid 77 | end 78 | end 79 | 80 | describe 'delete' do 81 | it 'should return id' do 82 | expect(zbx.screens.delete(@screenid)).to eq @screenid 83 | end 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /spec/application.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'application' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 7 | @template = gen_name 'template' 8 | @templateid = zbx.templates.create( 9 | host: @template, 10 | groups: [groupid: @hostgroupid] 11 | ) 12 | end 13 | 14 | context 'when name not exists' do 15 | before do 16 | @application = gen_name 'application' 17 | end 18 | 19 | describe 'create' do 20 | it 'should return integer id' do 21 | applicationid = zbx.applications.create( 22 | name: @application, 23 | hostid: @templateid 24 | ) 25 | expect(applicationid).to be_kind_of(Integer) 26 | end 27 | end 28 | 29 | describe 'get_id' do 30 | it 'should return nil' do 31 | expect(zbx.applications.get_id(name: @application)).to be_kind_of(NilClass) 32 | end 33 | end 34 | end 35 | 36 | context 'when name exists' do 37 | before :all do 38 | @application = gen_name 'application' 39 | @applicationid = zbx.applications.create( 40 | name: @application, 41 | hostid: @templateid 42 | ) 43 | end 44 | 45 | describe 'get_or_create' do 46 | it 'should return id of application' do 47 | expect( 48 | zbx.applications.get_or_create( 49 | name: @application, 50 | hostid: @templateid 51 | ) 52 | ).to eq @applicationid 53 | end 54 | end 55 | 56 | describe 'get_full_data' do 57 | it 'should contains created application' do 58 | expect(zbx.applications.get_full_data(name: @application)[0]).to include('name' => @application) 59 | end 60 | end 61 | 62 | describe 'get_id' do 63 | it 'should return id of application' do 64 | expect(zbx.applications.get_id(name: @application)).to eq @applicationid 65 | end 66 | end 67 | 68 | describe 'create_or_update' do 69 | it 'should return id of updated application' do 70 | expect( 71 | zbx.applications.create_or_update( 72 | name: @application, 73 | hostid: @templateid 74 | ) 75 | ).to eq @applicationid 76 | end 77 | end 78 | 79 | describe 'delete' do 80 | it 'should return id' do 81 | expect(zbx.applications.delete(@applicationid)).to eq @applicationid 82 | end 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /examples/Actions.md: -------------------------------------------------------------------------------- 1 | # Actions 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Actions: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/action](https://www.zabbix.com/documentation/4.0/manual/api/reference/action) 7 | 8 | ## Create Action based on Trigger 9 | ```ruby 10 | zbx.actions.create( 11 | :name => "trigger action", 12 | :eventsource => '0', # event source is a triggerid 13 | :status => '0', # action is enabled 14 | :esc_period => '120', # how long each step should take 15 | :def_shortdata => "Email header", 16 | :def_longdata => "Email content", 17 | :maintenance_mode => '1', 18 | :filter => { 19 | :evaltype => '1', # perform 'and' between the conditions 20 | :conditions => [ 21 | { 22 | :conditiontype => '3', # trigger name 23 | :operator => '2', # like 24 | :value => 'pattern' # the pattern 25 | }, 26 | { 27 | :conditiontype => '4', # trigger severity 28 | :operator => '5', # >= 29 | :value => '3' # average 30 | } 31 | ] 32 | }, 33 | :operations => [ 34 | { 35 | :operationtype => '0', # send message 36 | :opmessage_grp => [ # who the message will be sent to 37 | { 38 | :usrgrpid => '2' 39 | } 40 | ], 41 | :opmessage => { 42 | :default_msg => '0', # use default message 43 | :mediatypeid => '1' # email id 44 | } 45 | } 46 | ], 47 | :recovery_operations => [ 48 | { 49 | :operationtype => '11', # send recovery message 50 | :opmessage_grp => [ # who the message will be sent to 51 | { 52 | :usrgrpid => '2' 53 | } 54 | ], 55 | :opmessage => { 56 | :default_msg => '0', # use default message 57 | :mediatypeid => '1' # email id 58 | } 59 | } 60 | ] 61 | ) 62 | # In Zabbix 3.2 and higher actions now have a maintenance_mode property which pauses notifications during host maintenance 63 | # A separate action condition for Maintenance status = not in “maintenance” is no longer needed 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | Examples Index 2 | ==================== 3 | 4 | - [Quick Start](README.md#quick-start) 5 | - [Connect](README.md#connect) 6 | - [Create Host](README.md#create-host) 7 | - [Custom Queries](README.md#custom-queries) 8 | - Supported Zabbix Objects 9 | - [Actions](Actions.md) 10 | - [Applications](Applications.md) 11 | - [Configurations](Configurations.md) 12 | - [Graphs](Graphs.md) 13 | - [Hostgroups](Hostgroups.md) 14 | - [Hosts](Hosts.md) 15 | - [Httptests](Httptests.md) 16 | - [Items](Items.md) 17 | - [Maintenance](Maintenance.md) 18 | - [MediaTypes](MediaTypes.md) 19 | - [Problems](Problems.md) 20 | - [Proxies](Proxies.md) 21 | - [Screens](Screens.md) 22 | - [Templates](Templates.md) 23 | - [Triggers](Triggers.md) 24 | - [Usergroups](Usergroups.md) 25 | - [Usermacros](Usermacros.md) 26 | - [Users](Users.md) 27 | 28 | # Quick Start 29 | 30 | ## Connect 31 | 32 | ### Standard 33 | ```ruby 34 | require "zabbixapi" 35 | 36 | zbx = ZabbixApi.connect( 37 | :url => 'http://localhost/zabbix/api_jsonrpc.php', 38 | :user => 'Admin', 39 | :password => 'zabbix' 40 | ) 41 | ``` 42 | 43 | ### Ignore Zabbix API version 44 | ```ruby 45 | require "zabbixapi" 46 | 47 | zbx = ZabbixApi.connect( 48 | :url => 'http://localhost/zabbix/api_jsonrpc.php', 49 | :user => 'Admin', 50 | :password => 'zabbix', 51 | :ignore_version => true 52 | ) 53 | ``` 54 | 55 | ### Basic Auth 56 | ```ruby 57 | require "zabbixapi" 58 | 59 | zbx = ZabbixApi.connect( 60 | :url => 'http://localhost/zabbix/api_jsonrpc.php', 61 | :user => 'Admin', 62 | :password => 'zabbix', 63 | :http_password => 'foo', 64 | :http_user => 'bar' 65 | ) 66 | ``` 67 | 68 | ## Logout 69 | ```ruby 70 | require "zabbixapi" 71 | 72 | zbx = ZabbixApi.connect( 73 | :url => 'http://localhost/zabbix/api_jsonrpc.php', 74 | :user => 'Admin', 75 | :password => 'zabbix' 76 | ) 77 | 78 | # Do stuff 79 | 80 | zbx.logout 81 | ``` 82 | 83 | ## Create Host 84 | ```ruby 85 | zbx.hosts.create( 86 | :host => host.fqdn, 87 | :interfaces => [ 88 | { 89 | :type => 1, 90 | :main => 1, 91 | :ip => '10.0.0.1', 92 | :dns => 'server.example.org', 93 | :port => 10050, 94 | :useip => 0 95 | } 96 | ], 97 | :groups => [ :groupid => zbx.hostgroups.get_id(:name => "hostgroup") ] 98 | ) 99 | ``` 100 | 101 | ## Custom Queries 102 | ```ruby 103 | zbx.query( 104 | :method => "apiinfo.version", 105 | :params => {} 106 | ) 107 | ``` 108 | -------------------------------------------------------------------------------- /spec/action.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'action' do 4 | before do 5 | @actionname = gen_name 'action' 6 | @usergroupid = zbx.usergroups.create(name: gen_name('usergroup')) 7 | @actiondata = { 8 | name: @actionname, 9 | eventsource: '0', # event source is a triggerid 10 | status: '0', # action is enabled 11 | esc_period: '120', # how long each step should take 12 | def_shortdata: 'Email header', 13 | def_longdata: 'Email content', 14 | maintenance_mode: '1', 15 | filter: { 16 | evaltype: '1', # perform 'and' between the conditions 17 | conditions: [ 18 | { 19 | conditiontype: '3', # trigger name 20 | operator: '2', # like 21 | value: 'pattern' # the pattern 22 | }, 23 | { 24 | conditiontype: '4', # trigger severity 25 | operator: '5', # >= 26 | value: '3' # average 27 | } 28 | ] 29 | }, 30 | operations: [ 31 | { 32 | operationtype: '0', # send message 33 | opmessage_grp: [ # who the message will be sent to 34 | { 35 | usrgrpid: @usergroupid 36 | } 37 | ], 38 | opmessage: { 39 | default_msg: '0', # use default message 40 | mediatypeid: '1' # email id 41 | } 42 | } 43 | ], 44 | recovery_operations: [ 45 | { 46 | operationtype: '11', # send recovery message 47 | opmessage_grp: [ # who the message will be sent to 48 | { 49 | usrgrpid: @usergroupid 50 | } 51 | ], 52 | opmessage: { 53 | default_msg: '0', # use default message 54 | mediatypeid: '1' # email id 55 | } 56 | } 57 | ] 58 | } 59 | end 60 | 61 | context 'when not exists' do 62 | describe 'create' do 63 | it 'should return integer id' do 64 | actionid = zbx.actions.create(@actiondata) 65 | expect(actionid).to be_kind_of(Integer) 66 | end 67 | end 68 | end 69 | 70 | context 'when exists' do 71 | before do 72 | @actionid = zbx.actions.create(@actiondata) 73 | end 74 | 75 | describe 'create_or_update' do 76 | it 'should return id' do 77 | expect(zbx.actions.create_or_update(@actiondata)).to eq @actionid 78 | end 79 | end 80 | 81 | describe 'delete' do 82 | it 'should return id' do 83 | expect(zbx.actions.delete(@actionid)).to eq @actionid 84 | end 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /spec/maintenance.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'maintenance' do 4 | context 'when not exists' do 5 | before :all do 6 | @hostgroupid = zbx.hostgroups.create(name: "hostgroup_#{rand(1_000_000)}") 7 | end 8 | 9 | describe 'create' do 10 | it 'should return integer id after creation' do 11 | maintenanceid = zbx.maintenance.create( 12 | name: "maintenance_#{rand(1_000_000)}", 13 | groupids: [@hostgroupid], 14 | active_since: '1358844540', 15 | active_till: '1390466940', 16 | timeperiods: [timeperiod_type: 3, every: 1, dayofweek: 64, start_time: 64_800, period: 3_600] 17 | ) 18 | expect(maintenanceid).to be_kind_of(Integer) 19 | zbx.maintenance.delete(maintenanceid) 20 | end 21 | end 22 | 23 | after :all do 24 | zbx.hostgroups.delete(@hostgroupid) 25 | end 26 | end 27 | 28 | context 'when exists' do 29 | before :all do 30 | @hostgroupid_when_exists = zbx.hostgroups.create(name: "hostgroup_#{rand(1_000_000)}") 31 | @maintenance = gen_name('maintenance') 32 | @maintenanceid = zbx.maintenance.create( 33 | name: @maintenance, 34 | groupids: [@hostgroupid_when_exists], 35 | active_since: '1358844540', 36 | active_till: '1390466940', 37 | timeperiods: [timeperiod_type: 3, every: 1, dayofweek: 64, start_time: 64_800, period: 3_600] 38 | ) 39 | end 40 | 41 | describe 'get_id' do 42 | it 'should return id' do 43 | expect(zbx.maintenance.get_id(name: @maintenance)).to eq @maintenanceid 44 | end 45 | 46 | it 'should return nil for not existing group' do 47 | expect(zbx.maintenance.get_id(name: "#{@maintenance}______")).to be_kind_of(NilClass) 48 | end 49 | end 50 | 51 | describe 'get_or_create' do 52 | it 'should return id of existing maintenance' do 53 | expect(zbx.maintenance.get_or_create(name: @maintenance)).to eq @maintenanceid 54 | end 55 | end 56 | 57 | describe 'create_or_update' do 58 | it 'should return id of maintenance' do 59 | expect(zbx.maintenance.create_or_update(name: @maintenance)).to eq @maintenanceid 60 | end 61 | end 62 | 63 | describe 'all' do 64 | it 'should contains created maintenance' do 65 | expect(zbx.maintenance.all).to include(@maintenance => @maintenanceid.to_s) 66 | end 67 | end 68 | 69 | describe 'delete' do 70 | it 'shold return id' do 71 | expect(zbx.maintenance.delete(@maintenanceid)).to eq @maintenanceid 72 | end 73 | end 74 | 75 | after :all do 76 | zbx.hostgroups.delete(@hostgroupid_when_exists) 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/valuemap_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::ValueMaps' do 4 | let(:valuemaps_mock) { ZabbixApi::ValueMaps.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { valuemaps_mock.method_name } 9 | 10 | it { is_expected.to eq 'valuemap' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { valuemaps_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.key' do 20 | subject { valuemaps_mock.key } 21 | 22 | it { is_expected.to eq 'valuemapid' } 23 | end 24 | 25 | describe '.get_or_create' do 26 | subject { valuemaps_mock.get_or_create(data) } 27 | 28 | let(:data) { { valuemapids: %w[100 101 102 104] } } 29 | 30 | before do 31 | allow(valuemaps_mock).to receive(:log) 32 | allow(valuemaps_mock).to receive(:get_id).and_return(data[:valuemapids].first) 33 | end 34 | 35 | it 'logs debug message' do 36 | expect(valuemaps_mock).to receive(:log).with("[DEBUG] Call get_or_create with parameters: #{data.inspect}") 37 | subject 38 | end 39 | 40 | context 'when id is found' do 41 | it 'returns the id' do 42 | expect(subject).to eq data[:valuemapids].first 43 | end 44 | end 45 | 46 | context 'when id is not found' do 47 | before { allow(valuemaps_mock).to receive(:get_id) } 48 | 49 | it 'creates a new id' do 50 | expect(valuemaps_mock).to receive(:create).with(data) 51 | subject 52 | end 53 | end 54 | end 55 | 56 | describe '.create_or_update' do 57 | subject { valuemaps_mock.create_or_update(data) } 58 | 59 | let(:data) { { name: 'fake_valuemap_name' } } 60 | let(:id) { 123 } 61 | 62 | before { allow(valuemaps_mock).to receive(:get_id).with(name: data[:name]).and_return(id) } 63 | 64 | after { subject } 65 | context 'when id is found' do 66 | let(:update_data) { data.merge(valuemapids: [id]) } 67 | 68 | before do 69 | allow(data).to receive(:merge).with(valuemapids: [:valuemapid]).and_return(update_data) 70 | 71 | allow(valuemaps_mock).to receive(:update) 72 | end 73 | 74 | it 'updates the data valueid item' do 75 | expect(valuemaps_mock).to receive(:update).with(update_data) 76 | end 77 | end 78 | 79 | context 'when id is not found' do 80 | before do 81 | allow(valuemaps_mock).to receive(:get_id).with(name: data[:name]) 82 | allow(valuemaps_mock).to receive(:create).with(data) 83 | end 84 | 85 | it 'creates a new valueid item' do 86 | expect(valuemaps_mock).to receive(:create).with(data) 87 | end 88 | end 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/hosts.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Hosts < Basic 3 | # The method name used for interacting with Hosts via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'host' 8 | end 9 | 10 | # The id field name used for identifying specific Host objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'host' 15 | end 16 | 17 | # Dump Host object data by key from Zabbix API 18 | # 19 | # @param data [Hash] Should include desired object's key and value 20 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 21 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 22 | # @return [Hash] 23 | def dump_by_id(data) 24 | log "[DEBUG] Call dump_by_id with parameters: #{data.inspect}" 25 | 26 | @client.api_request( 27 | method: 'host.get', 28 | params: { 29 | filter: { 30 | key.to_sym => data[key.to_sym] 31 | }, 32 | output: 'extend', 33 | selectHostGroups: 'extend' 34 | } 35 | ) 36 | end 37 | 38 | # The default options used when creating Host objects via Zabbix API 39 | # 40 | # @return [Hash] 41 | def default_options 42 | { 43 | host: nil, 44 | interfaces: [], 45 | status: 0, 46 | available: 1, 47 | groups: [] 48 | } 49 | end 50 | 51 | # Unlink/Remove Templates from Hosts using Zabbix API 52 | # 53 | # @param data [Hash] Should include hosts_id array and templates_id array 54 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 55 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 56 | # @return [Boolean] 57 | def unlink_templates(data) 58 | result = @client.api_request( 59 | method: 'host.massRemove', 60 | params: { 61 | hostids: data[:hosts_id], 62 | templates: data[:templates_id] 63 | } 64 | ) 65 | result.empty? ? false : true 66 | end 67 | 68 | # Create or update Host object using Zabbix API 69 | # 70 | # @param data [Hash] Needs to include host to properly identify Hosts via Zabbix API 71 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 72 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 73 | # @return [Integer] Zabbix object id 74 | def create_or_update(data) 75 | hostid = get_id(host: data[:host]) 76 | hostid ? update(data.merge(hostid: hostid)) : create(data) 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /spec/usergroup.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'usergroup' do 4 | context 'when not exists' do 5 | it 'should be integer id' do 6 | usergroupid = zbx.usergroups.create(name: gen_name('usergroup')) 7 | expect(usergroupid).to be_kind_of(Integer) 8 | end 9 | end 10 | 11 | context 'when exists' do 12 | before do 13 | @usergroup = gen_name 'usergroup' 14 | @usergroupid = zbx.usergroups.create(name: @usergroup) 15 | @user = gen_name 'user' 16 | @roleid = "1" 17 | @userid = zbx.users.create( 18 | alias: @user, 19 | name: @user, 20 | surname: @user, 21 | passwd: @user, 22 | usrgrps: [{usrgrpid: @usergroupid}], 23 | roleid: @roleid 24 | ) 25 | 26 | @usergroup2 = gen_name 'usergroup' 27 | @usergroupid2 = zbx.usergroups.create(name: @usergroup2) 28 | @user2 = gen_name 'user' 29 | @userid2 = zbx.users.create( 30 | alias: @user2, 31 | name: @user2, 32 | surname: @user2, 33 | passwd: @user2, 34 | usrgrps: [{usrgrpid: @usergroupid2}], 35 | roleid: @roleid 36 | ) 37 | end 38 | 39 | describe 'get_or_create' do 40 | it 'should return id' do 41 | expect(zbx.usergroups.get_or_create(name: @usergroup)).to eq @usergroupid 42 | end 43 | end 44 | 45 | describe 'add_user' do 46 | it 'should return id' do 47 | expect( 48 | zbx.usergroups.add_user( 49 | usrgrpids: [@usergroupid], 50 | userids: [@userid,@userid2] 51 | ) 52 | ).to eq @usergroupid 53 | end 54 | end 55 | 56 | describe 'update_users' do 57 | it 'should return id' do 58 | expect( 59 | zbx.usergroups.update_users( 60 | usrgrpids: [@usergroupid2], 61 | userids: [@userid2] 62 | ) 63 | ).to eq @usergroupid2 64 | end 65 | end 66 | 67 | describe 'set_permissions' do 68 | it 'should return id' do 69 | expect( 70 | zbx.usergroups.permissions( 71 | usrgrpid: @usergroupid, 72 | hostgroupids: zbx.hostgroups.all.values, 73 | permission: 3 74 | ) 75 | ).to eq @usergroupid 76 | end 77 | end 78 | 79 | describe 'delete' do 80 | it 'should raise error when has users with only one group' do 81 | expect { zbx.usergroups.delete(@usergroupid) }.to raise_error(ZabbixApi::ApiError) 82 | end 83 | 84 | it 'should return id of deleted group' do 85 | usergroupid = zbx.usergroups.create(name: gen_name('usergroup')) 86 | 87 | expect(zbx.usergroups.delete(usergroupid)).to eq usergroupid 88 | end 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/items.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Items < Basic 3 | # The method name used for interacting with Items via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'item' 8 | end 9 | 10 | # The id field name used for identifying specific Item objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # The default options used when creating Item objects via Zabbix API 18 | # 19 | # @return [Hash] 20 | def default_options 21 | { 22 | name: nil, 23 | key_: nil, 24 | hostid: nil, 25 | delay: 60, 26 | history: 3600, 27 | status: 0, 28 | type: 7, 29 | snmp_community: '', 30 | snmp_oid: '', 31 | value_type: 3, 32 | data_type: 0, 33 | trapper_hosts: 'localhost', 34 | snmp_port: 161, 35 | units: '', 36 | multiplier: 0, 37 | delta: 0, 38 | snmpv3_securityname: '', 39 | snmpv3_securitylevel: 0, 40 | snmpv3_authpassphrase: '', 41 | snmpv3_privpassphrase: '', 42 | formula: 0, 43 | trends: 86400, 44 | logtimefmt: '', 45 | valuemapid: 0, 46 | delay_flex: '', 47 | authtype: 0, 48 | username: '', 49 | password: '', 50 | publickey: '', 51 | privatekey: '', 52 | params: '', 53 | ipmi_sensor: '' 54 | } 55 | end 56 | 57 | # Get or Create Item object using Zabbix API 58 | # 59 | # @param data [Hash] Needs to include name and hostid to properly identify Items via Zabbix API 60 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 61 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 62 | # @return [Integer] Zabbix object id 63 | def get_or_create(data) 64 | log "[DEBUG] Call get_or_create with parameters: #{data.inspect}" 65 | 66 | unless (id = get_id(name: data[:name], hostid: data[:hostid])) 67 | id = create(data) 68 | end 69 | id 70 | end 71 | 72 | # Create or update Item object using Zabbix API 73 | # 74 | # @param data [Hash] Needs to include name and hostid to properly identify Items via Zabbix API 75 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 76 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 77 | # @return [Integer] Zabbix object id 78 | def create_or_update(data) 79 | itemid = get_id(name: data[:name], hostid: data[:hostid]) 80 | itemid ? update(data.merge(itemid: itemid)) : create(data) 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/usergroups.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Usergroups < Basic 3 | # The method name used for interacting with Usergroups via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'usergroup' 8 | end 9 | 10 | # The key field name used for Usergroup objects via Zabbix API 11 | # 12 | # @return [String] 13 | def key 14 | 'usrgrpid' 15 | end 16 | 17 | # The id field name used for identifying specific Usergroup objects via Zabbix API 18 | # 19 | # @return [String] 20 | def identify 21 | 'name' 22 | end 23 | 24 | # Set permissions for usergroup using Zabbix API 25 | # 26 | # @param data [Hash] Needs to include usrgrpids and hostgroupids along with permissions to set 27 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 28 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 29 | # @return [Integer] Zabbix object id (usergroup) 30 | def permissions(data) 31 | permission = data[:permission] || 2 32 | result = @client.api_request( 33 | method: 'usergroup.update', 34 | params: { 35 | usrgrpid: data[:usrgrpid], 36 | rights: data[:hostgroupids].map { |t| { permission: permission, id: t } } 37 | } 38 | ) 39 | result ? result['usrgrpids'][0].to_i : nil 40 | end 41 | 42 | # Add users to usergroup using Zabbix API 43 | # 44 | # @deprecated Zabbix has removed massAdd in favor of update. 45 | # @param data [Hash] Needs to include userids and usrgrpids to mass add users to groups 46 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 47 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 48 | # @return [Integer] Zabbix object id (usergroup) 49 | def add_user(data) 50 | update_users(data) 51 | end 52 | 53 | # Update users in usergroups using Zabbix API 54 | # 55 | # @param data [Hash] Needs to include userids and usrgrpids to mass update users in groups 56 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 57 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 58 | # @return [Integer] Zabbix object id (usergroup) 59 | def update_users(data) 60 | user_groups = data[:usrgrpids].map do |t| 61 | { 62 | usrgrpid: t, 63 | userids: data[:userids], 64 | } 65 | end 66 | result = @client.api_request( 67 | method: 'usergroup.update', 68 | params: user_groups, 69 | ) 70 | result ? result['usrgrpids'][0].to_i : nil 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/proxies_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Proxies' do 4 | let(:proxies_mock) { ZabbixApi::Proxies.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { proxies_mock.method_name } 9 | 10 | it { is_expected.to eq 'proxy' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { proxies_mock.identify } 15 | 16 | it { is_expected.to eq 'host' } 17 | end 18 | 19 | describe '.delete' do 20 | subject { proxies_mock.delete(data) } 21 | 22 | let(:data) { { testidentify: 222 } } 23 | let(:result) { { 'proxyids' => ['1'] } } 24 | let(:identify) { 'testidentify' } 25 | let(:method_name) { 'testmethod' } 26 | 27 | before do 28 | allow(proxies_mock).to receive(:log) 29 | allow(proxies_mock).to receive(:identify).and_return(identify) 30 | allow(proxies_mock).to receive(:method_name).and_return(method_name) 31 | allow(client).to receive(:api_request).with( 32 | method: 'proxy.delete', 33 | params: data 34 | ).and_return(result) 35 | end 36 | 37 | context 'when result is not empty' do 38 | it 'returns the id of first proxy' do 39 | expect(subject).to eq 1 40 | end 41 | end 42 | 43 | context 'when result is empty' do 44 | let(:result) { [] } 45 | 46 | it { is_expected.to be_nil } 47 | end 48 | end 49 | 50 | describe '.isreadable' do 51 | subject { proxies_mock.isreadable(data) } 52 | 53 | let(:data) { { testidentify: 222 } } 54 | let(:result) { true } 55 | let(:identify) { 'testidentify' } 56 | let(:method_name) { 'testmethod' } 57 | 58 | before do 59 | allow(proxies_mock).to receive(:log) 60 | allow(proxies_mock).to receive(:identify).and_return(identify) 61 | allow(proxies_mock).to receive(:method_name).and_return(method_name) 62 | allow(client).to receive(:api_request).with( 63 | method: 'proxy.isreadable', 64 | params: data 65 | ).and_return(result) 66 | end 67 | 68 | it { is_expected.to be(true).or be(false) } 69 | end 70 | 71 | describe '.iswritable' do 72 | subject { proxies_mock.iswritable(data) } 73 | 74 | let(:data) { { testidentify: 222 } } 75 | let(:result) { true } 76 | let(:identify) { 'testidentify' } 77 | let(:method_name) { 'testmethod' } 78 | 79 | before do 80 | allow(proxies_mock).to receive(:log) 81 | allow(proxies_mock).to receive(:identify).and_return(identify) 82 | allow(proxies_mock).to receive(:method_name).and_return(method_name) 83 | allow(client).to receive(:api_request).with( 84 | method: 'proxy.iswritable', 85 | params: data 86 | ).and_return(result) 87 | end 88 | 89 | it { is_expected.to be(true).or be(false) } 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/users_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Users' do 4 | let(:users_mock) { ZabbixApi::Users.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { users_mock.method_name } 9 | 10 | it { is_expected.to eq 'user' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { users_mock.identify } 15 | 16 | it { is_expected.to eq 'alias' } 17 | end 18 | 19 | describe '.key' do 20 | subject { users_mock.key } 21 | 22 | it { is_expected.to eq 'userid' } 23 | end 24 | 25 | describe '.keys' do 26 | subject { users_mock.keys } 27 | 28 | it { is_expected.to eq 'userids' } 29 | end 30 | 31 | describe '.medias_helper' do 32 | subject { users_mock.medias_helper(data, action) } 33 | 34 | let(:data) { { userids: [1234, 5678], media: 'testmedia'} } 35 | #let(:result) { { 'mediaids' => ['111'], 'testidentify' => 1 } } 36 | let(:result) { { 'userids' => ['111'] } } 37 | let(:action) { 'updateMedia' } 38 | 39 | before do 40 | users = data[:userids].map do |t| 41 | { 42 | userid: t, 43 | user_medias: data[:media], 44 | } 45 | end 46 | allow(client).to receive(:api_request).with( 47 | method: "user.#{action}", 48 | params: users 49 | ).and_return(result) 50 | end 51 | 52 | context 'when api_request returns nil result' do 53 | let(:result) { nil } 54 | 55 | it { is_expected.to be_nil } 56 | end 57 | 58 | context 'when api_request does not return empty result' do 59 | it 'returns first mediaid' do 60 | expect(subject).to eq 111 61 | end 62 | end 63 | end 64 | 65 | describe '.add_medias' do 66 | subject { users_mock.add_medias(data) } 67 | 68 | let(:data) { { userids: [1234, 5678], media: 'testmedia' } } 69 | let(:result) { { 'userids' => ['111'], 'testidentify' => 1 } } 70 | 71 | before do 72 | allow(users_mock).to receive(:medias_helper) 73 | end 74 | 75 | it 'calls medias_helper' do 76 | expect(users_mock).to receive(:medias_helper).with( 77 | data, 78 | 'update' 79 | ) 80 | subject 81 | end 82 | end 83 | 84 | describe '.update_medias' do 85 | subject { users_mock.update_medias(data) } 86 | 87 | let(:data) { { userids: [1234, 5678], media: 'testmedia' } } 88 | let(:result) { { 'userids' => ['111'], 'testidentify' => 1 } } 89 | 90 | before do 91 | allow(users_mock).to receive(:medias_helper) 92 | end 93 | 94 | it 'calls medias_helper' do 95 | expect(users_mock).to receive(:medias_helper).with( 96 | data, 97 | 'update' 98 | ) 99 | subject 100 | end 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /spec/trigger.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'trigger' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 7 | @template = gen_name 'template' 8 | @templateid = zbx.templates.create( 9 | host: @template, 10 | groups: [groupid: @hostgroupid] 11 | ) 12 | @application = gen_name 'application' 13 | @applicationid = zbx.applications.create( 14 | name: @application, 15 | hostid: @templateid 16 | ) 17 | @item = gen_name 'item' 18 | @proc = "proc.num[#{gen_name 'proc'}]" 19 | @itemid = zbx.items.create( 20 | name: @item, 21 | key_: @proc, 22 | status: 0, 23 | hostid: @templateid, 24 | applications: [@applicationid] 25 | ) 26 | end 27 | 28 | context 'when name not exists' do 29 | describe 'create' do 30 | it 'should return integer id' do 31 | @trigger = gen_name 'trigger' 32 | triggerid = zbx.triggers.create( 33 | description: @trigger, 34 | expression: "{#{@template}:#{@proc}.last(0)}<1", 35 | comments: 'Bla-bla is faulty (disaster)', 36 | priority: 5, 37 | status: 0, 38 | type: 0, 39 | tags: [ 40 | { 41 | tag: 'proc', 42 | value: @proc.to_s 43 | }, 44 | { 45 | tag: 'error', 46 | value: '' 47 | } 48 | ] 49 | ) 50 | expect(triggerid).to be_kind_of(Integer) 51 | end 52 | end 53 | end 54 | 55 | context 'when name exists' do 56 | before :all do 57 | @trigger = gen_name 'trigger' 58 | @triggerid = zbx.triggers.create( 59 | description: @trigger, 60 | expression: "{#{@template}:#{@proc}.last(0)}<1", 61 | comments: 'Bla-bla is faulty (disaster)', 62 | priority: 5, 63 | status: 0, 64 | type: 0, 65 | tags: [ 66 | { 67 | tag: 'proc', 68 | value: @proc.to_s 69 | }, 70 | { 71 | tag: 'error', 72 | value: '' 73 | } 74 | ] 75 | ) 76 | end 77 | 78 | describe 'get_id' do 79 | it 'should return id' do 80 | expect(zbx.triggers.get_id(description: @trigger)).to eq @triggerid 81 | end 82 | end 83 | 84 | describe 'create_or_update' do 85 | it 'should return id of updated trigger' do 86 | expect( 87 | zbx.triggers.create_or_update( 88 | description: @trigger, 89 | hostid: @templateid 90 | ) 91 | ).to eq @triggerid 92 | end 93 | end 94 | 95 | describe 'delete' do 96 | it 'should return id' do 97 | expect(zbx.triggers.delete(@triggerid)).to eq @triggerid 98 | end 99 | end 100 | end 101 | end 102 | -------------------------------------------------------------------------------- /lib/zabbixapi/basic/basic_func.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Basic 3 | # Log messages to stdout when debugging 4 | # 5 | # @param message [String] 6 | def log(message) 7 | puts message.to_s if @client.options[:debug] 8 | end 9 | 10 | # Compare two hashes for equality 11 | # 12 | # @param first_hash [Hash] 13 | # @param second_hash [Hash] 14 | # @return [Boolean] 15 | def hash_equals?(first_hash, second_hash) 16 | normalized_first_hash = normalize_hash(first_hash) 17 | normalized_second_hash = normalize_hash(second_hash) 18 | 19 | hash1 = normalized_first_hash.merge(normalized_second_hash) 20 | hash2 = normalized_second_hash.merge(normalized_first_hash) 21 | hash1 == hash2 22 | end 23 | 24 | # Convert all hash/array keys to symbols 25 | # 26 | # @param object [Array, Hash] 27 | # @return [Array, Hash] 28 | def symbolize_keys(object) 29 | if object.is_a?(Array) 30 | object.each_with_index do |val, index| 31 | object[index] = symbolize_keys(val) 32 | end 33 | elsif object.is_a?(Hash) 34 | object.keys.each do |key| 35 | object[key.to_sym] = symbolize_keys(object.delete(key)) 36 | end 37 | end 38 | object 39 | end 40 | 41 | # Normalize all hash values to strings 42 | # 43 | # @param hash [Hash] 44 | # @return [Hash] 45 | def normalize_hash(hash) 46 | result = hash.dup 47 | 48 | result.delete(:hostid) # TODO: remove to logig. TemplateID and HostID has different id 49 | 50 | result.each do |key, value| 51 | result[key] = value.is_a?(Array) ? normalize_array(value) : value.to_s 52 | end 53 | 54 | result 55 | end 56 | 57 | # Normalize all array values to strings 58 | # 59 | # @param array [Array] 60 | # @return [Array] 61 | def normalize_array(array) 62 | result = [] 63 | 64 | array.each do |e| 65 | if e.is_a?(Array) 66 | result.push(normalize_array(e)) 67 | elsif e.is_a?(Hash) 68 | result.push(normalize_hash(e)) 69 | else 70 | result.push(e.to_s) 71 | end 72 | end 73 | 74 | result 75 | end 76 | 77 | # Parse a data hash for id key or boolean to return 78 | # 79 | # @param data [Hash] 80 | # @return [Integer] The object id if a single object hash is provided with key 81 | # @return [Boolean] True/False if multiple class object hash is provided 82 | def parse_keys(data) 83 | case data 84 | when Hash 85 | data.empty? ? nil : data[keys][0].to_i 86 | when TrueClass 87 | true 88 | when FalseClass 89 | false 90 | end 91 | end 92 | 93 | # Merge two hashes into a single new hash 94 | # 95 | # @param first_hash [Hash] 96 | # @param second_hash [Hash] 97 | # @return [Hash] 98 | def merge_params(first_hash, second_hash) 99 | new = first_hash.dup 100 | new.merge(second_hash) 101 | end 102 | end 103 | end 104 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/roles_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Roles' do 4 | let(:roles_mock) { ZabbixApi::Roles.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { roles_mock.method_name } 9 | 10 | it { is_expected.to eq 'role' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { roles_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.key' do 20 | subject { roles_mock.key } 21 | 22 | it { is_expected.to eq 'roleid' } 23 | end 24 | 25 | describe '.keys' do 26 | subject { roles_mock.keys } 27 | 28 | it { is_expected.to eq 'roleids' } 29 | end 30 | 31 | # TODO: fix Roles Spec tests 32 | # describe '.add_role' do 33 | # subject { roles_mock.add_role(data) } 34 | 35 | # let(:data) { { userids: [123, 111], usrgrpids: [4, 5] } } 36 | # let(:result) { { 'usrgrpids' => [9090] } } 37 | # let(:key) { 'testkey' } 38 | # let(:permission) { 3 } 39 | 40 | # before do 41 | # roles = data[:usrgrpids].map do |t| 42 | # { 43 | # userids: data[:userids], 44 | # usrgrpid: t, 45 | # } 46 | # end 47 | # allow(roles_mock).to receive(:log) 48 | # allow(roles_mock).to receive(:key).and_return(key) 49 | # allow(client).to receive(:api_request).with( 50 | # method: 'usergroup.update', 51 | # params: user_groups 52 | # ).and_return(result) 53 | # end 54 | 55 | # context 'when returns result with roles' do 56 | # it 'returns first roleid' do 57 | # expect(subject).to eq 9090 58 | # end 59 | # end 60 | 61 | # context 'when api returns nil result' do 62 | # let(:result) { nil } 63 | 64 | # it 'returns nil' do 65 | # expect(subject).to be_nil 66 | # end 67 | # end 68 | # end 69 | 70 | # describe '.update_roles' do 71 | # subject { roles_mock.update_users(data) } 72 | 73 | # let(:data) { { userids: [123, 111], usrgrpids: [4, 5] } } 74 | # let(:result) { { 'roleids' => [9090] } } 75 | # let(:key) { 'testkey' } 76 | # let(:permission) { 3 } 77 | 78 | # before do 79 | # roles = data[:roleids].map do |t| 80 | # { 81 | # userids: data[:userids], 82 | # usrgrpid: t, 83 | # } 84 | # end 85 | # allow(roles_mock).to receive(:log) 86 | # allow(roles_mock).to receive(:key).and_return(key) 87 | # allow(client).to receive(:api_request).with( 88 | # method: 'usergroup.update', 89 | # params: roles, 90 | # ).and_return(result) 91 | # end 92 | 93 | # context 'when returns result with roles' do 94 | # it 'returns first roleid' do 95 | # expect(subject).to eq 9090 96 | # end 97 | # end 98 | 99 | # context 'when api returns nil result' do 100 | # let(:result) { nil } 101 | 102 | # it 'returns nil' do 103 | # expect(subject).to be_nil 104 | # end 105 | # end 106 | # end 107 | end 108 | -------------------------------------------------------------------------------- /examples/Hosts.md: -------------------------------------------------------------------------------- 1 | # Hosts 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Hosts: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/host](https://www.zabbix.com/documentation/4.0/manual/api/reference/host) 7 | 8 | ## Create Host 9 | ```ruby 10 | zbx.hosts.create( 11 | :host => host.fqdn, 12 | :interfaces => [ 13 | { 14 | :type => 1, 15 | :main => 1, 16 | :ip => '10.0.0.1', 17 | :dns => 'server.example.org', 18 | :port => 10050, 19 | :useip => 0 20 | } 21 | ], 22 | :groups => [ :groupid => zbx.hostgroups.get_id(:name => "hostgroup") ] 23 | ) 24 | 25 | #or use: 26 | zbx.hosts.create_or_update( 27 | :host => host.fqdn, 28 | :interfaces => [ 29 | { 30 | :type => 1, 31 | :main => 1, 32 | :ip => '10.0.0.1', 33 | :dns => 'server.example.org', 34 | :port => 10050, 35 | :useip => 0 36 | } 37 | ], 38 | :groups => [ :groupid => zbx.hostgroups.get_id(:name => "hostgroup") ] 39 | ) 40 | ``` 41 | 42 | ## Add SNMP Bulk Hosts 43 | hosts = [ 44 | { :group=>"Discovered Hosts", :hostname=>"zabbix", :ip => "127.0.0.1", :community_string=>"public", :template=>"123" }, 45 | { :group=>"Discovered Hosts", :hostname=>"zabbix", :ip => "127.0.0.1", :community_string=>"public", :template=>"123" } 46 | ] 47 | 48 | hosts.each do |h| 49 | zbx.hosts.create_or_update( 50 | :host => h[:hostname], 51 | :interfaces => [ 52 | { 53 | :type => 2, 54 | :main => 1, 55 | :useip => 1, 56 | :ip => h[:ip], 57 | :dns => "", 58 | :port => 161, 59 | :details => { 60 | :version => 2, 61 | :community => "{$SNMP_COMMUNITY}" 62 | } 63 | } 64 | ], 65 | :groups => [ :groupid => zbx.hostgroups.get_id(:name => h[:group]) ], 66 | :templates => [ 67 | { 68 | :templateid => h[:template] 69 | } 70 | ], 71 | :inventory_mode => 1, 72 | :macros => [ 73 | { 74 | :macro => "{$SNMP_COMMUNITY}", 75 | :value => h[:community_string] 76 | } 77 | ] 78 | ) 79 | end 80 | 81 | ## Update Host 82 | ```ruby 83 | zbx.hosts.update( 84 | :hostid => zbx.hosts.get_id(:host => "hostname"), 85 | :status => 0 86 | ) 87 | 88 | #You can check host: 89 | puts zbx.hosts.get_full_data(:host => "hostname") 90 | 91 | # Zabbixapi checks that new object differ from one in zabbix. But if you 92 | # want to update nested arguments (like interfaces), you should use second argument. 93 | # For example: 94 | 95 | zbx.hosts.update({ 96 | :hostid => zbx.hosts.get_id(:host => "hostname"), 97 | :interfaces => [ 98 | { 99 | :type => 1, 100 | :main => 1, 101 | :ip => '10.0.0.1', 102 | :dns => 'server.example.org', 103 | :port => 10050, 104 | :useip => 0 105 | } 106 | ]}, true) 107 | ``` 108 | 109 | 110 | ## Get Host by id (See URL) 111 | ```ruby 112 | zbx.hosts.dump_by_id(:hostid => get_id(:host => "hostname")) 113 | ``` 114 | 115 | ## Delete Host 116 | ```ruby 117 | zbx.hosts.delete zbx.hosts.get_id(:host => "hostname") 118 | ``` 119 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/httptests_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::HttpTests' do 4 | let(:httptests_mock) { ZabbixApi::HttpTests.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { httptests_mock.method_name } 9 | 10 | it { is_expected.to eq 'httptest' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { httptests_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.default_options' do 20 | subject { httptests_mock.default_options } 21 | 22 | let(:result) do 23 | { 24 | hostid: nil, 25 | name: nil, 26 | steps: [] 27 | } 28 | end 29 | 30 | it { is_expected.to eq result } 31 | end 32 | 33 | describe '.get_or_create' do 34 | subject { httptests_mock.get_or_create(data) } 35 | 36 | let(:data) { { name: 'batman', hostid: 1234 } } 37 | let(:result) { [{ 'testkey' => '111', 'testidentify' => 1 }] } 38 | let(:id) { nil } 39 | let(:id_through_create) { 222 } 40 | 41 | before do 42 | allow(httptests_mock).to receive(:log) 43 | allow(httptests_mock).to receive(:get_id).with(name: data[:name], hostid: data[:hostid]).and_return(id) 44 | allow(httptests_mock).to receive(:create).with(data).and_return(id_through_create) 45 | end 46 | 47 | it 'logs the debug message' do 48 | expect(httptests_mock).to receive(:log).with("[DEBUG] Call get_or_create with parameters: #{data.inspect}") 49 | subject 50 | end 51 | 52 | context 'when ID already exist' do 53 | let(:id) { '111' } 54 | 55 | it 'returns the existing ID' do 56 | expect(subject).to eq id 57 | end 58 | end 59 | 60 | context 'when id does not exist' do 61 | it 'returns the newly created ID' do 62 | expect(subject).to eq id_through_create 63 | end 64 | end 65 | end 66 | 67 | describe '.create_or_update' do 68 | subject { httptests_mock.create_or_update(data) } 69 | 70 | let(:data) { { name: 'batman', hostid: 111 } } 71 | let(:result) { [{ 'testkey' => '111', 'testidentify' => 1 }] } 72 | let(:key) { 'testkey' } 73 | let(:identify) { 'testidentify' } 74 | let(:httptestid) { nil } 75 | let(:id_through_create) { 222 } 76 | let(:update_data) { { name: data[:name], hostid: data[:hostid], httptestid: httptestid } } 77 | 78 | before do 79 | allow(httptests_mock).to receive(:log) 80 | allow(httptests_mock).to receive(:identify).and_return(identify) 81 | allow(httptests_mock).to receive(:get_id) 82 | .with(name: data[:name], hostid: data[:hostid]).and_return(httptestid) 83 | allow(httptests_mock).to receive(:create).with(data).and_return(id_through_create) 84 | allow(httptests_mock).to receive(:update).with(update_data).and_return(httptestid) 85 | end 86 | 87 | context 'when Host ID already exist' do 88 | let(:httptestid) { 1234 } 89 | 90 | it 'updates an object returns the Host ID' do 91 | expect(subject).to eq httptestid 92 | end 93 | end 94 | 95 | context 'when Host ID does not exist' do 96 | it 'creates an object returns the newly created object ID' do 97 | expect(subject).to eq id_through_create 98 | end 99 | end 100 | end 101 | end 102 | -------------------------------------------------------------------------------- /spec/user.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'user' do 4 | before :all do 5 | @usergroup = gen_name 'usergroup' 6 | @usergroupid = { 7 | usrgrpid: zbx.usergroups.create(name: @usergroup), 8 | } 9 | @roleid = "1" 10 | puts "USERGROUPID: #{@usergroupid}" 11 | 12 | @mediatype = gen_name 'mediatype' 13 | @mediatypeid = zbx.mediatypes.create( 14 | name: @mediatype, 15 | type: 0, 16 | smtp_server: '127.0.0.1', 17 | smtp_email: 'zabbix@test.com', 18 | smtp_helo: 'test.com' 19 | ) 20 | end 21 | 22 | def media 23 | { 24 | mediatypeid: @mediatypeid, 25 | sendto: ['test@test.com'], 26 | active: 0, 27 | period: '1-7,00:00-24:00', 28 | severity: '56' 29 | } 30 | end 31 | 32 | context 'when not exists' do 33 | describe 'create' do 34 | it 'should return integer id' do 35 | user = gen_name 'user' 36 | userid = zbx.users.create( 37 | alias: user, 38 | name: user, 39 | surname: user, 40 | passwd: user, 41 | roleid: @roleid, 42 | usrgrps: [@usergroupid] 43 | ) 44 | expect(userid).to be_kind_of(Integer) 45 | end 46 | end 47 | 48 | describe 'get_id' do 49 | it 'should return nil' do 50 | expect(zbx.users.get_id(alias: 'name_____')).to be_nil 51 | end 52 | end 53 | end 54 | 55 | context 'when exists' do 56 | before :all do 57 | @user = gen_name 'user' 58 | @userid = zbx.users.create( 59 | alias: @user, 60 | name: @user, 61 | surname: @user, 62 | passwd: @user, 63 | usrgrps: [@usergroupid], 64 | roleid: @roleid 65 | ) 66 | end 67 | 68 | describe 'create_or_update' do 69 | it 'should return id' do 70 | expect( 71 | zbx.users.create_or_update( 72 | alias: @user, 73 | name: @user, 74 | surname: @user, 75 | passwd: @user, 76 | roleid: @roleid 77 | ) 78 | ).to eq @userid 79 | end 80 | end 81 | 82 | describe 'get_full_data' do 83 | it 'should return string name' do 84 | expect(zbx.users.get_full_data(alias: @user)[0]['name']).to be_kind_of(String) 85 | end 86 | end 87 | 88 | describe 'update' do 89 | it 'should return id' do 90 | expect(zbx.users.update(userid: @userid, name: gen_name('user'))).to eq @userid 91 | end 92 | end 93 | 94 | describe 'update by adding media' do 95 | it 'should return id' do 96 | expect( 97 | zbx.users.add_medias( 98 | userids: [@userid], 99 | media: [media] 100 | ) 101 | ).to be_kind_of(Integer) 102 | end 103 | end 104 | 105 | describe 'update_medias' do 106 | it 'should return the user id' do 107 | # Call twice to ensure update_medias first successfully creates the media, then updates it 108 | 2.times do 109 | returned_userid = zbx.users.update_medias( 110 | userids: [@userid], 111 | media: [media] 112 | ) 113 | 114 | expect(returned_userid).to eq @userid 115 | end 116 | end 117 | end 118 | 119 | describe 'delete' do 120 | it 'should return id' do 121 | expect(zbx.users.delete(@userid)).to eq @userid 122 | end 123 | end 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/screens.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Screens < Basic 3 | # extracted from frontends/php/include/defines.inc.php 4 | # SCREEN_RESOURCE_GRAPH => 0, 5 | # SCREEN_RESOURCE_SIMPLE_GRAPH => 1, 6 | # SCREEN_RESOURCE_MAP => 2, 7 | # SCREEN_RESOURCE_PLAIN_TEXT => 3, 8 | # SCREEN_RESOURCE_HOSTS_INFO => 4, 9 | # SCREEN_RESOURCE_TRIGGERS_INFO => 5, 10 | # SCREEN_RESOURCE_SERVER_INFO => 6, 11 | # SCREEN_RESOURCE_CLOCK => 7, 12 | # SCREEN_RESOURCE_SCREEN => 8, 13 | # SCREEN_RESOURCE_TRIGGERS_OVERVIEW => 9, 14 | # SCREEN_RESOURCE_DATA_OVERVIEW => 10, 15 | # SCREEN_RESOURCE_URL => 11, 16 | # SCREEN_RESOURCE_ACTIONS => 12, 17 | # SCREEN_RESOURCE_EVENTS => 13, 18 | # SCREEN_RESOURCE_HOSTGROUP_TRIGGERS => 14, 19 | # SCREEN_RESOURCE_SYSTEM_STATUS => 15, 20 | # SCREEN_RESOURCE_HOST_TRIGGERS => 16 21 | 22 | # The method name used for interacting with Screens via Zabbix API 23 | # 24 | # @return [String] 25 | def method_name 26 | 'screen' 27 | end 28 | 29 | # The id field name used for identifying specific Screen objects via Zabbix API 30 | # 31 | # @return [String] 32 | def identify 33 | 'name' 34 | end 35 | 36 | # Delete Screen object using Zabbix API 37 | # 38 | # @param data [String, Array] Should include id's of the screens to delete 39 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 40 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 41 | # @return [Integer] Zabbix object id 42 | def delete(data) 43 | result = @client.api_request(method: 'screen.delete', params: [data]) 44 | result.empty? ? nil : result['screenids'][0].to_i 45 | end 46 | 47 | # Get or Create Screen object for Host using Zabbix API 48 | # 49 | # @param data [Hash] Needs to include screen_name and graphids to properly identify Screens via Zabbix API 50 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 51 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 52 | # @return [Integer] Zabbix object id 53 | def get_or_create_for_host(data) 54 | screen_name = data[:screen_name] 55 | graphids = data[:graphids] 56 | screenitems = [] 57 | hsize = data[:hsize] || 3 58 | valign = data[:valign] || 2 59 | halign = data[:halign] || 2 60 | rowspan = data[:rowspan] || 1 61 | colspan = data[:colspan] || 1 62 | height = data[:height] || 320 # default 320 63 | width = data[:width] || 200 # default 200 64 | vsize = data[:vsize] || [1, (graphids.size / hsize).to_i].max 65 | screenid = get_id(name: screen_name) 66 | 67 | unless screenid 68 | # Create screen 69 | graphids.each_with_index do |graphid, index| 70 | screenitems << { 71 | resourcetype: 0, 72 | resourceid: graphid, 73 | x: (index % hsize).to_i, 74 | y: (index % graphids.size / hsize).to_i, 75 | valign: valign, 76 | halign: halign, 77 | rowspan: rowspan, 78 | colspan: colspan, 79 | height: height, 80 | width: width 81 | } 82 | end 83 | 84 | screenid = create( 85 | name: screen_name, 86 | hsize: hsize, 87 | vsize: vsize, 88 | screenitems: screenitems 89 | ) 90 | end 91 | screenid 92 | end 93 | end 94 | end 95 | -------------------------------------------------------------------------------- /examples/Configurations.md: -------------------------------------------------------------------------------- 1 | # Configurations 2 | 3 | This example assumes you have already initialized and connected the ZabbixApi. 4 | 5 | For more information and available properties please refer to the Zabbix API documentation for Configurations: 6 | [https://www.zabbix.com/documentation/4.0/manual/api/reference/configuration](https://www.zabbix.com/documentation/4.0/manual/api/reference/configuration) 7 | 8 | ## Export Configuration 9 | 10 | ```ruby 11 | zbx.configurations.export( 12 | :format => "xml", 13 | :options => { 14 | :templates => [zbx.templates.get_id(:host => "template")] 15 | } 16 | ) 17 | ``` 18 | 19 | ## Import Configuration 20 | 21 | ```ruby 22 | zbx.configurations.import( 23 | :format => "xml", 24 | :rules => { 25 | :templates => { 26 | :createMissing => true, 27 | :updateExisting => true 28 | }, 29 | :items => { 30 | :createMissing => true, 31 | :updateExisting => true 32 | } 33 | }, 34 | :source => "2.02012-04-18T11:20:14ZZabbix serversExport hostExport host00-12Zabbix servers111127.0.0.110050if1ApplicationItem00item.key309036503001000Applicationif1{Export host:item.key.last(0)}=0Trigger02Host trigger0Graph9002000.0000100.0000110100.00000.0000000000C80000070Export hostitem.key" 35 | ) 36 | ``` 37 | -------------------------------------------------------------------------------- /spec/configuration.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'configuration' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroup_id = zbx.hostgroups.create(name: @hostgroup) 7 | @template = gen_name 'template' 8 | @template_id = zbx.templates.create( 9 | host: @template, 10 | groups: [groupid: @hostgroup_id] 11 | ) 12 | @source = zbx.configurations.export( 13 | format: 'xml', 14 | options: { 15 | templates: [@template_id] 16 | } 17 | ) 18 | @item = gen_name 'item' 19 | @item_id = zbx.items.create( 20 | name: @item, 21 | description: 'item', 22 | key_: 'proc.num[aaa]', 23 | type: 0, 24 | value_type: 3, 25 | hostid: zbx.templates.get_id(host: @template) 26 | ) 27 | end 28 | 29 | after :all do 30 | zbx.items.delete(zbx.items.get_id(name: @item)) 31 | zbx.templates.delete(zbx.templates.get_id(host: @template)) 32 | zbx.hostgroups.delete(zbx.hostgroups.get_id(name: @hostgroup)) 33 | end 34 | 35 | context 'when object not exists' do 36 | describe 'import with createMissing' do 37 | before do 38 | zbx.items.delete(@item_id) 39 | zbx.templates.delete(@template_id) 40 | zbx.hostgroups.delete(@hostgroup_id) 41 | zbx.configurations.import( 42 | format: 'xml', 43 | rules: { 44 | groups: { 45 | createMissing: true 46 | }, 47 | templates: { 48 | createMissing: true 49 | } 50 | }, 51 | source: @source 52 | ) 53 | end 54 | 55 | it 'should create object' do 56 | expect(zbx.hostgroups.get_id(name: @hostgroup)).to be_kind_of(Integer) 57 | expect(zbx.templates.get_id(host: @template)).to be_kind_of(Integer) 58 | end 59 | end 60 | end 61 | 62 | context 'when object exists' do 63 | describe 'export' do 64 | before do 65 | zbx.items.create( 66 | name: @item, 67 | description: 'item', 68 | key_: 'proc.num[aaa]', 69 | type: 0, 70 | value_type: 3, 71 | hostid: zbx.templates.get_id(host: @template) 72 | ) 73 | end 74 | 75 | it 'should export updated object' do 76 | expect( 77 | zbx.configurations.export( 78 | format: 'xml', 79 | options: { 80 | templates: [zbx.templates.get_id(host: @template)] 81 | } 82 | ) 83 | ).to match(/#{@item}/) 84 | end 85 | end 86 | 87 | describe 'import with updateExisting' do 88 | before do 89 | @source_updated = zbx.configurations.export( 90 | format: 'xml', 91 | options: { 92 | templates: [zbx.templates.get_id(host: @template)] 93 | } 94 | ) 95 | zbx.items.delete(zbx.items.get_id(name: @item)) 96 | zbx.configurations.import( 97 | format: 'xml', 98 | rules: { 99 | templates: { 100 | updateExisting: true 101 | }, 102 | items: { 103 | createMissing: true 104 | } 105 | }, 106 | source: @source_updated 107 | ) 108 | end 109 | 110 | it 'should update object' do 111 | expect( 112 | zbx.configurations.export( 113 | format: 'xml', 114 | options: { 115 | templates: [zbx.templates.get_id(host: @template)] 116 | } 117 | ) 118 | ).to match(/#{@item}/) 119 | end 120 | end 121 | end 122 | end 123 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/problems.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Problems < Basic 3 | # The method name used for interacting with Hosts via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'problem' 8 | end 9 | 10 | # The id field name used for identifying specific Problem objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # The key field name used for Problem objects via Zabbix API 18 | # However, Problem object does not have a unique identifier 19 | # 20 | # @return [String] 21 | def key 22 | 'problemid' 23 | end 24 | 25 | # Returns the object's plural id field name (identify) based on key 26 | # However, Problem object does not have a unique identifier 27 | # 28 | # @return [String] 29 | def keys 30 | 'problemids' 31 | end 32 | 33 | # Dump Problem object data by key from Zabbix API 34 | # 35 | # @param data [Hash] Should include desired object's key and value 36 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 37 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 38 | # @return [Hash] 39 | def dump_by_id(data) 40 | log "[DEBUG] Call dump_by_id with parameters: #{data.inspect}" 41 | 42 | @client.api_request( 43 | method: 'problem.get', 44 | params: { 45 | filter: { 46 | identify.to_sym => data[identify.to_sym] 47 | }, 48 | output: 'extend' 49 | } 50 | ) 51 | end 52 | 53 | # Get full/extended Problem data from Zabbix API 54 | # 55 | # @param data [Hash] Should include object's id field name (identify) and id value 56 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 57 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 58 | # @return [Hash] 59 | def get_full_data(data) 60 | log "[DEBUG] Call get_full_data with parameters: #{data.inspect}" 61 | 62 | data = symbolize_keys(data) 63 | 64 | @client.api_request( 65 | method: "#{method_name}.get", 66 | params: { 67 | filter: { 68 | identify.to_sym => data[identify.to_sym] 69 | }, 70 | eventids: data[:eventids] || nil, 71 | groupids: data[:groupids] || nil, 72 | hostids: data[:hostids] || nil, 73 | objectids: data[:objectids] || nil, 74 | applicationids: data[:applicationids] || nil, 75 | tags: data[:tags] || nil, 76 | time_from: data[:time_from] || nil, 77 | time_till: data[:time_till] || nil, 78 | eventid_from: data[:eventid_from] || nil, 79 | eventid_till: data[:eventid_till] || nil, 80 | recent: data[:recent] || false, 81 | sortfield: data[:sortfield] || ['eventid'], 82 | sortorder: data[:sortorder] || 'DESC', 83 | countOutput: data[:countOutput] || nil, 84 | output: 'extend', 85 | selectAcknowledges: 'extend', 86 | selectTags: 'extend', 87 | selectSuppressionData: 'extend' 88 | } 89 | ) 90 | end 91 | 92 | # Get full/extended Zabbix data for Problem objects from API 93 | # 94 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 95 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 96 | # @return [Array] Array of matching objects 97 | def all 98 | get_full_data({}) 99 | end 100 | end 101 | end 102 | -------------------------------------------------------------------------------- /spec/script.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'script' do 4 | before :all do 5 | @hostid = zbx.hosts.get_id(host: 'Zabbix server') 6 | end 7 | 8 | context 'when name not exists' do 9 | before do 10 | @script = gen_name 'script' 11 | end 12 | 13 | describe 'create' do 14 | it 'should return integer id' do 15 | scriptid = zbx.scripts.create( 16 | name: @script, 17 | command: 'hostname' 18 | ) 19 | expect(scriptid).to be_kind_of(Integer) 20 | end 21 | end 22 | 23 | describe 'get_id' do 24 | it 'should return nil' do 25 | expect(zbx.scripts.get_id(name: @script)).to be_kind_of(NilClass) 26 | end 27 | end 28 | end 29 | 30 | context 'when name exists' do 31 | before :all do 32 | @script = gen_name 'script' 33 | @scriptid = zbx.scripts.create( 34 | name: @script, 35 | command: 'hostname' 36 | ) 37 | end 38 | 39 | describe 'get_or_create' do 40 | it 'should return id of script' do 41 | expect(zbx.scripts.get_or_create( 42 | name: @script, 43 | command: 'hostname' 44 | )).to eq @scriptid 45 | end 46 | end 47 | 48 | describe 'get_full_data' do 49 | it 'should contains created script' do 50 | expect(zbx.scripts.get_full_data(name: @script)[0]).to include('name' => @script) 51 | end 52 | end 53 | 54 | describe 'get_id' do 55 | it 'should return id of script' do 56 | expect(zbx.scripts.get_id(name: @script)).to eq @scriptid 57 | end 58 | end 59 | 60 | it 'should raise error on no identity given' do 61 | expect { zbx.scripts.get_id({}) }.to raise_error(ZabbixApi::ApiError) 62 | end 63 | 64 | describe 'update' do 65 | it 'should return id' do 66 | expect(zbx.scripts.update( 67 | scriptid: zbx.scripts.get_id(name: @script), 68 | # enable_confirmation: 1, 69 | confirmation: 'Are you sure you would like to show the system hostname?' 70 | )).to eq @scriptid 71 | end 72 | end 73 | 74 | describe 'create_or_update' do 75 | it 'should update existing script' do 76 | expect(zbx.scripts.get_or_create( 77 | name: @script, 78 | command: 'hostname' 79 | )).to eq @scriptid 80 | end 81 | 82 | it 'should create script' do 83 | new_script_id = zbx.scripts.get_or_create( 84 | name: @script + '____1', 85 | command: 'hostname' 86 | ) 87 | 88 | expect(new_script_id).to be_kind_of(Integer) 89 | expect(new_script_id).to be > @scriptid 90 | end 91 | end 92 | 93 | # TODO: see if we can get this test working with travis ci (passes on standalone zabbix server) 94 | # describe 'execute' do 95 | # it "should return success response" do 96 | # expect(zbx.scripts.execute(:scriptid => @scriptid, :hostid => @hostid)).to include("response" => "success") 97 | # end 98 | # end 99 | 100 | describe 'getscriptsbyhost' do 101 | it 'should return object with hostid and script' do 102 | expect(zbx.scripts.getscriptsbyhost([@hostid])[@hostid.to_s].select { |script| script[:name] == @script }).to_not be_nil 103 | end 104 | end 105 | 106 | describe 'delete' do 107 | before :all do 108 | @result = zbx.scripts.delete(@scriptid) 109 | end 110 | 111 | it 'should return deleted id' do 112 | expect(@result).to eq @scriptid 113 | end 114 | 115 | it 'should delete script from zabbix' do 116 | expect(zbx.scripts.get_id(name: @script)).to be_nil 117 | end 118 | end 119 | end 120 | end 121 | -------------------------------------------------------------------------------- /spec/graph.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'graph' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 7 | @template = gen_name 'template' 8 | @templateid = zbx.templates.create( 9 | host: @template, 10 | groups: [groupid: @hostgroupid] 11 | ) 12 | @application = gen_name 'application' 13 | @applicationid = zbx.applications.create( 14 | name: @application, 15 | hostid: @templateid 16 | ) 17 | @item = gen_name 'item' 18 | @itemid = zbx.items.create( 19 | name: @item, 20 | key_: "proc.num[#{gen_name 'proc'}]", 21 | status: 0, 22 | hostid: @templateid, 23 | applications: [@applicationid] 24 | ) 25 | 26 | @color = '123456' 27 | end 28 | 29 | def gitems 30 | { 31 | itemid: @itemid, 32 | calc_fnc: '3', 33 | color: @color, 34 | type: '0', 35 | periods_cnt: '5' 36 | } 37 | end 38 | 39 | def create_graph(graph, _itemid) 40 | zbx.graphs.create( 41 | gitems: [gitems], 42 | show_triggers: '0', 43 | name: graph, 44 | width: '900', 45 | height: '200' 46 | ) 47 | end 48 | 49 | context 'when name not exists' do 50 | describe 'create' do 51 | it 'should return integer id' do 52 | @graph = gen_name 'graph' 53 | expect(create_graph(@graph, @itemid)).to be_kind_of(Integer) 54 | end 55 | end 56 | end 57 | 58 | context 'when name exists' do 59 | before :all do 60 | @graph = gen_name 'graph' 61 | @graphid = create_graph(@graph, @itemid) 62 | end 63 | 64 | describe 'get_or_create' do 65 | it 'should return id of existing graph' do 66 | expect( 67 | zbx.graphs.get_or_create( 68 | gitems: [gitems], 69 | show_triggers: '0', 70 | name: @graph, 71 | width: '900', 72 | height: '200' 73 | ) 74 | ).to eq @graphid 75 | end 76 | end 77 | 78 | describe 'get_items' do 79 | it 'should return array' do 80 | expect(zbx.graphs.get_items(@graphid)).to be_kind_of(Array) 81 | end 82 | 83 | it 'should return array of size 1' do 84 | expect(zbx.graphs.get_items(@graphid).size).to eq 1 85 | end 86 | 87 | it 'should include correct item' do 88 | expect(zbx.graphs.get_items(@graphid)[0]).to include('color' => @color) 89 | end 90 | end 91 | 92 | describe 'get_id' do 93 | it 'should return id' do 94 | expect(zbx.graphs.get_id(name: @graph)).to eq @graphid 95 | end 96 | end 97 | 98 | describe 'get_ids_by_host' do 99 | it 'should contains id of graph' do 100 | graph_array = zbx.graphs.get_ids_by_host(host: @host) 101 | expect(graph_array).to be_kind_of(Array) 102 | expect(graph_array).to include(@graphid.to_s) 103 | end 104 | end 105 | 106 | describe 'update' do 107 | it 'should return id' do 108 | expect( 109 | zbx.graphs.update( 110 | graphid: @graphid, 111 | gitems: [gitems], 112 | ymax_type: 1 113 | ) 114 | ).to eq @graphid 115 | end 116 | end 117 | 118 | describe 'create_or_update' do 119 | it 'should return existing id' do 120 | expect( 121 | zbx.graphs.create_or_update( 122 | gitems: [gitems], 123 | show_triggers: '1', 124 | name: @graph, 125 | width: '900', 126 | height: '200' 127 | ) 128 | ).to eq @graphid 129 | end 130 | end 131 | 132 | describe 'delete' do 133 | it 'should return true' do 134 | expect(zbx.graphs.delete(@graphid)).to eq @graphid 135 | end 136 | end 137 | end 138 | end 139 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/hosts_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Hosts' do 4 | let(:hosts_mock) { ZabbixApi::Hosts.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { hosts_mock.method_name } 9 | 10 | it { is_expected.to eq 'host' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { hosts_mock.identify } 15 | 16 | it { is_expected.to eq 'host' } 17 | end 18 | 19 | describe '.dump_by_id' do 20 | subject { hosts_mock.dump_by_id(data) } 21 | 22 | let(:data) { { testkey: 222 } } 23 | let(:result) { { test: 1 } } 24 | let(:key) { 'testkey' } 25 | 26 | before do 27 | allow(hosts_mock).to receive(:log) 28 | allow(hosts_mock).to receive(:key).and_return(key) 29 | allow(client).to receive(:api_request).with( 30 | method: 'host.get', 31 | params: { 32 | filter: { 33 | testkey: 222 34 | }, 35 | output: 'extend', 36 | selectGroups: 'shorten' 37 | } 38 | ).and_return(result) 39 | end 40 | 41 | it 'logs debug message' do 42 | expect(hosts_mock).to receive(:log).with("[DEBUG] Call dump_by_id with parameters: #{data.inspect}") 43 | subject 44 | end 45 | 46 | it { is_expected.to eq result } 47 | end 48 | 49 | describe '.default_options' do 50 | subject { hosts_mock.default_options } 51 | 52 | let(:result) do 53 | { 54 | host: nil, 55 | interfaces: [], 56 | status: 0, 57 | available: 1, 58 | groups: [], 59 | proxy_hostid: nil 60 | } 61 | end 62 | 63 | it { is_expected.to eq result } 64 | end 65 | 66 | describe '.unlink_templates' do 67 | subject { hosts_mock.unlink_templates(data) } 68 | 69 | let(:data) { { hosts_id: 222, templates_id: 333 } } 70 | let(:result) { { test: 1 } } 71 | let(:key) { 'testkey' } 72 | 73 | before do 74 | allow(hosts_mock).to receive(:log) 75 | allow(hosts_mock).to receive(:key).and_return(key) 76 | allow(client).to receive(:api_request).with( 77 | method: 'host.massRemove', 78 | params: { 79 | hostids: data[:hosts_id], 80 | templates: data[:templates_id] 81 | } 82 | ).and_return(result) 83 | end 84 | 85 | context 'when result is an empty hash' do 86 | let(:result) { {} } 87 | 88 | it { is_expected.to be_falsy } 89 | end 90 | 91 | context 'when result is not an empty hash' do 92 | it { is_expected.to be_truthy } 93 | end 94 | end 95 | 96 | describe '.create_or_update' do 97 | subject { hosts_mock.create_or_update(data) } 98 | 99 | let(:data) { { host: 'batman' } } 100 | let(:result) { [{ 'testkey' => '111', 'testidentify' => 1 }] } 101 | let(:key) { 'testkey' } 102 | let(:identify) { 'testidentify' } 103 | let(:id) { nil } 104 | let(:id_through_create) { 222 } 105 | let(:update_data) { { host: 'batman', hostid: 1234 } } 106 | 107 | before do 108 | allow(hosts_mock).to receive(:log) 109 | allow(hosts_mock).to receive(:identify).and_return(identify) 110 | allow(hosts_mock).to receive(:get_id) 111 | .with(host: data[:host]).and_return(id) 112 | allow(hosts_mock).to receive(:create).with(data).and_return(id_through_create) 113 | allow(hosts_mock).to receive(:update).with(update_data).and_return(id) 114 | end 115 | 116 | context 'when Host ID already exist' do 117 | let(:id) { 1234 } 118 | 119 | it 'updates an object returns the Host ID' do 120 | expect(subject).to eq id 121 | end 122 | end 123 | 124 | context 'when Host ID does not exist' do 125 | it 'creates an object returns the newly created object ID' do 126 | expect(subject).to eq id_through_create 127 | end 128 | end 129 | end 130 | end 131 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/applications_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Applications' do 4 | let(:actions_mock) { ZabbixApi::Applications.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { actions_mock.method_name } 9 | 10 | it { is_expected.to eq 'application' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { actions_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.get_or_create' do 20 | subject { actions_mock.get_or_create(data) } 21 | 22 | let(:data) { { name: 'batman', hostid: 1234 } } 23 | let(:result) { [{ 'testkey' => '111', 'testidentify' => 1 }] } 24 | let(:key) { 'testkey' } 25 | let(:identify) { 'testidentify' } 26 | let(:id) { nil } 27 | let(:id_through_create) { 222 } 28 | 29 | before do 30 | allow(actions_mock).to receive(:log) 31 | allow(actions_mock).to receive(:identify).and_return(identify) 32 | allow(actions_mock).to receive(:get_id).with(name: data[:name], hostid: data[:hostid]).and_return(id) 33 | allow(actions_mock).to receive(:create).with(data).and_return(id_through_create) 34 | end 35 | 36 | it 'logs the debug message' do 37 | expect(actions_mock).to receive(:log).with("[DEBUG] Call get_or_create with parameters: #{data.inspect}") 38 | subject 39 | end 40 | 41 | context 'when ID already exist' do 42 | let(:id) { '111' } 43 | 44 | it 'returns the existing ID' do 45 | expect(subject).to eq id 46 | end 47 | end 48 | 49 | context 'when id does not exist' do 50 | it 'returns the newly created ID' do 51 | expect(subject).to eq id_through_create 52 | end 53 | end 54 | end 55 | 56 | describe '.create_or_update' do 57 | subject { actions_mock.create_or_update(data) } 58 | 59 | let(:data) { { name: 'batman', hostid: 1234 } } 60 | let(:result) { [{ 'testkey' => '111', 'testidentify' => 1 }] } 61 | let(:key) { 'testkey' } 62 | let(:identify) { 'testidentify' } 63 | let(:id) { nil } 64 | let(:id_through_create) { 222 } 65 | let(:update_data) { { name: 'batman', hostid: 1234, applicationid: id } } 66 | 67 | before do 68 | allow(actions_mock).to receive(:log) 69 | allow(actions_mock).to receive(:identify).and_return(identify) 70 | allow(actions_mock).to receive(:get_id) 71 | .with(name: data[:name], hostid: data[:hostid]).and_return(id) 72 | allow(actions_mock).to receive(:create).with(data).and_return(id_through_create) 73 | allow(actions_mock).to receive(:update).with(update_data).and_return(id) 74 | end 75 | 76 | context 'when Application ID already exist' do 77 | let(:id) { '111' } 78 | 79 | it 'updates an object returns the object ID' do 80 | expect(subject).to eq id 81 | end 82 | end 83 | 84 | context 'when Application ID does not exist' do 85 | it 'creates an object returns the newly created object ID' do 86 | expect(subject).to eq id_through_create 87 | end 88 | end 89 | 90 | context 'when an API request raise ApiError' do 91 | before do 92 | allow(actions_mock).to receive(:create).with(data).and_raise(ZabbixApi::ApiError, 'ApiError occured.') 93 | end 94 | 95 | it 'propogates the ApiError raise by an API' do 96 | expect { subject }.to raise_error(ZabbixApi::ApiError, 'ApiError occured.') 97 | end 98 | end 99 | 100 | context 'when an API request raise HttpError' do 101 | before do 102 | allow(actions_mock).to receive(:create).with(data).and_raise(ZabbixApi::HttpError, 'HttpError occured.') 103 | end 104 | 105 | it 'propogates the HttpError raise by an API' do 106 | expect { subject }.to raise_error(ZabbixApi::HttpError, 'HttpError occured.') 107 | end 108 | end 109 | end 110 | end 111 | -------------------------------------------------------------------------------- /spec/item.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'item' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 7 | @template = gen_name 'template' 8 | @templateid = zbx.templates.create( 9 | host: @template, 10 | groups: [groupid: @hostgroupid] 11 | ) 12 | @application = gen_name 'application' 13 | @applicationid = zbx.applications.create( 14 | name: @application, 15 | hostid: @templateid 16 | ) 17 | end 18 | 19 | context 'when name not exists' do 20 | before do 21 | @item = gen_name 'item' 22 | end 23 | 24 | describe 'create' do 25 | it 'should return integer id' do 26 | itemid = zbx.items.create( 27 | name: @item, 28 | key_: "proc.num[#{gen_name 'proc'}]", 29 | status: 0, 30 | hostid: @templateid, 31 | applications: [@applicationid] 32 | ) 33 | expect(itemid).to be_kind_of(Integer) 34 | end 35 | end 36 | 37 | describe 'get_id' do 38 | it 'should return nil' do 39 | expect(zbx.items.get_id(name: @item)).to be_kind_of(NilClass) 40 | end 41 | end 42 | end 43 | 44 | context 'when name exists' do 45 | before :all do 46 | @item = gen_name 'item' 47 | @itemid = zbx.items.create( 48 | name: @item, 49 | key_: 'proc.num[aaa]', 50 | status: 0, 51 | hostid: @templateid, 52 | applications: [@applicationid] 53 | ) 54 | end 55 | 56 | describe 'get_or_create' do 57 | it 'should return id of item' do 58 | expect( 59 | zbx.items.get_or_create( 60 | name: @item, 61 | key_: "proc.num[#{gen_name 'proc'}]", 62 | status: 0, 63 | hostid: @templateid, 64 | applications: [@applicationid] 65 | ) 66 | ).to eq @itemid 67 | end 68 | end 69 | 70 | describe 'get_full_data' do 71 | it 'should contains created item' do 72 | expect(zbx.items.get_full_data(name: @item)[0]).to include('name' => @item) 73 | end 74 | end 75 | 76 | describe 'get_id' do 77 | it 'should return id of item' do 78 | expect(zbx.items.get_id(name: @item)).to eq @itemid 79 | end 80 | end 81 | 82 | it 'should raise error on no identity given' do 83 | expect { zbx.items.get_id({}) }.to raise_error(ZabbixApi::ApiError) 84 | end 85 | 86 | describe 'update' do 87 | it 'should return id' do 88 | expect( 89 | zbx.items.update( 90 | itemid: zbx.items.get_id(name: @item), 91 | status: 1 92 | ) 93 | ).to eq @itemid 94 | end 95 | end 96 | 97 | describe 'create_or_update' do 98 | it 'should update existing item' do 99 | expect( 100 | zbx.items.create_or_update( 101 | name: @item, 102 | key_: "proc.num[#{gen_name 'proc'}]", 103 | status: 0, 104 | hostid: @templateid, 105 | applications: [@applicationid] 106 | ) 107 | ).to eq @itemid 108 | end 109 | 110 | it 'should create item' do 111 | new_item_id = zbx.items.create_or_update( 112 | name: @item + '____1', 113 | key_: "proc.num[#{gen_name 'proc'}]", 114 | status: 0, 115 | hostid: @templateid, 116 | applications: [@applicationid] 117 | ) 118 | 119 | expect(new_item_id).to be_kind_of(Integer) 120 | expect(new_item_id).to be > @itemid 121 | end 122 | end 123 | 124 | describe 'delete' do 125 | before :all do 126 | @result = zbx.items.delete(@itemid) 127 | end 128 | 129 | it 'should return deleted id' do 130 | expect(@result).to eq @itemid 131 | end 132 | 133 | it 'should delete item from zabbix' do 134 | expect(zbx.items.get_id(name: @item)).to be_nil 135 | end 136 | end 137 | end 138 | end 139 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/items_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Items' do 4 | let(:items_mock) { ZabbixApi::Items.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { items_mock.method_name } 9 | 10 | it { is_expected.to eq 'item' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { items_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.default_options' do 20 | subject { items_mock.default_options } 21 | 22 | let(:result) do 23 | { 24 | name: nil, 25 | key_: nil, 26 | hostid: nil, 27 | delay: 60, 28 | history: 3600, 29 | status: 0, 30 | type: 7, 31 | snmp_community: '', 32 | snmp_oid: '', 33 | value_type: 3, 34 | data_type: 0, 35 | trapper_hosts: 'localhost', 36 | snmp_port: 161, 37 | units: '', 38 | multiplier: 0, 39 | delta: 0, 40 | snmpv3_securityname: '', 41 | snmpv3_securitylevel: 0, 42 | snmpv3_authpassphrase: '', 43 | snmpv3_privpassphrase: '', 44 | formula: 0, 45 | trends: 86400, 46 | logtimefmt: '', 47 | valuemapid: 0, 48 | delay_flex: '', 49 | authtype: 0, 50 | username: '', 51 | password: '', 52 | publickey: '', 53 | privatekey: '', 54 | params: '', 55 | ipmi_sensor: '' 56 | } 57 | end 58 | 59 | it { is_expected.to eq result } 60 | end 61 | 62 | describe '.get_or_create' do 63 | subject { items_mock.get_or_create(data) } 64 | 65 | let(:data) { { name: 'batman', hostid: 1234 } } 66 | let(:result) { [{ 'testkey' => '111', 'testidentify' => 1 }] } 67 | let(:id) { nil } 68 | let(:id_through_create) { 222 } 69 | 70 | before do 71 | allow(items_mock).to receive(:log) 72 | allow(items_mock).to receive(:get_id).with(name: data[:name], hostid: data[:hostid]).and_return(id) 73 | allow(items_mock).to receive(:create).with(data).and_return(id_through_create) 74 | end 75 | 76 | it 'logs the debug message' do 77 | expect(items_mock).to receive(:log).with("[DEBUG] Call get_or_create with parameters: #{data.inspect}") 78 | subject 79 | end 80 | 81 | context 'when ID already exist' do 82 | let(:id) { '111' } 83 | 84 | it 'returns the existing ID' do 85 | expect(subject).to eq id 86 | end 87 | end 88 | 89 | context 'when id does not exist' do 90 | it 'returns the newly created ID' do 91 | expect(subject).to eq id_through_create 92 | end 93 | end 94 | end 95 | 96 | describe '.create_or_update' do 97 | subject { items_mock.create_or_update(data) } 98 | 99 | let(:data) { { name: 'batman', hostid: '1234' } } 100 | let(:result) { [{ 'testkey' => '111', 'testidentify' => 1 }] } 101 | let(:key) { 'testkey' } 102 | let(:identify) { 'testidentify' } 103 | let(:itemid) { nil } 104 | let(:id_through_create) { 222 } 105 | let(:update_data) { { name: data[:name], hostid: data[:hostid], itemid: itemid } } 106 | 107 | before do 108 | allow(items_mock).to receive(:log) 109 | allow(items_mock).to receive(:identify).and_return(identify) 110 | allow(items_mock).to receive(:get_id) 111 | .with(name: data[:name], hostid: data[:hostid]).and_return(itemid) 112 | allow(items_mock).to receive(:create).with(data).and_return(id_through_create) 113 | allow(items_mock).to receive(:update).with(update_data).and_return(itemid) 114 | end 115 | 116 | context 'when Item ID already exist' do 117 | let(:itemid) { 1234 } 118 | 119 | it 'updates an object returns the Item ID' do 120 | expect(subject).to eq itemid 121 | end 122 | end 123 | 124 | context 'when Item ID does not exist' do 125 | it 'creates an object returns the newly created object ID' do 126 | expect(subject).to eq id_through_create 127 | end 128 | end 129 | end 130 | end 131 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/graphs.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Graphs < Basic 3 | # The method name used for interacting with Graphs via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'graph' 8 | end 9 | 10 | # The id field name used for identifying specific Graph objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # Get full/extended Graph data from Zabbix API 18 | # 19 | # @param data [Hash] Should include object's id field name (identify) and id value 20 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 21 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 22 | # @return [Hash] 23 | def get_full_data(data) 24 | log "[DEBUG] Call get_full_data with parameters: #{data.inspect}" 25 | 26 | @client.api_request( 27 | method: "#{method_name}.get", 28 | params: { 29 | search: { 30 | identify.to_sym => data[identify.to_sym] 31 | }, 32 | output: 'extend' 33 | } 34 | ) 35 | end 36 | 37 | # Get Graph ids for Host from Zabbix API 38 | # 39 | # @param data [Hash] Should include host value to query for matching graphs 40 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 41 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 42 | # @return [Array] Returns array of Graph ids 43 | def get_ids_by_host(data) 44 | result = @client.api_request( 45 | method: 'graph.get', 46 | params: { 47 | filter: { 48 | host: data[:host] 49 | }, 50 | output: 'extend' 51 | } 52 | ) 53 | 54 | result.map do |graph| 55 | num = graph['graphid'] 56 | name = graph['name'] 57 | filter = data[:filter] 58 | 59 | num if filter.nil? || /#{filter}/ =~ name 60 | end.compact 61 | end 62 | 63 | # Get Graph Item object using Zabbix API 64 | # 65 | # @param data [Hash] Needs to include graphids to properly identify Graph Items via Zabbix API 66 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 67 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 68 | # @return [Hash] 69 | def get_items(data) 70 | @client.api_request( 71 | method: 'graphitem.get', 72 | params: { 73 | graphids: [data], 74 | output: 'extend' 75 | } 76 | ) 77 | end 78 | 79 | # Get or Create Graph object using Zabbix API 80 | # 81 | # @param data [Hash] Needs to include name and templateid to properly identify Graphs via Zabbix API 82 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 83 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 84 | # @return [Integer] Zabbix object id 85 | def get_or_create(data) 86 | log "[DEBUG] Call get_or_create with parameters: #{data.inspect}" 87 | 88 | unless (id = get_id(name: data[:name], templateid: data[:templateid])) 89 | id = create(data) 90 | end 91 | 92 | id 93 | end 94 | 95 | # Create or update Graph object using Zabbix API 96 | # 97 | # @param data [Hash] Needs to include name and templateid to properly identify Graphs via Zabbix API 98 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 99 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 100 | # @return [Integer] Zabbix object id 101 | def create_or_update(data) 102 | graphid = get_id(name: data[:name], templateid: data[:templateid]) 103 | graphid ? _update(data.merge(graphid: graphid)) : create(data) 104 | end 105 | 106 | def _update(data) 107 | data.delete(:name) 108 | update(data) 109 | end 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ruby Zabbix Api Module 2 | 3 | [![Gem Version](http://img.shields.io/gem/v/zabbixapi.svg)][gem] 4 | [![Build Status](https://github.com/anapsix/zabbixapi/workflows/CI/badge.svg)][github-ci] 5 | 6 | [gem]: https://rubygems.org/gems/zabbixapi 7 | [github-ci]: https://github.com/express42/zabbixapi/actions?query=workflow%3ACI 8 | 9 | Simple and lightweight ruby module for working with [Zabbix][Zabbix] via the [Zabbix API][Zabbix API] 10 | 11 | ## Installation 12 | ```sh 13 | # latest 14 | gem install zabbixapi 15 | 16 | # specific version 17 | gem install zabbixapi -v 4.2.0 18 | ``` 19 | 20 | ## Documentation 21 | [http://rdoc.info/gems/zabbixapi][documentation] 22 | 23 | [documentation]: http://rdoc.info/gems/zabbixapi 24 | 25 | ## Examples 26 | [https://github.com/express42/zabbixapi/tree/master/examples][examples] 27 | 28 | [examples]: https://github.com/express42/zabbixapi/tree/master/examples 29 | 30 | ## Version Policy 31 | 32 | **NOTE:** `master` branch is used for ongoing development on Zabbix API 5.x (5.0 and 5.2). 33 | 34 | We support only two last versions of zabbix (5.0 and 5.2), so you should consider all previous versions deprecated. 35 | 36 | * Zabbix 1.8.2 (api version 1.2) | zabbixapi 0.6.x | [branch zabbix1.8](https://github.com/express42/zabbixapi/tree/zabbix1.8) 37 | * Zabbix 1.8.9 (api version 1.3) | zabbixapi 0.6.x | [branch zabbix1.8](https://github.com/express42/zabbixapi/tree/zabbix1.8) 38 | * Zabbix 2.0.x (api version 1.4 -> 2.0.10) | zabbixapi 2.0.x | [branch zabbix2.0](https://github.com/express42/zabbixapi/tree/zabbix2.0) 39 | * Zabbix 2.2.x (api version 2.2.x) | zabbixapi 2.2.x | [branch zabbix2.2](https://github.com/express42/zabbixapi/tree/zabbix2.2) 40 | * Zabbix 2.4.x (api version 2.2.x) | zabbixapi 2.4.x | [branch zabbix2.4](https://github.com/express42/zabbixapi/tree/zabbix2.4) 41 | * Zabbix 3.0.x (api version 3.0.x) | zabbixapi 3.0.x | [branch zabbix3.0](https://github.com/express42/zabbixapi/tree/zabbix3.0) 42 | * Zabbix 3.2.x (api version 3.2.x) | zabbixapi 3.2.x | [branch zabbix3.2](https://github.com/express42/zabbixapi/tree/zabbix3.2) 43 | * Zabbix 4.0.x (api version 4.0.x) | zabbixapi 4.1.x | [branch zabbix4.0](https://github.com/express42/zabbixapi/tree/zabbix4.0) 44 | * Zabbix 4.2.x (api version 4.2.x) | zabbixapi 4.1.x | [branch zabbix4.0](https://github.com/express42/zabbixapi/tree/zabbix4.0) 45 | * Zabbix 4.4.x (api version 4.4.x) | zabbixapi 4.2.x | [branch zabbix4.2](https://github.com/express42/zabbixapi/tree/zabbix4.2) 46 | 47 | ## Supported Ruby Versions 48 | This library aims to support and is [tested against][github-ci] the following Ruby 49 | versions: 50 | 51 | * Ruby 2.5 52 | * Ruby 2.6 53 | * Ruby 2.7 54 | * JRuby 9.2.10.0 55 | 56 | If something doesn't work on one of these versions, it's a bug. 57 | 58 | This library may inadvertently work (or seem to work) on other Ruby versions, 59 | however support will only be provided for the versions listed above. 60 | 61 | If you would like this library to support another Ruby version or 62 | implementation, you may volunteer to be a maintainer. Being a maintainer 63 | entails making sure all tests run and pass on that implementation. When 64 | something breaks on your implementation, you will be responsible for providing 65 | patches in a timely fashion. If critical issues for a particular implementation 66 | exist at the time of a major release, support for that Ruby version may be 67 | dropped. 68 | 69 | ## Dependencies 70 | 71 | * net/http 72 | * json 73 | 74 | ## Contributing 75 | 76 | * Fork the project. 77 | * Base your work on the master branch. 78 | * Make your feature addition or bug fix, write tests, write documentation/examples. 79 | * Commit, do not mess with rakefile, version. 80 | * Make a pull request. 81 | 82 | ## Zabbix documentation 83 | 84 | * [Zabbix Project Homepage][Zabbix] 85 | * [Zabbix API docs][Zabbix API] 86 | 87 | [Zabbix]: https://www.zabbix.com 88 | [Zabbix API]: https://www.zabbix.com/documentation/5.2/manual/api 89 | 90 | ## Copyright 91 | 92 | - Copyright (c) 2021 [contributors] 93 | - Copyright (c) 2015-2018 Express 42 and [contributors] 94 | 95 | See [LICENSE] for details. 96 | 97 | [LICENSE]: LICENSE.md 98 | [contributors]: https://github.com/express42/zabbixapi/graphs/contributors 99 | -------------------------------------------------------------------------------- /spec/httptest.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'httptest' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 7 | @template = gen_name 'template' 8 | @templateid = zbx.templates.create( 9 | host: @template, 10 | groups: [groupid: @hostgroupid] 11 | ) 12 | end 13 | 14 | context 'when name not exists' do 15 | before do 16 | @httptest_name = gen_name 'httptest_name' 17 | @step_name = gen_name 'step_name' 18 | end 19 | 20 | describe 'create' do 21 | it 'should return integer id' do 22 | httptestid = zbx.httptests.create( 23 | name: @httptest_name, 24 | hostid: @templateid, 25 | steps: [ 26 | { 27 | name: @step_name, 28 | url: 'http://localhost/zabbix/', 29 | status_codes: '200', 30 | no: 1 31 | } 32 | ] 33 | ) 34 | expect(httptestid).to be_kind_of(Integer) 35 | end 36 | end 37 | 38 | describe 'get_id' do 39 | it 'should return nil' do 40 | expect(zbx.httptests.get_id(name: @httptest_name)).to be_kind_of(NilClass) 41 | expect(zbx.httptests.get_id('name' => @httptest_name)).to be_kind_of(NilClass) 42 | end 43 | end 44 | end 45 | 46 | context 'when name exists' do 47 | before :all do 48 | @httptest_name = gen_name 'httptest_name' 49 | @step_name = gen_name 'step_name' 50 | @httptestid = zbx.httptests.create( 51 | name: @httptest_name, 52 | hostid: @templateid, 53 | steps: [ 54 | { 55 | name: @step_name, 56 | url: 'http://localhost/zabbix/', 57 | status_codes: '200', 58 | no: 1 59 | } 60 | ] 61 | ) 62 | end 63 | 64 | describe 'get_or_create' do 65 | it 'should return id of httptest' do 66 | expect( 67 | zbx.httptests.get_or_create( 68 | name: @httptest_name, 69 | hostid: @templateid, 70 | steps: [ 71 | { 72 | name: @step_name, 73 | url: 'http://localhost/zabbix/', 74 | status_codes: '200', 75 | no: 1 76 | } 77 | ] 78 | ) 79 | ).to eq @httptestid 80 | end 81 | end 82 | 83 | describe 'get_full_data' do 84 | it 'should contain created httptest' do 85 | expect(zbx.httptests.get_full_data(name: @httptest_name)[0]).to include('name' => @httptest_name) 86 | end 87 | end 88 | 89 | describe 'get_id' do 90 | it 'should return id of httptest' do 91 | expect(zbx.httptests.get_id(name: @httptest_name)).to eq @httptestid 92 | expect(zbx.httptests.get_id('name' => @httptest_name)).to eq @httptestid 93 | end 94 | end 95 | 96 | describe 'create_or_update' do 97 | it 'should return id of updated httptest' do 98 | expect( 99 | zbx.httptests.create_or_update( 100 | name: @httptest_name, 101 | hostid: @templateid, 102 | steps: [ 103 | { 104 | name: @step_name, 105 | url: 'http://localhost/zabbix/', 106 | status_codes: '200', 107 | no: 1 108 | } 109 | ] 110 | ) 111 | ).to eq @httptestid 112 | end 113 | end 114 | 115 | describe 'update' do 116 | it 'should return id' do 117 | expect( 118 | zbx.httptests.update( 119 | httptestid: @httptestid, 120 | status: 0, 121 | steps: [ 122 | { 123 | name: @step_name, 124 | url: 'http://localhost/zabbix/', 125 | status_codes: '200', 126 | no: 1 127 | } 128 | ] 129 | ) 130 | ).to eq @httptestid 131 | end 132 | end 133 | 134 | describe 'delete' do 135 | it 'HTTPTEST: Delete' do 136 | expect(zbx.httptests.delete(@httptestid)).to eq @httptestid 137 | end 138 | end 139 | end 140 | end 141 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/roles.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Roles < Basic 3 | # The method name used for interacting with Role via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'role' 8 | end 9 | 10 | # The key field name used for Role objects via Zabbix API 11 | # 12 | # @return [String] 13 | def key 14 | 'roleid' 15 | end 16 | 17 | # The id field name used for identifying specific Role objects via Zabbix API 18 | # 19 | # @return [String] 20 | def identify 21 | 'name' 22 | end 23 | 24 | # Set permissions for usergroup using Zabbix API 25 | # 26 | # @param data [Hash] Needs to include usrgrpids and hostgroupids along with permissions to set 27 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 28 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 29 | # @return [Integer] Zabbix object id (usergroup) 30 | def rules(data) 31 | rules = data[:rules] || 2 32 | result = @client.api_request( 33 | method: 'role.update', 34 | params: { 35 | roleid: data[:roleid], 36 | rules: data[:hostgroupids].map { |t| { permission: permission, id: t } } 37 | } 38 | ) 39 | result ? result['usrgrpids'][0].to_i : nil 40 | end 41 | 42 | # Add users to usergroup using Zabbix API 43 | # 44 | # @deprecated Zabbix has removed massAdd in favor of update. 45 | # @param data [Hash] Needs to include userids and usrgrpids to mass add users to groups 46 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 47 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 48 | # @return [Integer] Zabbix object id (usergroup) 49 | def add_user(data) 50 | update_users(data) 51 | end 52 | 53 | # Dump Role object data by key from Zabbix API 54 | # 55 | # @param data [Hash] Should include desired object's key and value 56 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 57 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 58 | # @return [Hash] 59 | def dump_by_id(data) 60 | log "[DEBUG] Call dump_by_id with parameters: #{data.inspect}" 61 | 62 | @client.api_request( 63 | method: 'role.get', 64 | params: { 65 | output: 'extend', 66 | selectRules: 'extend', 67 | roleids: data[:id] 68 | } 69 | ) 70 | end 71 | 72 | # Get Role ids by Role Name from Zabbix API 73 | # 74 | # @param data [Hash] Should include host value to query for matching graphs 75 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 76 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 77 | # @return [Array] Returns array of Graph ids 78 | def get_ids_by_name(data) 79 | result = @client.api_request( 80 | method: 'role.get', 81 | params: { 82 | filter: { 83 | name: data[:name] 84 | }, 85 | output: 'extend' 86 | } 87 | ) 88 | 89 | result.map do |rule| 90 | rule['roleid'] 91 | end.compact 92 | end 93 | 94 | # Update users in Userroles using Zabbix API 95 | # 96 | # @param data [Hash] Needs to include userids and usrgrpids to mass update users in groups 97 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 98 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 99 | # @return [Integer] Zabbix object id (usergroup) 100 | def update_users(data) 101 | user_groups = data[:usrgrpids].map do |t| 102 | { 103 | usrgrpid: t, 104 | userids: data[:userids], 105 | } 106 | end 107 | result = @client.api_request( 108 | method: 'usergroup.update', 109 | params: user_groups, 110 | ) 111 | result ? result['usrgrpids'][0].to_i : nil 112 | end 113 | end 114 | end 115 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/templates.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Templates < Basic 3 | # The method name used for interacting with Templates via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'template' 8 | end 9 | 10 | # The id field name used for identifying specific Template objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'host' 15 | end 16 | 17 | # Delete Template object using Zabbix API 18 | # 19 | # @param data [Array] Should include array of templateid's 20 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 21 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 22 | # @return [Integer] The Template object id that was deleted 23 | def delete(data) 24 | result = @client.api_request(method: 'template.delete', params: [data]) 25 | result.empty? ? nil : result['templateids'][0].to_i 26 | end 27 | 28 | # Get Template ids for Host from Zabbix API 29 | # 30 | # @param data [Hash] Should include host value to query for matching templates 31 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 32 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 33 | # @return [Array] Returns array of Template ids 34 | def get_ids_by_host(data) 35 | @client.api_request(method: 'template.get', params: data).map do |tmpl| 36 | tmpl['templateid'] 37 | end 38 | end 39 | 40 | # Get or Create Template object using Zabbix API 41 | # 42 | # @param data [Hash] Needs to include host to properly identify Templates via Zabbix API 43 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 44 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 45 | # @return [Integer] Zabbix object id 46 | def get_or_create(data) 47 | unless (templateid = get_id(host: data[:host])) 48 | templateid = create(data) 49 | end 50 | templateid 51 | end 52 | 53 | # Mass update Templates for Hosts using Zabbix API 54 | # 55 | # @param data [Hash] Should include hosts_id array and templates_id array 56 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 57 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 58 | # @return [Boolean] 59 | def mass_update(data) 60 | result = @client.api_request( 61 | method: 'template.massUpdate', 62 | params: { 63 | hosts: data[:hosts_id].map { |t| { hostid: t } }, 64 | templates: data[:templates_id].map { |t| { templateid: t } } 65 | } 66 | ) 67 | result.empty? ? false : true 68 | end 69 | 70 | # Mass add Templates to Hosts using Zabbix API 71 | # 72 | # @param data [Hash] Should include hosts_id array and templates_id array 73 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 74 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 75 | # @return [Boolean] 76 | def mass_add(data) 77 | result = @client.api_request( 78 | method: 'template.massAdd', 79 | params: { 80 | hosts: data[:hosts_id].map { |t| { hostid: t } }, 81 | templates: data[:templates_id].map { |t| { templateid: t } } 82 | } 83 | ) 84 | result.empty? ? false : true 85 | end 86 | 87 | # Mass remove Templates to Hosts using Zabbix API 88 | # 89 | # @param data [Hash] Should include hosts_id array and templates_id array 90 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 91 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 92 | # @return [Boolean] 93 | def mass_remove(data) 94 | result = @client.api_request( 95 | method: 'template.massRemove', 96 | params: { 97 | hostids: data[:hosts_id], 98 | templateids: data[:templates_id], 99 | groupids: data[:group_id], 100 | force: 1 101 | } 102 | ) 103 | result.empty? ? false : true 104 | end 105 | end 106 | end 107 | -------------------------------------------------------------------------------- /examples/Queries with Filters.md: -------------------------------------------------------------------------------- 1 | # Queries with zabbixapi 2 | 3 | These examples assumes you have already initialized and connected the ZabbixApi and have an object "zbx" that represents this connection. 4 | 5 | ### Learning with the debug option 6 | If you're just learning how this library works with the zabbix api and you're having trouble understanding what the library is doing as it relates to the zabbix api documentation, you can try enabling the debug option in the client, either when you instantiate it or later on as you desire. With debug turned on, you can see what zabbixapi has constructed as a query, and you can see the json data that's coming back from zabbix. 7 | 8 | #### instantiate w/ debug 9 | ``` ruby 10 | zbx = ZabbixApi.connect(url: '', user: '', password: '', debug: true) 11 | ``` 12 | 13 | #### debug on demand 14 | ``` ruby 15 | zbx.client.options[:debug] = true 16 | ``` 17 | 18 | ### Listing all objects of a type: "all" 19 | 20 | For all object types, you can get a list of all objects of that type that are defined in zabbix by calling 21 | ``` ruby 22 | .all 23 | ``` 24 | So to get a list of all host groups in your installation you can call 25 | ``` ruby 26 | zbx.hostgroups.all 27 | ``` 28 | 29 | ### Searching with filters: "get[_*]" 30 | 31 | The get() method available for all objects includes some implied logic: the only parameter being sent in is a filter object, and the parameters you provide to this method are properties of that filter. 32 | 33 | In general, the get_* methods are wrappers around calls to the get() method that help with construction of particular filters. 34 | 35 | As of this writing, a filter object is descrbed in this way: 36 | 37 | > Return only those results that exactly match the given filter. 38 | > 39 | > Accepts an array, where the keys are property names, and the values are either a single value or an array of values to match against. 40 | > 41 | > Doesn't work for text fields. 42 | 43 | For instance, to get a list of all the fields you can filter on when using hosts.get_* methods, you can first run 44 | 45 | ``` ruby 46 | zbx.hosts.get_full_data(host: 'zabbix-server') 47 | ``` 48 | 49 | That call will return a structure like: 50 | 51 | ``` ruby 52 | [{"hostid"=>"1001", 53 | "proxy_hostid"=>"0", 54 | "host"=>"zabbix-server", 55 | "status"=>"0", 56 | "disable_until"=>"0", 57 | "error"=>"", 58 | "available"=>"1", 59 | "errors_from"=>"0", 60 | "lastaccess"=>"0", 61 | "ipmi_authtype"=>"-1", 62 | "ipmi_privilege"=>"2", 63 | "ipmi_username"=>"", 64 | "ipmi_password"=>"", 65 | "ipmi_disable_until"=>"0", 66 | "ipmi_available"=>"0", 67 | "snmp_disable_until"=>"0", 68 | "snmp_available"=>"0", 69 | "maintenanceid"=>"0", 70 | "maintenance_status"=>"0", 71 | "maintenance_type"=>"0", 72 | "maintenance_from"=>"0", 73 | "ipmi_errors_from"=>"0", 74 | "snmp_errors_from"=>"0", 75 | "ipmi_error"=>"", 76 | "snmp_error"=>"", 77 | "jmx_disable_until"=>"0", 78 | "jmx_available"=>"0", 79 | "jmx_errors_from"=>"0", 80 | "jmx_error"=>"", 81 | "name"=>"zabbix-server", 82 | "flags"=>"0", 83 | "templateid"=>"0", 84 | "description"=>"This is the zabbix server", 85 | "tls_connect"=>"1", 86 | "tls_accept"=>"1", 87 | "tls_issuer"=>"", 88 | "tls_subject"=>"", 89 | "tls_psk_identity"=>"", 90 | "tls_psk"=>"", 91 | "proxy_address"=>"", 92 | "auto_compress"=>"1"}] 93 | ``` 94 | 95 | Using the information you see in this structure, you can query more specifically like: 96 | 97 | ``` ruby 98 | zbx.hosts.get_id(host: 'zabbix-server') 99 | ``` 100 | 101 | (which for this call returns a single host id). 102 | 103 | 104 | ### Searches with parameters beyond "filter" 105 | 106 | If you want to do queries that use the parameters described in the api for the various object other than just the "filter" one, you'll need to do a custom query. 107 | 108 | Custom queries closely mirror what you see in the zabbix api documentation, so it's pretty easy to translate from the offical api documentation to a custom query. 109 | 110 | For instance, say that you want get a list of hosts that belong to a host group. You can construct a custom query like this: 111 | 112 | ``` ruby 113 | zbx.query(method: 'host.get', params: {groupids: [1,2,3], selectGroups: :extend}) 114 | ``` 115 | and of course you can nest calls: 116 | ```ruby 117 | zbx.query(method: 'host.get', params: {groupids: zbx.hostgroups.get_id(name: 'My Hostgroup'), selectGroups: :extend}) 118 | ``` 119 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/triggers.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Triggers < Basic 3 | # The method name used for interacting with Triggers via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'trigger' 8 | end 9 | 10 | # The id field name used for identifying specific Trigger objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'description' 15 | end 16 | 17 | # Dump Trigger object data by key from Zabbix API 18 | # 19 | # @param data [Hash] Should include desired object's key and value 20 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 21 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 22 | # @return [Hash] 23 | def dump_by_id(data) 24 | log "[DEBUG] Call dump_by_id with parameters: #{data.inspect}" 25 | 26 | @client.api_request( 27 | method: 'trigger.get', 28 | params: { 29 | filter: { 30 | key.to_sym => data[key.to_sym] 31 | }, 32 | output: 'extend', 33 | select_items: 'extend', 34 | select_functions: 'extend' 35 | } 36 | ) 37 | end 38 | 39 | # Safely update Trigger object using Zabbix API by deleting and replacing trigger 40 | # 41 | # @param data [Hash] Needs to include description and hostid to properly identify Triggers via Zabbix API 42 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 43 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 44 | # @return [Integer] Zabbix object id 45 | def safe_update(data) 46 | log "[DEBUG] Call safe_update with parameters: #{data.inspect}" 47 | 48 | dump = {} 49 | item_id = data[key.to_sym].to_i 50 | dump_by_id(key.to_sym => data[key.to_sym]).each do |item| 51 | dump = symbolize_keys(item) if item[key].to_i == data[key.to_sym].to_i 52 | end 53 | 54 | expression = dump[:items][0][:key_] + '.' + dump[:functions][0][:function] + '(' + dump[:functions][0][:parameter] + ')' 55 | dump[:expression] = dump[:expression].gsub(/\{(\d*)\}/, "{#{expression}}") # TODO: ugly regexp 56 | dump.delete(:functions) 57 | dump.delete(:items) 58 | 59 | old_expression = data[:expression] 60 | data[:expression] = data[:expression].gsub(/\{.*\:/, '{') # TODO: ugly regexp 61 | data.delete(:templateid) 62 | 63 | log "[DEBUG] expression: #{dump[:expression]}\n data: #{data[:expression]}" 64 | 65 | if hash_equals?(dump, data) 66 | log "[DEBUG] Equal keys #{dump} and #{data}, skip safe_update" 67 | item_id 68 | else 69 | data[:expression] = old_expression 70 | # disable old trigger 71 | log '[DEBUG] disable :' + @client.api_request(method: "#{method_name}.update", params: [{ triggerid: data[:triggerid], status: '1' }]).inspect 72 | # create new trigger 73 | data.delete(:triggerid) 74 | create(data) 75 | end 76 | end 77 | 78 | # Get or Create Trigger object using Zabbix API 79 | # 80 | # @param data [Hash] Needs to include description and hostid to properly identify Triggers via Zabbix API 81 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 82 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 83 | # @return [Integer] Zabbix object id 84 | def get_or_create(data) 85 | log "[DEBUG] Call get_or_create with parameters: #{data.inspect}" 86 | 87 | unless (id = get_id(description: data[:description], hostid: data[:hostid])) 88 | id = create(data) 89 | end 90 | id 91 | end 92 | 93 | # Create or update Trigger object using Zabbix API 94 | # 95 | # @param data [Hash] Needs to include description and hostid to properly identify Triggers via Zabbix API 96 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 97 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 98 | # @return [Integer] Zabbix object id 99 | def create_or_update(data) 100 | triggerid = get_id(description: data[:description], hostid: data[:hostid]) 101 | 102 | triggerid ? update(data.merge(triggerid: triggerid)) : create(data) 103 | end 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /spec/template.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'template' do 4 | before :all do 5 | @hostgroup = gen_name 'hostgroup' 6 | @hostgroupid = zbx.hostgroups.create(name: @hostgroup) 7 | end 8 | 9 | context 'when name not exists' do 10 | before do 11 | @template = gen_name 'template' 12 | end 13 | 14 | describe 'create' do 15 | it 'should return integer id' do 16 | templateid = zbx.templates.create( 17 | host: @template, 18 | groups: [groupid: @hostgroupid] 19 | ) 20 | expect(templateid).to be_kind_of(Integer) 21 | end 22 | end 23 | 24 | describe 'get_id' do 25 | it 'should return nil' do 26 | expect(zbx.templates.get_id(host: @template)).to be_kind_of(NilClass) 27 | end 28 | end 29 | end 30 | 31 | context 'when name exists' do 32 | before :all do 33 | @template = gen_name 'template' 34 | @templateid = zbx.templates.create( 35 | host: @template, 36 | groups: [groupid: @hostgroupid] 37 | ) 38 | end 39 | 40 | describe 'get_or_create' do 41 | it 'should return id of template' do 42 | expect( 43 | zbx.templates.get_or_create( 44 | host: @template, 45 | groups: [groupid: @hostgroupid] 46 | ) 47 | ).to eq @templateid 48 | end 49 | end 50 | 51 | describe 'get_full_data' do 52 | it 'should contains created template' do 53 | expect(zbx.templates.get_full_data(host: @template)[0]).to include('host' => @template) 54 | end 55 | end 56 | 57 | describe 'get_id' do 58 | it 'should return id of template' do 59 | expect(zbx.templates.get_id(host: @template)).to eq @templateid 60 | end 61 | end 62 | 63 | describe 'all' do 64 | it 'should contains template' do 65 | expect(zbx.templates.all).to include(@template => @templateid.to_s) 66 | end 67 | end 68 | 69 | describe 'delete' do 70 | it 'should return id' do 71 | template = gen_name 'template' 72 | templateid = zbx.templates.create( 73 | host: template, 74 | groups: [groupid: @hostgroupid] 75 | ) 76 | expect(zbx.templates.delete(templateid)).to eq templateid 77 | end 78 | end 79 | 80 | context 'host related operations' do 81 | before :all do 82 | @host = gen_name 'host' 83 | @hostid = zbx.hosts.create( 84 | host: @host, 85 | interfaces: [ 86 | { 87 | type: 1, 88 | main: 1, 89 | ip: '10.20.48.88', 90 | dns: '', 91 | port: '10050', 92 | useip: 1 93 | } 94 | ], 95 | groups: [groupid: @hostgroupid] 96 | ) 97 | end 98 | 99 | context 'not linked with host' do 100 | describe 'mass_update' do 101 | it 'should return true' do 102 | expect( 103 | zbx.templates.mass_update( 104 | hosts_id: [@hostid], 105 | templates_id: [@templateid] 106 | ) 107 | ).to be true 108 | end 109 | end 110 | end 111 | 112 | context 'linked with host' do 113 | before :all do 114 | zbx.templates.mass_update( 115 | hosts_id: [@hostid], 116 | templates_id: [@templateid] 117 | ) 118 | end 119 | 120 | describe 'get_ids_by_host' do 121 | it 'should contains id of linked template' do 122 | tmpl_array = zbx.templates.get_ids_by_host( 123 | hostids: [@hostid] 124 | ) 125 | expect(tmpl_array).to be_kind_of(Array) 126 | expect(tmpl_array).to include @templateid.to_s 127 | end 128 | end 129 | 130 | describe 'mass_add' do 131 | it 'should return true' do 132 | expect( 133 | zbx.templates.mass_add( 134 | hosts_id: [@hostid], 135 | templates_id: [@templateid] 136 | ) 137 | ).to be_kind_of(TrueClass) 138 | end 139 | end 140 | 141 | describe 'mass_remove' do 142 | it 'should return true' do 143 | expect( 144 | zbx.templates.mass_remove( 145 | hosts_id: [@hostid], 146 | templates_id: [@templateid] 147 | ) 148 | ).to be true 149 | end 150 | end 151 | end 152 | end 153 | end 154 | end 155 | -------------------------------------------------------------------------------- /spec/zabbixapi/classes/screens_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Screens' do 4 | let(:screens_mock) { ZabbixApi::Screens.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.method_name' do 8 | subject { screens_mock.method_name } 9 | 10 | it { is_expected.to eq 'screen' } 11 | end 12 | 13 | describe '.identify' do 14 | subject { screens_mock.identify } 15 | 16 | it { is_expected.to eq 'name' } 17 | end 18 | 19 | describe '.delete' do 20 | subject { screens_mock.delete(data) } 21 | 22 | let(:data) { { testidentify: 222 } } 23 | let(:result) { { 'screenids' => ['1'] } } 24 | let(:identify) { 'testidentify' } 25 | let(:method_name) { 'testmethod' } 26 | 27 | before do 28 | allow(screens_mock).to receive(:log) 29 | allow(screens_mock).to receive(:identify).and_return(identify) 30 | allow(screens_mock).to receive(:method_name).and_return(method_name) 31 | allow(client).to receive(:api_request).with( 32 | method: 'screen.delete', 33 | params: [data] 34 | ).and_return(result) 35 | end 36 | 37 | context 'when result is not empty' do 38 | it 'returns the id of first screen' do 39 | expect(subject).to eq 1 40 | end 41 | end 42 | 43 | context 'when result is empty' do 44 | let(:result) { [] } 45 | 46 | it { is_expected.to be_nil } 47 | end 48 | end 49 | 50 | describe '.get_or_create_for_host' do 51 | subject { screens_mock.get_or_create_for_host(data) } 52 | 53 | let(:data) { { screen_name: screen_name, graphids: graphids } } 54 | let(:screen_name) { 'testscreen' } 55 | let(:result) { { 'screenids' => ['1'] } } 56 | let(:graphids) { [2222] } 57 | let(:method_name) { 'testmethod' } 58 | let(:existing_screen_id) { 1212 } 59 | let(:newly_created_screen_id) { 3434 } 60 | 61 | before do 62 | allow(screens_mock).to receive(:get_id).with(name: screen_name).and_return(existing_screen_id) 63 | end 64 | 65 | context 'when screen already exist' do 66 | it 'returns the id of first screen' do 67 | expect(subject).to eq existing_screen_id 68 | end 69 | end 70 | 71 | context "when screen doesn't exist" do 72 | let(:existing_screen_id) { nil } 73 | let(:index) { 0 } 74 | let(:screenitems) do 75 | [ 76 | { 77 | resourcetype: 0, 78 | resourceid: 2222, 79 | x: (index % hsize).to_i, 80 | y: (index % graphids.size / hsize).to_i, 81 | valign: valign, 82 | halign: halign, 83 | rowspan: rowspan, 84 | colspan: colspan, 85 | height: height, 86 | width: width 87 | } 88 | ] 89 | end 90 | 91 | before do 92 | allow(screens_mock).to receive(:create).with( 93 | name: screen_name, 94 | hsize: hsize, 95 | vsize: vsize, 96 | screenitems: screenitems 97 | ).and_return(newly_created_screen_id) 98 | end 99 | 100 | context 'when data do not have all value for request' do 101 | let(:hsize) { 3 } 102 | let(:valign) { 2 } 103 | let(:halign) { 2 } 104 | let(:rowspan) { 1 } 105 | let(:colspan) { 1 } 106 | let(:height) { 320 } 107 | let(:width) { 200 } 108 | let(:vsize) { [1, (graphids.size / hsize).to_i].max } 109 | 110 | it 'creates screen with default and rest of provided values' do 111 | expect(subject).to eq newly_created_screen_id 112 | end 113 | end 114 | 115 | context 'when data do not have all value for request' do 116 | let(:hsize) { 3 } 117 | let(:valign) { 2 } 118 | let(:halign) { 2 } 119 | let(:rowspan) { 1 } 120 | let(:colspan) { 1 } 121 | let(:height) { 320 } 122 | let(:width) { 200 } 123 | let(:vsize) { 5 } 124 | 125 | let(:data) do 126 | { 127 | screen_name: screen_name, 128 | graphids: graphids, 129 | hsize: hsize, 130 | valign: valign, 131 | halign: halign, 132 | rowspan: rowspan, 133 | colspan: colspan, 134 | height: height, 135 | width: width, 136 | vsize: vsize 137 | } 138 | end 139 | 140 | it 'creates screen with values provided in data' do 141 | expect(subject).to eq newly_created_screen_id 142 | end 143 | end 144 | end 145 | end 146 | end 147 | -------------------------------------------------------------------------------- /lib/zabbixapi/classes/mediatypes.rb: -------------------------------------------------------------------------------- 1 | class ZabbixApi 2 | class Mediatypes < Basic 3 | # The method name used for interacting with MediaTypes via Zabbix API 4 | # 5 | # @return [String] 6 | def method_name 7 | 'mediatype' 8 | end 9 | 10 | # The id field name used for identifying specific MediaType objects via Zabbix API 11 | # 12 | # @return [String] 13 | def identify 14 | 'name' 15 | end 16 | 17 | # The default options used when creating MediaType objects via Zabbix API 18 | # 19 | # @return [Hash] 20 | def default_options 21 | { 22 | name: '', # Name 23 | description: '', # Description 24 | type: 0, # 0 - Email, 1 - External script, 2 - SMS, 3 - Jabber, 100 - EzTexting 25 | smtp_server: '', 26 | smtp_helo: '', 27 | smtp_email: '', # Email address of Zabbix server 28 | exec_path: '', # Name of external script 29 | gsm_modem: '', # Serial device name of GSM modem 30 | username: '', # Jabber user name used by Zabbix server 31 | passwd: '' # Jabber password used by Zabbix server 32 | } 33 | end 34 | 35 | # def log(message) 36 | # STDERR.puts 37 | # STDERR.puts message.to_s 38 | # STDERR.puts 39 | # end 40 | 41 | # Update MediaType object using API 42 | # 43 | # @param data [Hash] Should include object's id field name (identify) and id value 44 | # @param force [Boolean] Whether to force an object update even if provided data matches Zabbix 45 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 46 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 47 | # @return [Integer] The object id if a single object is created 48 | # @return [Boolean] True/False if multiple objects are created 49 | def update(data, force = false) 50 | log "[DEBUG] Call update with parameters: #{data.inspect}" 51 | if data[key.to_sym].nil? 52 | data[key.to_sym] = get_id(data) 53 | log "[DEBUG] Enriched data with id: #{data.inspect}" 54 | end 55 | dump = {} 56 | dump_by_id(key.to_sym => data[key.to_sym]).each do |item| 57 | dump = symbolize_keys(item) if item[key].to_i == data[key.to_sym].to_i 58 | end 59 | if hash_equals?(dump, data) && !force 60 | log "[DEBUG] Equal keys #{dump} and #{data}, skip update" 61 | data[key.to_sym].to_i 62 | else 63 | data_update = [data] 64 | result = @client.api_request(method: "#{method_name}.update", params: data_update) 65 | parse_keys result 66 | end 67 | end 68 | 69 | # Get MediaType object id from API based on provided data 70 | # 71 | # @param data [Hash] 72 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call or missing object's id field name (identify). 73 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 74 | # @return [Integer] Zabbix object id 75 | def get_id(data) 76 | log "[DEBUG] Call get_id with parameters: #{data.inspect}" 77 | # symbolize keys if the user used string keys instead of symbols 78 | data = symbolize_keys(data) if data.key?(identify) 79 | # raise an error if identify name was not supplied 80 | name = data[identify.to_sym] 81 | raise ApiError.new("#{identify} not supplied in call to get_id, #{data} (#{method_name})") if name.nil? 82 | 83 | result = @client.api_request( 84 | method: "#{method_name}.get", 85 | params: { 86 | filter: {name: name}, 87 | output: [key, identify] 88 | } 89 | ) 90 | id = nil 91 | result.each { |item| id = item[key].to_i if item[identify] == data[identify.to_sym] } 92 | id 93 | end 94 | 95 | # Create or update MediaType object using API 96 | # 97 | # @param data [Hash] Should include object's id field name (identify) and id value 98 | # @raise [ApiError] Error returned when there is a problem with the Zabbix API call. 99 | # @raise [HttpError] Error raised when HTTP status from Zabbix Server response is not a 200 OK. 100 | # @return [Integer] The object id if a single object is created 101 | # @return [Boolean] True/False if multiple objects are created 102 | def create_or_update(data) 103 | log "[DEBUG] Call create_or_update with parameters: #{data.inspect}" 104 | 105 | id = get_id(identify.to_sym => data[identify.to_sym]) 106 | id ? update(data.merge(key.to_sym => id.to_s)) : create(data) 107 | end 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /spec/zabbixapi/basic/basic_func_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'ZabbixApi::Basic' do 4 | let(:basic_mock) { ZabbixApi::Basic.new(client) } 5 | let(:client) { double } 6 | 7 | describe '.log' do 8 | subject { basic_mock.log(message) } 9 | 10 | let(:message) { 'test-message' } 11 | let(:debug) { true } 12 | let(:client) { instance_double('ZabbixApi::Client', options: { debug: debug }) } 13 | 14 | context 'when debug is set to true' do 15 | it 'prints the message' do 16 | expect(basic_mock).to receive(:puts).with(message) 17 | subject 18 | end 19 | end 20 | 21 | context 'when debug is set to false' do 22 | let(:debug) { false } 23 | 24 | it 'does not print the message' do 25 | expect(basic_mock).not_to receive(:puts).with(message) 26 | subject 27 | end 28 | end 29 | end 30 | 31 | describe '.symbolize_keys' do 32 | subject { basic_mock.symbolize_keys(object) } 33 | 34 | let(:object) { { 'test' => { 'one' => 1, 'two' => [1, 2] } } } 35 | let(:symbolized_object) { { test: { one: 1, two: [1, 2] } } } 36 | 37 | context 'when hash with string keys is passed' do 38 | it 'converts all the string keys to symbol' do 39 | expect(subject).to eq symbolized_object 40 | end 41 | end 42 | 43 | context 'when string object is passed' do 44 | let(:object) { 'test-this' } 45 | let(:symbolized_object) { 'test-this' } 46 | 47 | it 'returns the same object back' do 48 | expect(subject).to eq symbolized_object 49 | end 50 | end 51 | 52 | context 'when nil object is passed' do 53 | let(:object) { nil } 54 | let(:symbolized_object) { nil } 55 | 56 | it 'returns nil back' do 57 | expect(subject).to eq symbolized_object 58 | end 59 | end 60 | end 61 | 62 | describe '.normalize_hash' do 63 | subject { basic_mock.normalize_hash(hash) } 64 | 65 | let(:hash) { { 'one' => 1, 'two' => [1, 2] } } 66 | let(:hash_dup) { { 'one' => 1, 'two' => [1, 2] } } 67 | let(:symbolized_object) { { 'one' => '1', 'two' => normalized_array } } 68 | let(:normalized_array) { %w[1 2] } 69 | 70 | before do 71 | allow(basic_mock).to receive(:normalized_array).with([1, 2]).and_return(normalized_array) 72 | allow(hash).to receive(:dup).and_return(hash_dup) 73 | end 74 | 75 | context 'when hash is passed' do 76 | it 'normalizes the hash' do 77 | expect(subject).to eq symbolized_object 78 | end 79 | 80 | it 'duplicates the hash before modifying' do 81 | expect(hash).to receive(:dup) 82 | subject 83 | end 84 | end 85 | 86 | context 'when passed hash contains key hostid' do 87 | let(:hash) { { one: 1, two: [1, 2], hostid: 3 } } 88 | let(:hash_dup) { { one: 1, two: [1, 2], hostid: 3 } } 89 | let(:symbolized_object) { { one: '1', two: %w[1 2] } } 90 | 91 | it 'deletes hostid from hash during normalization' do 92 | expect(subject).to eq symbolized_object 93 | end 94 | end 95 | end 96 | 97 | describe '.normalize_array' do 98 | subject { basic_mock.normalize_array(array) } 99 | 100 | let(:array) { ['one', [2, 3], { four: 5 }] } 101 | let(:normalized_array) { ['one', %w[2 3], normalized_hash] } 102 | let(:normalized_hash) { { four: '5' } } 103 | 104 | before do 105 | allow(basic_mock).to receive(:normalize_hash).with(four: 5).and_return(normalized_hash) 106 | end 107 | 108 | context 'when array is passed' do 109 | it 'normalizes the array' do 110 | expect(subject).to eq normalized_array 111 | end 112 | end 113 | end 114 | 115 | describe '.parse_keys' do 116 | subject { basic_mock.parse_keys(data) } 117 | 118 | let(:data) { { test: ['1'] } } 119 | let(:expected) { 1 } 120 | 121 | before do 122 | allow(basic_mock).to receive(:keys).and_return(:test) 123 | end 124 | 125 | context 'when hash is passed' do 126 | it 'returns the object id' do 127 | expect(subject).to eq expected 128 | end 129 | end 130 | 131 | context 'when passed hash is empty' do 132 | let(:data) { {} } 133 | 134 | it { is_expected.to be_nil } 135 | end 136 | 137 | context 'when TrueClass is passed' do 138 | let(:data) { true } 139 | 140 | it { is_expected.to be_truthy } 141 | end 142 | 143 | context 'when FalseClass is passed' do 144 | let(:data) { false } 145 | 146 | it { is_expected.to be_falsy } 147 | end 148 | end 149 | 150 | describe '.merge_params' do 151 | subject { basic_mock.merge_params(first_hash, second_hash) } 152 | 153 | let(:first_hash) { { test1: 1 } } 154 | let(:first_hash_dup) { { test1: 1 } } 155 | let(:second_hash) { { test2: 2 } } 156 | let(:expected) { { test1: 1, test2: 2 } } 157 | 158 | before { allow(first_hash).to receive(:dup).and_return(first_hash_dup) } 159 | 160 | it { is_expected.to eq expected } 161 | 162 | it 'merged two hashes in new hash object' do 163 | expect(first_hash).to receive(:dup) 164 | subject 165 | end 166 | end 167 | end 168 | --------------------------------------------------------------------------------