├── spec ├── spec_helper.rb └── zabbix_web_apache_spec.rb ├── templates ├── default │ ├── mongo.ini.erb │ ├── user_params.conf.erb │ ├── zabbix-java-gateway │ │ └── zabbix_java_gateway.conf.erb │ ├── zabbix_nginx.erb │ ├── zabbix_java_proxy_settings.sh.erb │ ├── zabbix_java_proxy.init.erb │ ├── zabbix_web.conf.php.erb │ ├── zabbix_agentd.conf.erb │ ├── zabbix_server.conf.erb │ ├── zabbix_server.init.erb │ ├── web_app.conf.erb │ ├── zabbix_server.init-rh.erb │ ├── zabbix_agentd.init.erb │ └── zabbix_agentd.init-rh.erb └── windows │ └── zabbix_agentd.conf.erb ├── Berksfile ├── recipes ├── web.rb ├── _providers_common.rb ├── agent_common.rb ├── default.rb ├── server.rb ├── _agent_common_directories.rb ├── _agent_common_user.rb ├── _agent_common_service.rb ├── agent_prebuild.rb ├── agent_chocolatey.rb ├── server_common.rb ├── agent.rb ├── agent_source.rb ├── common.rb ├── firewall.rb ├── java_gateway.rb ├── web_apache.rb ├── web_nginx.rb ├── database.rb ├── agent_registration.rb └── server_source.rb ├── .travis.yml ├── files └── default │ ├── zabbix-java-gateway │ ├── settings.sh │ ├── zabbix_java_gateway.logback.xml │ ├── init.debian │ └── init.rhel │ └── tests │ └── minitest │ ├── support │ └── helpers.rb │ ├── default_test.rb │ └── server_source_test.rb ├── resources ├── hostgroup.rb ├── interface.rb ├── host_group.rb ├── api_call.rb ├── application.rb ├── template.rb ├── trigger_dependency.rb ├── source.rb ├── trigger.rb ├── database.rb ├── host.rb ├── user.rb ├── graph.rb ├── discovery_rule.rb └── item.rb ├── test └── kitchen │ ├── cookbooks │ └── zabbix_test │ │ ├── metadata.rb │ │ └── recipes │ │ ├── default.rb │ │ └── server_source.rb │ └── Kitchenfile ├── libraries ├── chef_zabbix.rb ├── zabbix_connection.rb ├── chef_zabbix_errors.rb ├── chef_zabbix_enumerations.rb └── chef_zabbix_api.rb ├── Gemfile ├── .gitignore ├── .kitchen.yml ├── providers ├── database_oracle.rb ├── api_call.rb ├── hostgroup.rb ├── template.rb ├── application.rb ├── host_group.rb ├── trigger.rb ├── discovery_rule.rb ├── interface.rb ├── trigger_dependency.rb ├── graph.rb ├── item.rb ├── source.rb ├── host.rb.good ├── database_my_sql.rb ├── database_postgres.rb ├── user.rb └── host.rb ├── attributes ├── agent_prebuild.rb ├── database.rb ├── web.rb ├── default.rb ├── server.rb └── agent.rb ├── .rubocop.yml ├── metadata.rb ├── chefignore ├── Rakefile ├── Vagrantfile ├── LICENSE └── README.md /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | -------------------------------------------------------------------------------- /templates/default/mongo.ini.erb: -------------------------------------------------------------------------------- 1 | extension=mongo.so -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | source 'https://api.berkshelf.com' 2 | 3 | metadata 4 | -------------------------------------------------------------------------------- /recipes/web.rb: -------------------------------------------------------------------------------- 1 | include_recipe "zabbix::web_#{node['zabbix']['web']['install_method']}" 2 | -------------------------------------------------------------------------------- /recipes/_providers_common.rb: -------------------------------------------------------------------------------- 1 | chef_gem 'zabbixapi' do 2 | action :install 3 | version '~> 0.6.3' 4 | end 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | bundler_args: --without integration 3 | rvm: 4 | - 1.9.3 5 | - 2.0.0 6 | script: bundle exec rake travis 7 | -------------------------------------------------------------------------------- /files/default/zabbix-java-gateway/settings.sh: -------------------------------------------------------------------------------- 1 | # Please see /etc/zabbix/zabbix_java_gateway.conf for the 2 | # main Zabbix java gateway settings. 3 | -------------------------------------------------------------------------------- /resources/hostgroup.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :server_connection, :kind_of => Hash, :required => true 5 | attribute :parameters, :kind_of => Hash, :required => true 6 | -------------------------------------------------------------------------------- /resources/interface.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :server_connection, :kind_of => Hash, :required => true 5 | attribute :parameters, :kind_of => Hash, :required => true 6 | -------------------------------------------------------------------------------- /recipes/agent_common.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'zabbix::_agent_common_user' 2 | include_recipe 'zabbix::common' 3 | include_recipe 'zabbix::_agent_common_directories' 4 | include_recipe 'zabbix::_agent_common_service' 5 | -------------------------------------------------------------------------------- /files/default/tests/minitest/support/helpers.rb: -------------------------------------------------------------------------------- 1 | module Helpers 2 | module Zabbix 3 | include MiniTest::Chef::Assertions 4 | include MiniTest::Chef::Context 5 | include MiniTest::Chef::Resources 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /resources/host_group.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attr_accessor :exists 5 | 6 | attribute :group, :kind_of => String, :name_attribute => true 7 | attribute :server_connection, :kind_of => Hash, :default => {} 8 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: default 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | include_recipe 'zabbix::agent' 11 | -------------------------------------------------------------------------------- /test/kitchen/cookbooks/zabbix_test/metadata.rb: -------------------------------------------------------------------------------- 1 | maintainer 'Efactures' 2 | maintainer_email 'nacer.laradji@gmail.com' 3 | license 'Apache 2.0' 4 | description 'This cookbook is used with test-kitchen to test the parent, zabbix cookbook.' 5 | version '1.0.0' 6 | -------------------------------------------------------------------------------- /resources/api_call.rb: -------------------------------------------------------------------------------- 1 | actions :call 2 | default_action :call 3 | 4 | attribute :server_connection, :kind_of => Hash, :required => true 5 | attribute :method, :kind_of => [String, Symbol], :required => true 6 | attribute :parameters, :kind_of => Hash, :required => true 7 | -------------------------------------------------------------------------------- /resources/application.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :name, :kind_of => String, :name_attribute => true 5 | attribute :server_connection, :kind_of => Hash, :required => true 6 | attribute :template, :kind_of => String, :required => true 7 | -------------------------------------------------------------------------------- /test/kitchen/cookbooks/zabbix_test/recipes/default.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix-test 3 | # Recipe:: default 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | 9 | include_recipe 'zabbix::default' 10 | -------------------------------------------------------------------------------- /resources/template.rb: -------------------------------------------------------------------------------- 1 | actions :create # , :delete 2 | default_action :create 3 | 4 | attribute :name, :kind_of => String, :name_attribute => true 5 | attribute :server_connection, :kind_of => Hash, :required => true 6 | attribute :group, :kind_of => String, :default => 'Templates' 7 | -------------------------------------------------------------------------------- /recipes/server.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: server 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | include_recipe "zabbix::server_#{node['zabbix']['server']['install_method']}" 11 | -------------------------------------------------------------------------------- /libraries/chef_zabbix.rb: -------------------------------------------------------------------------------- 1 | class Chef 2 | module Zabbix 3 | class << self 4 | def default_download_url(branch, version) 5 | "http://downloads.sourceforge.net/project/zabbix/#{branch}/#{version}/zabbix-#{version}.tar.gz" 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /templates/default/user_params.conf.erb: -------------------------------------------------------------------------------- 1 | # The first rule of this file is: Do not edit. 2 | # The second rule of this file is: Do not edit. 3 | # Created by chef 4 | <% node['zabbix']['agent']['user_parameter'].each do |user_parameter| -%> 5 | UserParameter=<%= user_parameter %> 6 | <% end -%> 7 | -------------------------------------------------------------------------------- /resources/trigger_dependency.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :trigger_name, :kind_of => String, :name_attribute => true 5 | attribute :dependency_name, :kind_of => String, :required => true 6 | 7 | attribute :server_connection, :kind_of => Hash, :required => true 8 | -------------------------------------------------------------------------------- /test/kitchen/Kitchenfile: -------------------------------------------------------------------------------- 1 | cookbook "zabbix" do 2 | configuration "default" 3 | configuration "server_source" 4 | exclude :platform => 'centos' 5 | exclude :platform => 'debian' 6 | exclude :platform => 'redhat' 7 | run_list_extras ['mysql::server'] 8 | lint(:ignore => ["FC017"]) 9 | 10 | runtimes [] 11 | 12 | end 13 | -------------------------------------------------------------------------------- /templates/default/zabbix-java-gateway/zabbix_java_gateway.conf.erb: -------------------------------------------------------------------------------- 1 | # 2 | # Main Zabbix Java Gateway configuration file managed by Chef 3 | # 4 | LISTEN_IP="<%= @java_gateway_listen_ip %>" 5 | LISTEN_PORT="<%= @java_gateway_listen_port %>" 6 | PID_FILE="/var/run/zabbix/zabbix_java_gateway.pid" 7 | START_POLLERS=<%= @java_gateway_pollers %> 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rake' 4 | 5 | group :test do 6 | gem 'foodcritic', '~> 3.0' 7 | gem 'rubocop', '~> 0.24.0' 8 | gem 'chefspec', '~> 3.4.0' 9 | end 10 | 11 | group :integration do 12 | gem 'berkshelf', '~> 3.1' 13 | gem 'test-kitchen', '~> 1.1' 14 | gem 'kitchen-vagrant', '~> 0.14' 15 | end 16 | -------------------------------------------------------------------------------- /test/kitchen/cookbooks/zabbix_test/recipes/server_source.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix-test 3 | # Recipe:: server_source 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | 9 | node.normal['zabbix']['server']['install'] = true 10 | include_recipe 'zabbix::server_source' 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .rvmrc 6 | .yardoc 7 | /Gemfile.lock 8 | _yardoc 9 | /coverage 10 | /doc/ 11 | /pkg 12 | /spec/reports 13 | /Berksfile* 14 | tmp 15 | *~ 16 | *.tar* 17 | \#* 18 | .DS_Store 19 | /spec/knife.rb 20 | /spec/*.pem 21 | /features/config.yml 22 | *.sw[op] 23 | \.\#* 24 | rerun.txt 25 | .rspec 26 | .kitchen 27 | .vagrant 28 | vendor 29 | -------------------------------------------------------------------------------- /files/default/tests/minitest/default_test.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../support/helpers.rb', __FILE__) 2 | 3 | describe 'zabbix::default' do 4 | include Helpers::Zabbix 5 | 6 | it 'creates a user for the daemon to run as' do 7 | user('zabbix').must_exist 8 | end 9 | 10 | it 'runs as a daemon' do 11 | service('zabbix_agentd').must_be_running 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /.kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | 5 | driver_config: 6 | require_chef_omnibus: true 7 | 8 | platforms: 9 | - name: ubuntu-10.04 10 | - name: ubuntu-12.04 11 | - name: centos-6.4 12 | - name: centos-5.9 13 | 14 | provisioner: 15 | name: chef_zero 16 | 17 | suites: 18 | - name: default 19 | run_list: 20 | - "recipe[zabbix::default]" 21 | attributes: 22 | -------------------------------------------------------------------------------- /files/default/tests/minitest/server_source_test.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../support/helpers.rb', __FILE__) 2 | 3 | describe 'zabbix::server_source' do 4 | include Helpers::Zabbix 5 | 6 | it 'creates a user for the daemon to run as' do 7 | user('zabbix').must_exist 8 | end 9 | 10 | it 'runs as a daemon' do 11 | service('zabbix_server').must_be_running 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /recipes/_agent_common_directories.rb: -------------------------------------------------------------------------------- 1 | root_dirs = [ 2 | node['zabbix']['agent']['include_dir'] 3 | ] 4 | 5 | # Create root folders 6 | root_dirs.each do |dir| 7 | directory dir do 8 | unless node['platform'] == 'windows' 9 | owner 'root' 10 | group 'root' 11 | mode '755' 12 | end 13 | recursive true 14 | notifies :restart, 'service[zabbix_agentd]' 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /providers/database_oracle.rb: -------------------------------------------------------------------------------- 1 | # Stub Oracle provider 2 | 3 | use_inline_resources 4 | 5 | def whyrun_supported? 6 | true 7 | end 8 | 9 | def load_current_resource 10 | true 11 | end 12 | 13 | def database_exists?(_dbname, _host, _port, _root_username, _root_password) 14 | true 15 | end 16 | 17 | action :create do 18 | Chef::Log.info 'Oracle provider is a stub - does not do anything yet!' 19 | end 20 | 21 | def create_new_database 22 | true 23 | end 24 | -------------------------------------------------------------------------------- /attributes/agent_prebuild.rb: -------------------------------------------------------------------------------- 1 | include_attribute 'zabbix::agent' 2 | 3 | default['zabbix']['agent']['prebuild']['arch'] = node['kernel']['machine'] == 'x86_64' ? 'amd64' : 'i386' 4 | default['zabbix']['agent']['prebuild']['url'] = "http://www.zabbix.com/downloads/#{node['zabbix']['agent']['version']}/zabbix_agents_#{node['zabbix']['agent']['version']}.linux2_6.#{node['zabbix']['agent']['prebuild']['arch']}.tar.gz" 5 | default['zabbix']['agent']['checksum'] = 'ec3d19dcdf484f60bc4583a84a39a3bd59c34ba1e7f8abf9438606eb14b90211' 6 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | Include: 3 | - Berksfile 4 | - Gemfile 5 | - Rakefile 6 | - Thorfile 7 | - Guardfile 8 | Exclude: 9 | - vendor/**/* 10 | 11 | ClassLength: 12 | Enabled: false 13 | Documentation: 14 | Enabled: false 15 | Encoding: 16 | Enabled: false 17 | HashSyntax: 18 | Enabled: false 19 | LineLength: 20 | Enabled: false 21 | MethodLength: 22 | Enabled: false 23 | SignalException: 24 | Enabled: false 25 | TrailingComma: 26 | Enabled: false 27 | WordArray: 28 | Enabled: false 29 | -------------------------------------------------------------------------------- /resources/source.rb: -------------------------------------------------------------------------------- 1 | actions :extract_only, :install_server, :install_agent 2 | default_action :extract_only 3 | 4 | attribute :source_url, :kind_of => String, :required => true 5 | 6 | attribute :branch, :kind_of => String, :required => true 7 | attribute :version, :kind_of => String, :required => true 8 | 9 | attribute :code_dir, :kind_of => String, :required => true 10 | attribute :target_dir, :kind_of => String, :required => true 11 | 12 | attribute :install_dir, :kind_of => String, :default => '' 13 | attribute :configure_options, :kind_of => String, :default => '' 14 | -------------------------------------------------------------------------------- /providers/api_call.rb: -------------------------------------------------------------------------------- 1 | action :call do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | connection.query( 4 | :method => new_resource.method, 5 | :params => new_resource.parameters 6 | ) 7 | end 8 | new_resource.updated_by_last_action(true) 9 | end 10 | 11 | def load_current_resource 12 | run_context.include_recipe 'zabbix::_providers_common' 13 | require 'zabbixapi' 14 | end 15 | 16 | def validate_parameters(parameters) 17 | Chef::Log.error("#{parameter} isn't an Hash") unless parameters.is_a?(Hash) 18 | end 19 | -------------------------------------------------------------------------------- /recipes/_agent_common_user.rb: -------------------------------------------------------------------------------- 1 | # Manage user and group 2 | if node['zabbix']['agent']['user'] 3 | # Create zabbix group 4 | group node['zabbix']['agent']['group'] do 5 | gid node['zabbix']['agent']['gid'] if node['zabbix']['agent']['gid'] 6 | system true 7 | end 8 | 9 | # Create zabbix User 10 | user node['zabbix']['agent']['user'] do 11 | home node['zabbix']['install_dir'] 12 | shell node['zabbix']['agent']['shell'] 13 | uid node['zabbix']['agent']['uid'] if node['zabbix']['agent']['uid'] 14 | gid node['zabbix']['agent']['gid'] || node['zabbix']['agent']['group'] 15 | system true 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /resources/trigger.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :name, :kind_of => String, :name_attribute => true 5 | attribute :expression, :kind_of => String, :required => true 6 | attribute :priority, :kind_of => Zabbix::API::TriggerPriority, :required => true 7 | attribute :description, :kind_of => String 8 | attribute :status, :kind_of => Zabbix::API::TriggerStatus, :default => Zabbix::API::TriggerStatus.active 9 | attribute :type, :kind_of => Zabbix::API::TriggerType, :default => Zabbix::API::TriggerType.normal 10 | 11 | attribute :prototype, :kind_of => [TrueClass, FalseClass], :default => false 12 | attribute :server_connection, :kind_of => Hash, :required => true 13 | -------------------------------------------------------------------------------- /templates/default/zabbix_nginx.erb: -------------------------------------------------------------------------------- 1 | server { 2 | 3 | listen <%= @web_port %>; 4 | index index.php; 5 | root <%= @web_dir %>; 6 | server_name "<%=@server_name%>"; 7 | 8 | access_log /var/log/nginx/zabbix.access.log; 9 | 10 | location ~ .*\.php$ { 11 | include /etc/nginx/fastcgi_params; 12 | fastcgi_read_timeout 60000; 13 | fastcgi_buffers 512 16k; 14 | fastcgi_pass <%= @fastcgi_listen %>; 15 | fastcgi_index index.php; 16 | <% php_values = @php_settings.map { |name, value| "#{name}=#{value}"}.join("\n") %> 17 | fastcgi_param PHP_VALUE "<%=php_values%>"; 18 | fastcgi_param SCRIPT_FILENAME <%=@web_dir%>$fastcgi_script_name; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /attributes/database.rb: -------------------------------------------------------------------------------- 1 | default['zabbix']['database']['install_method'] = 'mysql' 2 | default['zabbix']['database']['dbname'] = 'zabbix' 3 | default['zabbix']['database']['dbuser'] = 'zabbix' 4 | default['zabbix']['database']['dbhost'] = 'localhost' 5 | default['zabbix']['database']['dbpassword'] = nil 6 | default['zabbix']['database']['dbport'] = '3306' 7 | default['zabbix']['database']['allowed_user_hosts'] = 'localhost' 8 | 9 | default['zabbix']['database']['rds_master_user'] = nil 10 | default['zabbix']['database']['rds_master_password'] = nil 11 | 12 | # SCHEMA is relevant only for IBM_DB2 database 13 | default['zabbix']['database']['schema'] = nil 14 | -------------------------------------------------------------------------------- /providers/hostgroup.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | hostgroup_id = connection.query( 4 | :method => 'hostgroup.get', 5 | :params => { 6 | :filter => { 7 | :name => new_resource.parameters[:name] 8 | } 9 | } 10 | ) 11 | if hostgroup_id.size == 0 12 | connection.query( 13 | :method => 'hostgroup.create', 14 | :params => new_resource.parameters 15 | ) 16 | end 17 | end 18 | new_resource.updated_by_last_action(true) 19 | end 20 | 21 | def load_current_resource 22 | run_context.include_recipe 'zabbix::_providers_common' 23 | require 'zabbixapi' 24 | end 25 | -------------------------------------------------------------------------------- /recipes/_agent_common_service.rb: -------------------------------------------------------------------------------- 1 | # Manage Agent service 2 | case node['zabbix']['agent']['init_style'] 3 | when 'sysvinit' 4 | template '/etc/init.d/zabbix_agentd' do 5 | source value_for_platform_family(['rhel'] => 'zabbix_agentd.init-rh.erb', 'default' => 'zabbix_agentd.init.erb') 6 | owner 'root' 7 | group 'root' 8 | mode '754' 9 | end 10 | 11 | # Define zabbix_agentd service 12 | service 'zabbix_agentd' do 13 | supports :status => true, :start => true, :stop => true, :restart => true 14 | action :nothing 15 | end 16 | when 'windows' 17 | service 'zabbix_agentd' do 18 | service_name 'Zabbix Agent' 19 | provider Chef::Provider::Service::Windows 20 | supports :restart => true 21 | action :nothing 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /recipes/agent_prebuild.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: agent_prebuild 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | include_recipe 'zabbix::agent_common' 11 | 12 | # Install prerequisite RPM 13 | package 'redhat-lsb' if node['platform_family'] == 'rhel' 14 | 15 | ark 'zabbix_agent' do 16 | name 'zabbix' 17 | url node['zabbix']['agent']['prebuild']['url'] 18 | owner node['zabbix']['agent']['user'] 19 | group node['zabbix']['agent']['group'] 20 | action :put 21 | path '/opt' 22 | strip_components 0 23 | has_binaries ['bin/zabbix_sender', 'bin/zabbix_get', 'sbin/zabbix_agent', 'sbin/zabbix_agentd'] 24 | notifies :restart, 'service[zabbix_agentd]' 25 | checksum node['zabbix']['agent']['checksum'] 26 | end 27 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'zabbix' 2 | maintainer 'Nacer Laradji' 3 | maintainer_email 'nacer.laradji@gmail.com' 4 | license 'Apache 2.0' 5 | description 'Installs/Configures Zabbix Agent/Server' 6 | long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) 7 | version '0.8.0' 8 | supports 'ubuntu', '>= 10.04' 9 | supports 'debian', '>= 6.0' 10 | supports 'redhat', '>= 5.0' 11 | supports 'centos', '>= 5.0' 12 | supports 'oracle', '>= 5.0' 13 | supports 'windows' 14 | depends 'apache2', '>= 1.0.8' 15 | depends 'database', '>= 1.3.0' 16 | depends 'mysql', '>= 1.3.0' 17 | depends 'ufw', '>= 0.6.1' 18 | depends 'yum' 19 | depends 'postgresql' 20 | depends 'php-fpm' 21 | depends 'nginx', '>= 1.0.0' 22 | depends 'ark', '>= 0.7.2' 23 | depends 'chocolatey' 24 | depends 'java' 25 | depends 'oracle-instantclient' 26 | depends 'php' 27 | depends 'yum-epel' 28 | -------------------------------------------------------------------------------- /recipes/agent_chocolatey.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: zabbix 3 | # Author:: Guilhem Lettron 4 | # 5 | # Copyright 2013, Youscribe 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | include_recipe 'chocolatey' 21 | 22 | chocolatey 'zabbix-agent' 23 | 24 | include_recipe 'zabbix::agent_common' 25 | -------------------------------------------------------------------------------- /templates/default/zabbix_java_proxy_settings.sh.erb: -------------------------------------------------------------------------------- 1 | # This is a configuration file for Zabbix Java Proxy. 2 | # It is sourced by startup.sh and shutdown.sh scripts. 3 | 4 | ### Option: zabbix.listenIP 5 | # IP address to listen on. 6 | # 7 | # Mandatory: no 8 | # Default: 9 | # LISTEN_IP="0.0.0.0" 10 | 11 | ### Option: zabbix.listenPort 12 | # Port to listen on. 13 | # 14 | # Mandatory: no 15 | # Range: 1024-32767 16 | # Default: 17 | LISTEN_PORT=10052 18 | 19 | ### Option: zabbix.pidFile 20 | # Name of PID file. 21 | # If omitted, Zabbix Java Proxy is started as a console application. 22 | # 23 | # Mandatory: no 24 | # Default: 25 | # PID_FILE= 26 | 27 | PID_FILE="<%= node.zabbix.run_dir %>/zabbix_java_proxy.pid" 28 | 29 | ### Option: zabbix.startPollers 30 | # Number of worker threads to start. 31 | # 32 | # Mandatory: no 33 | # Range: 1-1000 34 | # Default: 35 | # START_POLLERS=5 -------------------------------------------------------------------------------- /providers/template.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | template_ids = Zabbix::API.find_template_ids(connection, new_resource.name) 4 | 5 | if template_ids.empty? 6 | group_ids = Zabbix::API.find_hostgroup_ids(connection, new_resource.group) 7 | 8 | if group_ids.empty? 9 | Chef::Application.fatal! "Couldn't find a Hostgroup called #{new_resource.group}" 10 | end 11 | 12 | create_template_request = { 13 | :method => 'template.create', 14 | :params => { 15 | :host => new_resource.name, 16 | :groups => group_ids.first 17 | } 18 | } 19 | connection.query(create_template_request) 20 | end 21 | end 22 | new_resource.updated_by_last_action(true) 23 | end 24 | 25 | def load_current_resource 26 | run_context.include_recipe 'zabbix::_providers_common' 27 | require 'zabbixapi' 28 | end 29 | -------------------------------------------------------------------------------- /templates/default/zabbix_java_proxy.init.erb: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Zabbix java proxy daemon start/stop script. 4 | # Nacer Laradji 5 | 6 | NAME=zabbix_java_proxy 7 | DESC="Zabbix java proxy daemon" 8 | DIR=<%= node.zabbix.run_dir %> 9 | PID=<%= node.zabbix.run_dir %>/$NAME.pid 10 | 11 | test -f $DAEMON || exit 0 12 | 13 | [ -d "$DIR" ] || mkdir "$DIR" 14 | chown -R zabbix:zabbix "$DIR" 15 | 16 | case "$1" in 17 | start) 18 | echo "Starting $DESC: $NAME" 19 | (cd <%= node.zabbix.install_dir %>/sbin/zabbix_java && ./startup.sh) 20 | ;; 21 | stop) 22 | echo "Stopping $DESC: $NAME" 23 | (cd <%= node.zabbix.install_dir %>/sbin/zabbix_java && ./shutdown.sh) 24 | ;; 25 | restart|force-reload) 26 | $0 stop 27 | $0 start 28 | ;; 29 | *) 30 | N=/etc/init.d/$NAME 31 | echo "Usage: $N {start|stop|restart}" >&2 32 | exit 1 33 | ;; 34 | esac 35 | 36 | exit 0 -------------------------------------------------------------------------------- /providers/application.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | # Convert the "hostname" (a template name) into a hostid 4 | 5 | template_ids = Zabbix::API.find_template_ids(connection, new_resource.template) 6 | if template_ids.empty? 7 | Chef::Application.fatal! "Could not find a template named #{new_resource.template}" 8 | end 9 | 10 | application_ids = Zabbix::API.find_application_ids(connection, new_resource.name, template_ids.first) 11 | 12 | if application_ids.empty? 13 | request = { 14 | :method => 'application.create', 15 | :params => { 16 | :name => new_resource.name, 17 | :hostid => template_ids.first['hostid'] 18 | } 19 | } 20 | connection.query(request) 21 | end 22 | end 23 | new_resource.updated_by_last_action(true) 24 | end 25 | 26 | def load_current_resource 27 | run_context.include_recipe 'zabbix::_providers_common' 28 | require 'zabbixapi' 29 | end 30 | -------------------------------------------------------------------------------- /files/default/zabbix-java-gateway/zabbix_java_gateway.logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | /var/log/zabbix/zabbix_java_gateway.log 6 | 7 | 8 | /var/log/zabbix/zabbix_java_gateway.log.%i 9 | 1 10 | 3 11 | 12 | 13 | 14 | 5MB 15 | 16 | 17 | 18 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /templates/windows/zabbix_agentd.conf.erb: -------------------------------------------------------------------------------- 1 | # Do not edit 2 | # Created by chef 3 | Hostname=<%= node['zabbix']['agent']['hostname'] %> 4 | <% ::Dir.foreach(node['zabbix']['agent']['include_dir']).sort.drop(2) do |dir| -%> 5 | Include=<%= dir %> 6 | <% end -%> 7 | Server=<%= node.zabbix.agent.servers.join(',') %> 8 | <% if node['zabbix']['agent']['log_file'] -%> 9 | LogFile=<%= node['zabbix']['agent']['log_file'] %> 10 | <% end -%> 11 | <% if node['zabbix']['agent']['debug_level'] -%> 12 | DebugLevel=<%= node['zabbix']['agent']['debug_level'] %> 13 | <% end -%> 14 | <% if node['zabbix']['agent']['enable_remote_commands'] -%> 15 | EnableRemoteCommands=1 16 | LogRemoteCommands=1 17 | <% end -%> 18 | <% if node['zabbix']['agent']['pid_file'] -%> 19 | PidFile=<%= node['zabbix']['agent']['pid_file'] %> 20 | <% end -%> 21 | <% if node.zabbix.agent.servers_active.first -%> 22 | ServerActive=<%= node.zabbix.agent.servers_active.join(',') %> 23 | <% end -%> 24 | <% if node['zabbix']['agent']['start_agents'] -%> 25 | StartAgents=<%= node['zabbix']['agent']['start_agents'] %> 26 | <% end -%> 27 | -------------------------------------------------------------------------------- /recipes/server_common.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: server_common 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | if node['zabbix']['login'] 11 | # Create zabbix group 12 | group node['zabbix']['group'] do 13 | gid node['zabbix']['gid'] 14 | if node['zabbix']['gid'].nil? 15 | action :nothing 16 | else 17 | action :create 18 | end 19 | end 20 | 21 | # Create zabbix User 22 | user node['zabbix']['login'] do 23 | comment 'zabbix User' 24 | home node['zabbix']['install_dir'] 25 | shell node['zabbix']['shell'] 26 | uid node['zabbix']['uid'] 27 | gid node['zabbix']['gid'] 28 | end 29 | end 30 | 31 | root_dirs = [ 32 | node['zabbix']['external_dir'], 33 | node['zabbix']['server']['include_dir'], 34 | node['zabbix']['alert_dir'] 35 | ] 36 | 37 | # Create root folders 38 | root_dirs.each do |dir| 39 | directory dir do 40 | owner 'root' 41 | group 'root' 42 | mode '755' 43 | recursive true 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /templates/default/zabbix_web.conf.php.erb: -------------------------------------------------------------------------------- 1 | 6 | <% dbtypes['mysql'] = "MYSQL" %> 7 | <% dbtypes['rds_mysql'] = "MYSQL" %> 8 | <% dbtypes['postgres'] = "POSTGRESQL" %> 9 | <% dbtypes['oracle'] = "ORACLE" %> 10 | 11 | $DB["TYPE"] = '<%= dbtypes[@database[:install_method]] %>'; 12 | $DB["SERVER"] = '<%= @database[:dbhost] %>'; 13 | $DB["PORT"] = '<%= @database[:dbport] %>'; 14 | $DB["DATABASE"] = '<%= @database[:dbname] %>'; 15 | $DB["USER"] = '<%= @database[:dbuser] %>'; 16 | $DB["PASSWORD"] = '<%= @database[:dbpassword] %>'; 17 | // SCHEMA is relevant only for IBM_DB2 database 18 | $DB["SCHEMA"] = '<%= @database[:schema] %>'; 19 | 20 | $ZBX_SERVER = '<%= @server[:host] %>'; 21 | $ZBX_SERVER_PORT = '<%= @server[:port] %>'; 22 | $ZBX_SERVER_NAME = '<%= @server[:name] %>'; 23 | 24 | $IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG; 25 | ?> 26 | -------------------------------------------------------------------------------- /attributes/web.rb: -------------------------------------------------------------------------------- 1 | default['zabbix']['web']['login'] = 'admin' 2 | default['zabbix']['web']['password'] = 'zabbix' 3 | default['zabbix']['web']['install_method'] = 'apache' 4 | default['zabbix']['web']['fqdn'] = node['fqdn'] 5 | default['zabbix']['web']['aliases'] = ['zabbix'] 6 | default['zabbix']['web']['port'] = 80 7 | 8 | default['zabbix']['web']['php']['fastcgi_listen'] = '127.0.0.1:9000' # only applicable when using php-fpm (nginx) 9 | default['zabbix']['web']['php']['settings'] = { 10 | 'memory_limit' => '256M', 11 | 'post_max_size' => '32M', 12 | 'upload_max_filesize' => '16M', 13 | 'max_execution_time' => '600', 14 | 'max_input_time' => '600', 15 | 'date.timezone' => "'UTC'", 16 | } 17 | 18 | default['zabbix']['web']['packages'] = value_for_platform_family( 19 | 'debian' => %w(php5-mysql php5-gd libapache2-mod-php5), 20 | 'rhel' => 21 | if node['platform_version'].to_f < 6.0 22 | %w(php53-mysql php53-gd php53-bcmath php53-mbstring) 23 | else 24 | %w(php php-mysql php-gd php-bcmath php-mbstring php-xml) 25 | end 26 | ) 27 | -------------------------------------------------------------------------------- /libraries/zabbix_connection.rb: -------------------------------------------------------------------------------- 1 | require 'socket' 2 | require 'timeout' 3 | 4 | class Chef 5 | module Zabbix 6 | class << self 7 | # Creates a Zabbix connection and passes it to the block provided 8 | # 9 | # @param [Hash] connection_spec The specification for your Zabbix connection 10 | # @option connection_spec [String] :url The Url to your Zabbix server's api_jsonrpc.php endpoint 11 | # @option connection_spec [String] :user The username to log in as 12 | # @option connection_spec [String] :password The password for your user 13 | # 14 | # @yieldparam [ZabbixApi] connection The connection to the Zabbix server 15 | def with_connection(connection_spec, &block) 16 | validate_connection(connection_spec) 17 | connection = ZabbixApi.connect(connection_spec) 18 | block.call(connection) 19 | end 20 | 21 | def validate_connection(connection_spec) 22 | return if [:url, :user, :password].all? { |key| !connection_spec[key].to_s.empty? } 23 | Chef::Log.error('invalid connection') 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /resources/database.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attr_accessor :exists 5 | 6 | def initialize(name, run_context = nil) 7 | super 8 | @provider ||= Chef::Provider::ZabbixDatabaseMySql 9 | end 10 | 11 | attribute :dbname, :kind_of => String, :name_attribute => true 12 | attribute :host, :kind_of => String, :required => true 13 | attribute :port, :kind_of => Integer, :required => true 14 | attribute :username, :kind_of => String, :required => true 15 | attribute :password, :kind_of => String, :required => true 16 | attribute :root_username, :kind_of => String, :required => true 17 | attribute :root_password, :kind_of => String, :required => true 18 | attribute :allowed_user_hosts, :kind_of => String, :default => '' 19 | 20 | attribute :server_version, :kind_of => String, :required => true 21 | attribute :source_url, :kind_of => String, :required => true 22 | attribute :source_dir, :kind_of => String, :required => true 23 | attribute :install_dir, :kind_of => String, :required => true 24 | attribute :branch, :kind_of => String, :required => false 25 | attribute :version, :kind_of => String, :required => false 26 | -------------------------------------------------------------------------------- /templates/default/zabbix_agentd.conf.erb: -------------------------------------------------------------------------------- 1 | # Do not edit 2 | # Created by chef 3 | Hostname=<%= node['zabbix']['agent']['hostname'] %> 4 | Include=<%= node['zabbix']['agent']['include_dir'] %> 5 | Server=<%= node['zabbix']['agent']['servers'].join(',') %> 6 | <% if node['zabbix']['agent']['log_file'] -%> 7 | LogFile=<%= node['zabbix']['agent']['log_file'] %> 8 | <% end -%> 9 | <% if node['zabbix']['agent']['debug_level'] -%> 10 | DebugLevel=<%= node['zabbix']['agent']['debug_level'] %> 11 | <% end -%> 12 | <% if node['zabbix']['agent']['enable_remote_commands'] -%> 13 | EnableRemoteCommands=1 14 | LogRemoteCommands=1 15 | <% end -%> 16 | <% if node['zabbix']['agent']['pid_file'] -%> 17 | PidFile=<%= node['zabbix']['agent']['pid_file'] %> 18 | <% end -%> 19 | <% if node.zabbix.agent.servers_active.first -%> 20 | ServerActive=<%= node.zabbix.agent.servers_active.join(',') %> 21 | <% end -%> 22 | <% if node['zabbix']['agent']['start_agents'] -%> 23 | StartAgents=<%= node['zabbix']['agent']['start_agents'] %> 24 | <% end -%> 25 | ListenPort=<%=node['zabbix']['agent']['listen_port'] %> 26 | Timeout=<%= node['zabbix']['agent']['timeout'] %> 27 | -------------------------------------------------------------------------------- /recipes/agent.rb: -------------------------------------------------------------------------------- 1 | include_recipe "zabbix::agent_#{node['zabbix']['agent']['install_method']}" 2 | include_recipe 'zabbix::agent_common' 3 | 4 | # Install configuration 5 | template 'zabbix_agentd.conf' do 6 | path node['zabbix']['agent']['config_file'] 7 | source 'zabbix_agentd.conf.erb' 8 | unless node['platform_family'] == 'windows' 9 | owner 'root' 10 | group 'root' 11 | mode '644' 12 | end 13 | notifies :restart, 'service[zabbix_agentd]' 14 | end 15 | 16 | # Install optional additional agent config file containing UserParameter(s) 17 | template 'user_params.conf' do 18 | path node['zabbix']['agent']['userparams_config_file'] 19 | source 'user_params.conf.erb' 20 | unless node['platform_family'] == 'windows' 21 | owner 'root' 22 | group 'root' 23 | mode '644' 24 | end 25 | notifies :restart, 'service[zabbix_agentd]' 26 | only_if { node['zabbix']['agent']['user_parameter'].length > 0 } 27 | end 28 | 29 | ruby_block 'start service' do 30 | block do 31 | true 32 | end 33 | Array(node['zabbix']['agent']['service_state']).each do |action| 34 | notifies action, 'service[zabbix_agentd]' 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /providers/host_group.rb: -------------------------------------------------------------------------------- 1 | def whyrun_supported? 2 | true 3 | end 4 | 5 | action :create do 6 | if @current_resource.exists 7 | Chef::Log.info("Create: Host Group '#{new_resource.group}' already exists") 8 | else 9 | converge_by("Creating Host Group '#{new_resource.group}'") do 10 | create_group(new_resource.group) 11 | end 12 | new_resource.updated_by_last_action(true) 13 | end 14 | end 15 | 16 | def load_current_resource 17 | run_context.include_recipe 'zabbix::_providers_common' 18 | require 'zabbixapi' 19 | 20 | @current_resource = Chef::Resource::ZabbixHostGroup.new(@new_resource.group) 21 | @current_resource.server_connection(@new_resource.server_connection) 22 | @current_resource.exists = group_exists?(@current_resource.group) 23 | end 24 | 25 | def group_exists?(group) 26 | id = Chef::Zabbix.with_connection(@current_resource.server_connection) do |connection| 27 | connection.hostgroups.get_id(:name => group) 28 | end 29 | !(id.nil?) 30 | end 31 | 32 | def create_group(group) 33 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 34 | connection.hostgroups.create(:name => group) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /templates/default/zabbix_server.conf.erb: -------------------------------------------------------------------------------- 1 | # Generated by chef. 2 | 3 | ############ GENERAL PARAMETERS ################# 4 | 5 | <% if node['zabbix']['server']['log_file'] -%> 6 | LogFile=<%= node['zabbix']['server']['log_file'] %> 7 | <% end -%> 8 | 9 | DBHost=<%= @dbhost %> 10 | DBName=<%= @dbname %> 11 | DBUser=<%= @dbuser %> 12 | DBPassword=<%= @dbpassword %> 13 | DBPort=<%= @dbport %> 14 | 15 | DebugLevel=<%= node['zabbix']['server']['log_level'] %> 16 | PidFile=<%= node['zabbix']['run_dir'] %>/zabbix_server.pid 17 | Include=<%= node['zabbix']['server']['include_dir'] %> 18 | AlertScriptsPath=<%= node['zabbix']['alert_dir'] %> 19 | 20 | HousekeepingFrequency=<%= node['zabbix']['server']['housekeeping_frequency']%> 21 | MaxHousekeeperDelete=<%= node['zabbix']['server']['max_housekeeper_delete'] %> 22 | 23 | JavaGateway=<%= @java_gateway %> 24 | JavaGatewayPort=<%= @java_gateway_port %> 25 | StartJavaPollers=<%= @java_pollers %> 26 | StartPollers=<%= node['zabbix']['server']['start_pollers']%> 27 | 28 | ExternalScripts=<%= node['zabbix']['server']['externalscriptspath'] %> 29 | Timeout=<%= node['zabbix']['server']['timeout']%> 30 | ValueCacheSize=<%= node['zabbix']['server']['value_cache_size'] %> 31 | CacheSize=<%= node['zabbix']['server']['cache_size'] %> 32 | -------------------------------------------------------------------------------- /templates/default/zabbix_server.init.erb: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # Zabbix daemon start/stop script. 4 | # 5 | # Written by Alexei Vladishev . 6 | 7 | NAME=zabbix_server 8 | DAEMON=<%= node.zabbix.install_dir %>/sbin/${NAME} 9 | DESC="Zabbix server daemon" 10 | DIR=<%= node.zabbix.run_dir %> 11 | PID=<%= node.zabbix.run_dir %>/$NAME.pid 12 | 13 | . /lib/lsb/init-functions 14 | 15 | test -f $DAEMON || exit 0 16 | 17 | [ -d "$DIR" ] || mkdir "$DIR" 18 | chown -R zabbix:zabbix "$DIR" 19 | 20 | case "$1" in 21 | start) 22 | echo "Starting $DESC: $NAME" 23 | start-stop-daemon --oknodo --start --pidfile $PID \ 24 | --exec $DAEMON -- -c <%= node.zabbix.etc_dir %>/zabbix_server.conf 25 | ;; 26 | stop) 27 | echo "Stopping $DESC: $NAME" 28 | start-stop-daemon --oknodo --stop --pidfile $PID \ 29 | --exec $DAEMON 30 | ;; 31 | restart|force-reload) 32 | $0 stop 33 | sleep 5 34 | $0 start 35 | ;; 36 | status) 37 | status_of_proc $DAEMON "Zabbix server" 38 | exit $? 39 | ;; 40 | *) 41 | N=/etc/init.d/$NAME 42 | echo "Usage: $N {start|stop|restart|force-reload}" >&2 43 | exit 1 44 | ;; 45 | esac 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /resources/host.rb: -------------------------------------------------------------------------------- 1 | actions :create_or_update, :create, :update, :link 2 | default_action :create_or_update 3 | 4 | attribute :hostname, :kind_of => String, :name_attribute => true 5 | 6 | attribute :ipmi_auth_type, :kind_of => Chef::Zabbix::API::IPMIAuthType, :default => Chef::Zabbix::API::IPMIAuthType.default 7 | attribute :ipmi_privilege, :kind_of => Chef::Zabbix::API::IPMIPrivilege, :default => Chef::Zabbix::API::IPMIPrivilege.user 8 | attribute :ipmi_username, :kind_of => String 9 | attribute :ipmi_password, :kind_of => String 10 | 11 | attribute :monitored, :kind_of => [TrueClass, FalseClass], :default => true 12 | 13 | attribute :interfaces, :kind_of => Array, :default => [] 14 | attribute :templates, :kind_of => Array, :default => [] 15 | attribute :groups, :kind_of => Array, :default => [] 16 | attribute :macros, :kind_of => Hash, :default => {} 17 | 18 | # See https://www.zabbix.com/documentation/2.0/manual/appendix/api/host/definitions#host 19 | # for appropriate inventory hash keys (Property name from the table) 20 | attribute :inventory, :kind_of => Hash, :default => {} 21 | 22 | attribute :server_connection, :kind_of => Hash, :default => {} 23 | attribute :create_missing_groups, :kind_of => [TrueClass, FalseClass], :default => false 24 | attribute :parameters, :kind_of => Hash, :default => {} 25 | -------------------------------------------------------------------------------- /spec/zabbix_web_apache_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'zabbix::web_apache' do 4 | context 'on Ubuntu 12.04' do 5 | let(:chef_run) do 6 | ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') 7 | .converge(described_recipe) 8 | end 9 | 10 | it 'installs required packages' do 11 | %w(php5-mysql php5-gd libapache2-mod-php5).each do |package| 12 | expect(chef_run).to install_package(package) 13 | end 14 | end 15 | end 16 | 17 | context 'on Centos 5.9' do 18 | let(:chef_run) do 19 | ChefSpec::Runner.new(platform: 'centos', version: '5.9') 20 | .converge(described_recipe) 21 | end 22 | 23 | it 'installs required packages' do 24 | %w(php53-mysql php53-gd php53-bcmath php53-mbstring).each do |package| 25 | expect(chef_run).to install_package(package) 26 | end 27 | end 28 | end 29 | 30 | context 'on Centos 6.0' do 31 | let(:chef_run) do 32 | ChefSpec::Runner.new(platform: 'centos', version: '6.0') 33 | .converge(described_recipe) 34 | end 35 | 36 | it 'installs required packages' do 37 | %w(php php-mysql php-gd php-bcmath php-mbstring php-xml).each do |package| 38 | expect(chef_run).to install_package(package) 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: zabbix 3 | # Attributes:: default 4 | 5 | case node['platform_family'] 6 | when 'windows' 7 | if ENV['ProgramFiles'] == ENV['ProgramFiles(x86)'] 8 | # if user has never logged into an interactive session then ENV['homedrive'] will be nil 9 | default['zabbix']['etc_dir'] = ::File.join((ENV['homedrive'] || 'C:'), 'Program Files', 'Zabbix Agent') 10 | else 11 | default['zabbix']['etc_dir'] = ::File.join(ENV['ProgramFiles'], 'Zabbix Agent') 12 | end 13 | else 14 | default['zabbix']['etc_dir'] = '/etc/zabbix' 15 | end 16 | default['zabbix']['install_dir'] = '/opt/zabbix' 17 | default['zabbix']['web_dir'] = '/opt/zabbix/web' 18 | default['zabbix']['external_dir'] = '/opt/zabbix/externalscripts' 19 | default['zabbix']['alert_dir'] = '/opt/zabbix/AlertScriptsPath' 20 | default['zabbix']['lock_dir'] = '/var/lock/subsys' 21 | default['zabbix']['src_dir'] = '/opt' 22 | default['zabbix']['log_dir'] = '/var/log/zabbix' 23 | default['zabbix']['run_dir'] = '/var/run/zabbix' 24 | 25 | default['zabbix']['login'] = 'zabbix' 26 | default['zabbix']['group'] = 'zabbix' 27 | default['zabbix']['uid'] = nil 28 | default['zabbix']['gid'] = nil 29 | default['zabbix']['home'] = '/opt/zabbix' 30 | default['zabbix']['shell'] = '/bin/bash' 31 | -------------------------------------------------------------------------------- /resources/user.rb: -------------------------------------------------------------------------------- 1 | actions :create_or_update, :create, :update, :delete 2 | default_action :create_or_update 3 | 4 | attribute :alias, :kind_of => String, :name_attribute => true, :required => true 5 | attribute :password, :kind_of => String 6 | 7 | attribute :first_name, :kind_of => String 8 | attribute :surname, :kind_of => String 9 | 10 | attribute :type, :kind_of => Integer, :default => 1 11 | 12 | # This accepting an Array of Strings as the names of the user_groups to add 13 | # the user to them 14 | attribute :groups, :kind_of => Array, :default => [] 15 | # This is accepting an Array of Zabbix Media objects supplied as Ruby Hashes 16 | # For the attributes of a Media object see: 17 | # https://www.zabbix.com/documentation/2.2/manual/api/reference/usermedia/object#media 18 | attribute :medias, :kind_of => Array, :default => [] 19 | 20 | attribute :create_missing_groups, :kind_of => [TrueClass, FalseClass], :default => false 21 | 22 | # This attribute is used to force the update action even if the user object seems to be 23 | # up-to-date, mostly used when we want to update the user's password, since the API 24 | # get call does not return it (obviously), so it would never be updated otherwise 25 | attribute :force_update, :kind_of => [TrueClass, FalseClass], :default => false 26 | 27 | attribute :server_connection, :kind_of => Hash, :default => {} 28 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # or sharing to the community site. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | Icon? 9 | nohup.out 10 | ehthumbs.db 11 | Thumbs.db 12 | 13 | # SASS # 14 | ######## 15 | .sass-cache 16 | 17 | # EDITORS # 18 | ########### 19 | \#* 20 | .#* 21 | *~ 22 | *.sw[a-z] 23 | *.bak 24 | REVISION 25 | TAGS* 26 | tmtags 27 | *_flymake.* 28 | *_flymake 29 | *.tmproj 30 | .project 31 | .settings 32 | mkmf.log 33 | 34 | ## COMPILED ## 35 | ############## 36 | a.out 37 | *.o 38 | *.pyc 39 | *.so 40 | *.com 41 | *.class 42 | *.dll 43 | *.exe 44 | */rdoc/ 45 | 46 | # Testing # 47 | ########### 48 | .watchr 49 | .rspec 50 | spec/* 51 | spec/fixtures/* 52 | test/* 53 | features/* 54 | Guardfile 55 | Procfile 56 | 57 | # SCM # 58 | ####### 59 | .git 60 | */.git 61 | .gitignore 62 | .gitmodules 63 | .gitconfig 64 | .gitattributes 65 | .svn 66 | */.bzr/* 67 | */.hg/* 68 | */.svn/* 69 | 70 | # Berkshelf # 71 | ############# 72 | Berksfile 73 | Berksfile.lock 74 | cookbooks/* 75 | tmp 76 | 77 | # Cookbooks # 78 | ############# 79 | CONTRIBUTING 80 | CHANGELOG* 81 | 82 | # Strainer # 83 | ############ 84 | Colanderfile 85 | Strainerfile 86 | .colander 87 | .strainer 88 | 89 | # Vagrant # 90 | ########### 91 | .vagrant 92 | Vagrantfile 93 | 94 | # Travis # 95 | ########## 96 | .travis.yml 97 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | 3 | # Style tests. Rubocop and Foodcritic 4 | namespace :style do 5 | begin 6 | require 'rubocop/rake_task' 7 | desc 'Run Ruby style checks' 8 | RuboCop::RakeTask.new(:ruby) 9 | rescue LoadError 10 | puts '>>>>> Rubocop gem not loaded, omitting tasks' unless ENV['CI'] 11 | end 12 | 13 | begin 14 | require 'foodcritic' 15 | 16 | desc 'Run Chef style checks' 17 | FoodCritic::Rake::LintTask.new(:chef) do |t| 18 | t.options = { 19 | fail_tags: ['any'] 20 | } 21 | end 22 | rescue LoadError 23 | puts '>>>>> foodcritic gem not loaded, omitting tasks' unless ENV['CI'] 24 | end 25 | end 26 | 27 | desc 'Run all style checks' 28 | task style: ['style:chef', 'style:ruby'] 29 | 30 | namespace :unit do 31 | begin 32 | require 'rspec/core/rake_task' 33 | desc 'Runs specs with chefspec.' 34 | RSpec::Core::RakeTask.new(:chefspec) 35 | rescue LoadError 36 | puts '>>>>> chefspec gem not loaded, omitting tasks' unless ENV['CI'] 37 | end 38 | end 39 | 40 | # Integration tests. Kitchen.ci 41 | namespace :integration do 42 | begin 43 | require 'kitchen/rake_tasks' 44 | 45 | desc 'Run kitchen integration tests' 46 | Kitchen::RakeTasks.new 47 | rescue LoadError 48 | puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI'] 49 | end 50 | end 51 | 52 | desc 'Run all tests on Travis' 53 | task travis: ['style'] 54 | 55 | # Default 56 | task default: ['style', 'integration:kitchen:all'] 57 | -------------------------------------------------------------------------------- /attributes/server.rb: -------------------------------------------------------------------------------- 1 | include_attribute 'zabbix' 2 | 3 | default['zabbix']['server']['version'] = '2.0.3' 4 | default['zabbix']['server']['branch'] = 'ZABBIX%20Latest%20Stable' 5 | default['zabbix']['server']['source_url'] = nil 6 | default['zabbix']['server']['install_method'] = 'source' 7 | default['zabbix']['server']['configure_options'] = ['--with-libcurl', '--with-net-snmp'] 8 | default['zabbix']['server']['include_dir'] = '/opt/zabbix/server_include' 9 | default['zabbix']['server']['log_file'] = ::File.join(node['zabbix']['log_dir'], 'zabbix_server.log') 10 | default['zabbix']['server']['log_level'] = 3 11 | default['zabbix']['server']['housekeeping_frequency'] = '1' 12 | default['zabbix']['server']['max_housekeeper_delete'] = '100000' 13 | 14 | default['zabbix']['server']['host'] = 'localhost' 15 | default['zabbix']['server']['port'] = 10_051 16 | default['zabbix']['server']['name'] = nil 17 | 18 | default['zabbix']['server']['java_gateway'] = '127.0.0.1' 19 | default['zabbix']['server']['java_gateway_port'] = 10_052 20 | default['zabbix']['server']['java_pollers'] = 0 21 | default['zabbix']['server']['start_pollers'] = 5 22 | 23 | default['zabbix']['server']['externalscriptspath'] = '/usr/local/scripts/zabbix/externalscripts/' 24 | 25 | default['zabbix']['server']['timeout'] = '3' 26 | default['zabbix']['server']['value_cache_size'] = '8M' # default 8MB 27 | default['zabbix']['server']['cache_size'] = '8M' # default 8MB 28 | -------------------------------------------------------------------------------- /recipes/agent_source.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: agent_source 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | include_recipe 'zabbix::agent_common' 11 | 12 | case node['platform'] 13 | when 'ubuntu', 'debian' 14 | # install some dependencies 15 | %w(fping libcurl3 libiksemel-dev libiksemel3 libsnmp-dev libiksemel-utils libcurl4-openssl-dev).each do |pck| 16 | package pck do 17 | action :install 18 | end 19 | end 20 | 21 | when 'redhat', 'centos', 'scientific', 'amazon' 22 | %w(fping curl-devel iksemel-devel iksemel-utils net-snmp-libs net-snmp-devel openssl-devel redhat-lsb).each do |pck| 23 | package pck do 24 | action :install 25 | end 26 | end 27 | end 28 | 29 | # --prefix is controlled by install_dir 30 | configure_options = node['zabbix']['agent']['configure_options'].dup 31 | configure_options = (configure_options || Array.new).delete_if do |option| 32 | option.match(/\s*--prefix(\s|=).+/) 33 | end 34 | node.normal['zabbix']['agent']['configure_options'] = configure_options 35 | 36 | zabbix_source 'install_zabbix_agent' do 37 | branch node['zabbix']['agent']['branch'] 38 | version node['zabbix']['agent']['version'] 39 | source_url node['zabbix']['agent']['source_url'] 40 | code_dir node['zabbix']['src_dir'] 41 | target_dir "zabbix-#{node['zabbix']['agent']['version']}-agent" 42 | install_dir node['zabbix']['install_dir'] 43 | configure_options configure_options.join(' ') 44 | 45 | action :install_agent 46 | end 47 | -------------------------------------------------------------------------------- /templates/default/web_app.conf.erb: -------------------------------------------------------------------------------- 1 | 2 | ServerName <%= @params[:server_name] %> 3 | ServerAlias <%= @params[:server_aliases].join(' ')%> 4 | DocumentRoot <%= @params[:docroot] %> 5 | RewriteEngine On 6 | 7 | > 8 | Options +FollowSymLinks 9 | AllowOverride None 10 | Order allow,deny 11 | Allow from all 12 | <% @params[:php_settings].each do |name, value| %> 13 | php_admin_value <%=name%> <%=value%> 14 | <%end%> 15 | 16 | 17 | 18 | Options FollowSymLinks 19 | AllowOverride None 20 | 21 | 22 | 23 | SetHandler server-status 24 | 25 | Order Deny,Allow 26 | Deny from all 27 | Allow from 127.0.0.1 28 | 29 | 30 | LogLevel info 31 | ErrorLog <%= node['apache']['log_dir'] %>/<%= @params[:server_name] %>-error.log 32 | CustomLog <%= node['apache']['log_dir'] %>/<%= @params[:server_name] %>-access.log combined 33 | 34 | RewriteEngine On 35 | RewriteLog <%= node['apache']['log_dir'] %>/<%= @application_name %>-rewrite.log 36 | RewriteLogLevel 0 37 | 38 | # Canonical host, <%= @params['server_name'] %> 39 | RewriteCond %{HTTP_HOST} !^<%= @params['server_name'] %> [NC] 40 | RewriteCond %{HTTP_HOST} !^$ 41 | RewriteRule ^/(.*)$ http://<%= @params['server_name'] %>/$1 [L,R=301] 42 | 43 | RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f 44 | RewriteCond %{SCRIPT_FILENAME} !maintenance.html 45 | RewriteRule ^.*$ /system/maintenance.html [L] 46 | 47 | -------------------------------------------------------------------------------- /providers/trigger.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | # NOTE: Triggers in the zabbix api don't really have a "name" 4 | # Instead we call it name so that lwrp users don't lose their minds 5 | # and we just treat it as the description field the api wants 6 | # 7 | # The description on the lwrp becomes comments in the api 8 | 9 | params = { 10 | # For whatever reason triggers have a description and comments 11 | # instead of a name and description... 12 | :description => new_resource.name, 13 | :comments => new_resource.description, 14 | :expression => new_resource.expression, 15 | :priority => new_resource.priority.value, 16 | :status => new_resource.status.value, 17 | } 18 | 19 | noun = (new_resource.prototype) ? 'triggerprototype' : 'trigger' 20 | verb = 'create' 21 | 22 | if new_resource.prototype 23 | trigger_ids = Zabbix::API.find_trigger_prototype_ids(connection, new_resource.name) 24 | else 25 | trigger_ids = Zabbix::API.find_trigger_ids(connection, new_resource.name) 26 | end 27 | 28 | unless trigger_ids.empty? 29 | verb = 'update' 30 | params[:triggerid] = trigger_ids.first['triggerid'] 31 | end 32 | 33 | method = "#{noun}.#{verb}" 34 | connection.query( 35 | :method => method, 36 | :params => params 37 | ) 38 | end 39 | new_resource.updated_by_last_action(true) 40 | end 41 | 42 | def load_current_resource 43 | run_context.include_recipe 'zabbix::_providers_common' 44 | require 'zabbixapi' 45 | end 46 | -------------------------------------------------------------------------------- /resources/graph.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :name, :kind_of => String, :required => true 5 | 6 | attribute :width, :kind_of => Fixnum, :default => 900 7 | attribute :height, :kind_of => Fixnum, :default => 200 8 | attribute :yaxismin, :kind_of => Float, :default => 0.000 9 | attribute :yaxismax, :kind_of => Float, :default => 100.000 10 | attribute :percent_left, :kind_of => Float, :default => 0.000 11 | attribute :percent_right, :kind_of => Float, :default => 0.000 12 | 13 | attribute :show_work_period, :kind_of => [TrueClass, FalseClass], :default => true 14 | attribute :show_triggers, :kind_of => [TrueClass, FalseClass], :default => true 15 | attribute :show_legend, :kind_of => [TrueClass, FalseClass], :default => true 16 | attribute :show_3d, :kind_of => [TrueClass, FalseClass], :default => false 17 | 18 | attribute :type, :kind_of => Zabbix::API::GraphType, :default => Zabbix::API::GraphType.normal 19 | attribute :ymin_type, :kind_of => Zabbix::API::GraphAxisType, :default => Zabbix::API::GraphAxisType.calculated 20 | attribute :ymax_type, :kind_of => Zabbix::API::GraphAxisType, :default => Zabbix::API::GraphAxisType.calculated 21 | # TODO: eventually these will be strings that could be floats for GraphAxisType.fixed 22 | # or could reference an item_id for GraphAxisType.item 23 | attribute :ymin_item, :kind_of => Float, :default => 0.000 24 | attribute :ymax_item, :kind_of => Float, :default => 0.000 25 | 26 | attribute :graph_items, :kind_of => Array, :required => true 27 | 28 | attribute :prototype, :kind_of => [TrueClass, FalseClass], :default => false 29 | attribute :server_connection, :kind_of => Hash, :required => true 30 | -------------------------------------------------------------------------------- /resources/discovery_rule.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :name, :kind_of => String, :name_attribute => true 5 | attribute :key, :kind_of => String, :required => true 6 | attribute :type, :kind_of => Chef::Zabbix::API::ItemType, :required => true 7 | attribute :template, :kind_of => String, :required => true 8 | attribute :server_connection, :kind_of => Hash, :required => true 9 | 10 | attribute :delay, :kind_of => Fixnum, :default => 30 11 | attribute :authtype, :kind_of => Chef::Zabbix::API::AuthType, :default => Chef::Zabbix::API::AuthType.password 12 | attribute :lifetime, :kind_of => Fixnum, :default => 30 13 | 14 | attribute :delay_flex, :kind_of => String 15 | attribute :description, :kind_of => String 16 | attribute :filter, :kind_of => String 17 | attribute :ipmi_sensor, :kind_of => String 18 | attribute :discovery_rule_params, :kind_of => String 19 | attribute :password, :kind_of => String 20 | attribute :port, :kind_of => String 21 | attribute :privatekey, :kind_of => String 22 | attribute :publickey, :kind_of => String 23 | attribute :snmp_community, :kind_of => String, :default => '{}' 24 | attribute :snmp_oid, :kind_of => String, :default => '{}' 25 | attribute :snmpv3_securityname, :kind_of => String 26 | attribute :snmpv3_authpassphrase, :kind_of => String 27 | attribute :snmpv3_privpassphrase, :kind_of => String 28 | attribute :snmpv3_securitylevel, :kind_of => Chef::Zabbix::API::SNMPV3SecurityLevel, :default => Chef::Zabbix::API::SNMPV3SecurityLevel.no_auth_no_priv 29 | attribute :status, :kind_of => Chef::Zabbix::API::ItemStatus, :default => Chef::Zabbix::API::ItemStatus.enabled 30 | attribute :allowed_hosts, :kind_of => String 31 | attribute :username, :kind_of => String 32 | -------------------------------------------------------------------------------- /recipes/common.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: common 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | # Define root owned folders 11 | root_dirs = [ 12 | node['zabbix']['etc_dir'], 13 | ] 14 | 15 | # Create root folders 16 | case node['platform_family'] 17 | when 'windows' 18 | root_dirs.each do |dir| 19 | directory dir do 20 | owner 'Administrator' 21 | rights :read, 'Everyone', :applies_to_children => true 22 | recursive true 23 | end 24 | end 25 | else 26 | root_dirs.each do |dir| 27 | directory dir do 28 | owner 'root' 29 | group 'root' 30 | mode '755' 31 | recursive true 32 | end 33 | end 34 | end 35 | 36 | # Define zabbix owned folders 37 | zabbix_dirs = [ 38 | node['zabbix']['log_dir'], 39 | node['zabbix']['run_dir'] 40 | ] 41 | 42 | # Create zabbix folders 43 | zabbix_dirs.each do |dir| 44 | directory dir do 45 | owner node['zabbix']['login'] 46 | group node['zabbix']['group'] 47 | mode '755' 48 | recursive true 49 | # Only execute this if zabbix can't write to it. This handles cases of 50 | # dir being world writable (like /tmp) 51 | not_if { ::File.world_writable?(dir) } 52 | end 53 | end 54 | 55 | unless node['zabbix']['agent']['source_url'] 56 | node.default['zabbix']['agent']['source_url'] = Chef::Zabbix.default_download_url(node['zabbix']['agent']['branch'], node['zabbix']['agent']['version']) 57 | end 58 | 59 | unless node['zabbix']['server']['source_url'] 60 | node.default['zabbix']['server']['source_url'] = Chef::Zabbix.default_download_url(node['zabbix']['server']['branch'], node['zabbix']['server']['version']) 61 | end 62 | -------------------------------------------------------------------------------- /recipes/firewall.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: firewall 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | # This is the firewall part of zabbix installation. 10 | # 11 | 12 | include_recipe 'ufw' 13 | # enable platform default firewall 14 | firewall 'ufw' do 15 | action :enable 16 | end 17 | 18 | if node['zabbix']['server']['install'] == true 19 | # Search for some client 20 | if Chef::Config[:solo] 21 | Chef::Log.warn('This recipe uses search. Chef Solo does not support search.') 22 | else 23 | zabbix_clients = search(:node, 'recipes:zabbix') 24 | 25 | zabbix_clients.each do |client| 26 | # Accept connection from zabbix_server on agent 27 | firewall_rule "zabbix_client_#{client[:fqdn]}" do 28 | port 10_051 29 | source client[:ipaddress] 30 | action :allow 31 | end 32 | end if zabbix_clients 33 | 34 | # Localhost too 35 | firewall_rule 'zabbix_client_127.0.0.1}' do 36 | port 10_051 37 | source '127.0.0.1' 38 | action :allow 39 | end 40 | end 41 | end 42 | 43 | # Search for some client 44 | if Chef::Config[:solo] 45 | Chef::Log.warn('This recipe uses search. Chef Solo does not support search.') 46 | else 47 | zabbix_servers = search(:node, 'recipes:zabbix\:\:server') 48 | zabbix_servers.each do |server| 49 | 50 | # Accept connection from zabbix_agent on server 51 | firewall_rule "zabbix_server_#{server[:fqdn]}" do 52 | port 10_050 53 | source server[:ipaddress] 54 | action :allow 55 | end 56 | end if zabbix_servers 57 | end 58 | 59 | # enable platform default firewall 60 | firewall 'ufw' do 61 | action :enable 62 | end 63 | -------------------------------------------------------------------------------- /providers/discovery_rule.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | template_ids = Zabbix::API.find_template_ids(connection, new_resource.template) 4 | if template_ids.empty? 5 | Chef::Application.fatal! "Could not find a template named #{new_resource.template}" 6 | end 7 | 8 | template_id = template_ids.first['hostid'] 9 | 10 | method = 'discoveryrule.create' 11 | params = {} 12 | simple_value_keys = [ 13 | :name, :delay, :lifetime, :delay_flex, :description, 14 | :filter, :ipmi_sensor, :password, :port, :privatekey, 15 | :publickey, :snmp_community, :snmp_oid, :snmpv3_securityname, 16 | :snmpv3_authpassphrase, :snmpv3_privpassphrase, :username 17 | ] 18 | simple_value_keys.each do |key| 19 | params[key] = new_resource.send(key) 20 | end 21 | 22 | enum_value_keys = [ 23 | :type, :authtype, :snmpv3_securitylevel, :status 24 | ] 25 | enum_value_keys.each do |key| 26 | params[key] = new_resource.send(key).value 27 | end 28 | 29 | params[:hostid] = template_id 30 | params[:key_] = new_resource.key 31 | params[:params] = new_resource.discovery_rule_params 32 | params[:trapper_hosts] = new_resource.allowed_hosts 33 | 34 | rule_ids = Zabbix::API.find_lld_rule_ids(connection, template_id, new_resource.key) 35 | unless rule_ids.empty? 36 | method = 'discoveryrule.update' 37 | params[:itemid] = rule_ids.first['itemid'] 38 | end 39 | 40 | connection.query(:method => method, 41 | :params => params) 42 | end 43 | new_resource.updated_by_last_action(true) 44 | end 45 | 46 | def load_current_resource 47 | run_context.include_recipe 'zabbix::_providers_common' 48 | require 'zabbixapi' 49 | end 50 | -------------------------------------------------------------------------------- /providers/interface.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | # Translate the name of the interface to a type 3 | # TODO: add error checking for bad interface names 4 | types = {} 5 | types['agent'] = 1 6 | types['SNMP'] = 2 7 | types['IPMI'] = 3 8 | types['JMX'] = 4 9 | # type = types[new_resource.name] 10 | 11 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 12 | # Convert the "hostname" (a template name) into a hostid 13 | host_id = connection.query( 14 | :method => 'host.get', 15 | :params => { 16 | :filter => { 17 | :host => new_resource.parameters[:hostName], 18 | }, 19 | } 20 | ) 21 | 22 | # interface_id = connection.query( 23 | # :method => 'hostinterface.get', 24 | # :params => { 25 | # :hostids => hostId[0]['hostid'], 26 | # :filter => { 27 | # :type => type, 28 | # } 29 | # } 30 | # ) 31 | 32 | if interfaceId.size == 0 33 | # Make a new params with the correct parameters 34 | new_resource.parameters[:hostid] = host_id[0]['hostid'] 35 | # Send the creation request to the server 36 | connection.query( 37 | :method => 'application.create', 38 | :params => new_resource.parameters 39 | ) 40 | else 41 | # Update the interface for this host 42 | new_resource.parameters[:interfaceid] = interfaceId[0]['interfaceid'] 43 | new_resource.parameters.delete('hostName') 44 | connection.query( 45 | :method => 'hostinterface.update', 46 | :params => new_resource.parameters 47 | ) 48 | end 49 | end 50 | new_resource.updated_by_last_action(true) 51 | end 52 | 53 | def load_current_resource 54 | run_context.include_recipe 'zabbix::_providers_common' 55 | require 'zabbixapi' 56 | end 57 | -------------------------------------------------------------------------------- /recipes/java_gateway.rb: -------------------------------------------------------------------------------- 1 | # Author:: Friedrich Clausen () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: java_gateway 4 | # 5 | # Apache 2.0 6 | # 7 | 8 | include_recipe 'java' 9 | 10 | template '/etc/zabbix/zabbix_java_gateway.conf' do 11 | source 'zabbix-java-gateway/zabbix_java_gateway.conf.erb' 12 | variables( 13 | :java_gateway_listen_ip => node['zabbix']['server']['java_gateway_listen_ip'], 14 | :java_gateway_listen_port => node['zabbix']['server']['java_gateway_listen_port'], 15 | :java_gateway_pollers => node['zabbix']['server']['java_gateway_pollers'] 16 | ) 17 | owner 'zabbix' 18 | group 'zabbix' 19 | mode '0644' 20 | notifies :restart, 'service[zabbix-java-gateway]' 21 | end 22 | 23 | cookbook_file '/etc/zabbix/zabbix_java_gateway.logback.xml' do 24 | source 'zabbix-java-gateway/zabbix_java_gateway.logback.xml' 25 | owner 'zabbix' 26 | group 'zabbix' 27 | mode '0644' 28 | notifies :restart, 'service[zabbix-java-gateway]' 29 | end 30 | 31 | case node['platform_family'] 32 | when 'rhel', 'fedora', 'suse' 33 | cookbook_file '/etc/init.d/zabbix-java-gateway' do 34 | source 'zabbix-java-gateway/init.rhel' 35 | owner 'root' 36 | group 'root' 37 | mode '0755' 38 | end 39 | when 'debian' 40 | cookbook_file '/etc/init.d/zabbix-java-gateway' do 41 | source 'zabbix-java-gateway/init.debian' 42 | owner 'root' 43 | group 'root' 44 | mode '0755' 45 | end 46 | end 47 | 48 | service 'zabbix-java-gateway' do 49 | service_name 'zabbix-java-gateway' 50 | supports :restart => true, :status => true, :reload => true 51 | action [:enable, :start] 52 | end 53 | 54 | # Dummy file saying look at /etc/zabbix/zabbix_java_gateway.conf 55 | cookbook_file '/opt/zabbix/sbin/zabbix_java/settings.sh' do 56 | source 'zabbix-java-gateway/settings.sh' 57 | owner 'zabbix' 58 | group 'zabbix' 59 | mode '0644' 60 | end 61 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # This Vagrantfile needs the vagrant-omnbius plugin installed 5 | # To install this, run "vagrant plugin install vagrant-omnibus" 6 | 7 | Vagrant.configure("2") do |config| 8 | config.vm.provider :virtualbox do |vbox| 9 | vbox.customize ['modifyvm', :id, 10 | '--memory', 1024] 11 | end 12 | 13 | config.vm.box = "Chef-CentOS-6.5" 14 | config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box" 15 | 16 | config.vm.hostname = "zabbix-berkshelf" 17 | server_ip = "192.168.50.10" 18 | config.vm.network :private_network, ip: server_ip 19 | 20 | config.omnibus.chef_version = "11.6.2" 21 | config.vm.provision :chef_solo do |chef| 22 | chef.json = { 23 | :mysql => { 24 | :server_root_password => 'rootpass', 25 | :server_debian_password => 'debpass', 26 | :server_repl_password => 'replpass' 27 | }, 28 | 'postgresql' => { 29 | 'password' => { 30 | 'postgres' => 'rootpass' 31 | } 32 | }, 33 | 'zabbix' => { 34 | 'agent' => { 35 | 'servers' => [server_ip], 36 | 'servers_active' => [server_ip] 37 | }, 38 | 'web' => { 39 | 'install_method' => 'apache', 40 | 'fqdn' => server_ip 41 | }, 42 | 'server' => { 43 | 'install' => true, 44 | 'ipaddress' => server_ip 45 | }, 46 | 'database' => { 47 | #'dbport' => '5432', 48 | #'install_method' => 'postgres', 49 | 'dbpassword' => 'password123' 50 | } 51 | } 52 | } 53 | 54 | chef.add_recipe "database::mysql" 55 | chef.add_recipe "mysql::server" 56 | chef.add_recipe "zabbix" 57 | chef.add_recipe "zabbix::database" 58 | chef.add_recipe "zabbix::server" 59 | chef.add_recipe "zabbix::web" 60 | chef.add_recipe "zabbix::agent_registration" 61 | 62 | #chef.log_level = :debug 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /providers/trigger_dependency.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | # NOTE: Triggers in the zabbix api don't really have a "name" 4 | # Instead we call it name so that lwrp users don't lose their minds 5 | # and we just treat it as the description field the api wants 6 | # 7 | # The description on the lwrp becomes comments in the api 8 | 9 | get_trigger_request = { 10 | :method => 'trigger.get', 11 | :params => { 12 | :filter => { 13 | :description => new_resource.trigger_name 14 | }, 15 | :selectDependencies => 'refer' 16 | } 17 | } 18 | triggers = connection.query(get_trigger_request) 19 | if triggers.empty? 20 | Chef::Application.fatal! "No trigger named '#{new_resource.trigger_name}' found" 21 | end 22 | trigger = triggers.first 23 | 24 | get_dependency_request = { 25 | :method => 'trigger.get', 26 | :params => { 27 | :filter => { 28 | :description => new_resource.dependency_name 29 | } 30 | } 31 | } 32 | dependency_ids = connection.query(get_dependency_request) 33 | if dependency_ids.empty? 34 | Chef::Application.fatal! "No trigger named '#{new_resource.dependency_name}' found" 35 | end 36 | dependency_id = dependency_ids.first['triggerid'] 37 | 38 | if !trigger['dependencies'].map { |dep| dep['triggerid'] }.include?(dependency_id) 39 | add_dependency_request = { 40 | :method => 'trigger.adddependencies', 41 | :params => { 42 | :triggerid => trigger['triggerid'], 43 | :dependsOnTriggerid => dependency_id, 44 | } 45 | } 46 | connection.query(add_dependency_request) 47 | new_resource.updated_by_last_action(true) 48 | else 49 | Chef::Log.info "Trigger '#{new_resource.trigger_name}' already depends on a trigger named '#{new_resource.dependency_name}'" 50 | end 51 | 52 | end 53 | end 54 | 55 | def load_current_resource 56 | run_context.include_recipe 'zabbix::_providers_common' 57 | require 'zabbixapi' 58 | end 59 | -------------------------------------------------------------------------------- /recipes/web_apache.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: web 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | include_recipe 'zabbix::common' 11 | 12 | directory node['zabbix']['install_dir'] do 13 | mode '0755' 14 | end 15 | 16 | unless node['zabbix']['web']['user'] 17 | node.normal['zabbix']['web']['user'] = 'apache' 18 | end 19 | 20 | user node['zabbix']['web']['user'] 21 | 22 | node['zabbix']['web']['packages'].each do |pkg| 23 | package pkg do 24 | action :install 25 | notifies :restart, 'service[apache2]' 26 | end 27 | end 28 | 29 | package 'libapache2-mod-php5' if platform_family?('debian') 30 | 31 | zabbix_source 'extract_zabbix_web' do 32 | branch node['zabbix']['server']['branch'] 33 | version node['zabbix']['server']['version'] 34 | source_url node['zabbix']['server']['source_url'] 35 | code_dir node['zabbix']['src_dir'] 36 | target_dir "zabbix-#{node['zabbix']['server']['version']}" 37 | install_dir node['zabbix']['install_dir'] 38 | action :extract_only 39 | end 40 | 41 | link node['zabbix']['web_dir'] do 42 | to "#{node['zabbix']['src_dir']}/zabbix-#{node['zabbix']['server']['version']}/frontends/php" 43 | end 44 | 45 | directory "#{node['zabbix']['src_dir']}/zabbix-#{node['zabbix']['server']['version']}/frontends/php/conf" do 46 | owner node['apache']['user'] 47 | group node['apache']['group'] 48 | mode '0755' 49 | action :create 50 | end 51 | 52 | # install zabbix PHP config file 53 | template "#{node['zabbix']['src_dir']}/zabbix-#{node['zabbix']['server']['version']}/frontends/php/conf/zabbix.conf.php" do 54 | source 'zabbix_web.conf.php.erb' 55 | owner 'root' 56 | group 'root' 57 | mode '754' 58 | variables( 59 | :database => node['zabbix']['database'], 60 | :server => node['zabbix']['server'] 61 | ) 62 | end 63 | 64 | # install vhost for zabbix frontend 65 | web_app node['zabbix']['web']['fqdn'] do 66 | server_name node['zabbix']['web']['fqdn'] 67 | server_port node['zabbix']['web']['port'] 68 | server_aliases node['zabbix']['web']['aliases'] 69 | docroot node['zabbix']['web_dir'] 70 | not_if { node['zabbix']['web']['fqdn'].nil? } 71 | php_settings node['zabbix']['web']['php']['settings'] 72 | notifies :restart, 'service[apache2]', :immediately 73 | end 74 | 75 | apache_site '000-default' do 76 | enable false 77 | end 78 | -------------------------------------------------------------------------------- /recipes/web_nginx.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'zabbix::common' 2 | 3 | # Install nginx and disable default site 4 | node.override['nginx']['default_site_enabled'] = false 5 | # node.override['php-fpm']['pool']['www']['listen'] = node['zabbix']['web']['php']['fastcgi_listen'] 6 | include_recipe 'nginx' 7 | 8 | # Install php-fpm to execute PHP code from nginx 9 | include_recipe 'php-fpm' 10 | 11 | node['zabbix']['web']['packages'].each do |pck| 12 | package pck do 13 | notifies :restart, 'service[nginx]' 14 | end 15 | end 16 | 17 | zabbix_source 'extract_zabbix_web' do 18 | branch node['zabbix']['server']['branch'] 19 | version node['zabbix']['server']['version'] 20 | source_url node['zabbix']['server']['source_url'] 21 | code_dir node['zabbix']['src_dir'] 22 | target_dir "zabbix-#{node['zabbix']['server']['version']}" 23 | install_dir node['zabbix']['install_dir'] 24 | 25 | action :extract_only 26 | end 27 | 28 | # Link to the web interface version 29 | link node['zabbix']['web_dir'] do 30 | to "#{node['zabbix']['src_dir']}/zabbix-#{node['zabbix']['server']['version']}/frontends/php" 31 | end 32 | 33 | conf_dir = ::File.join(node['zabbix']['src_dir'], "zabbix-#{node['zabbix']['server']['version']}", 'frontends', 'php', 'conf') 34 | directory conf_dir do 35 | owner node['nginx']['user'] 36 | group node['nginx']['group'] 37 | mode '0755' 38 | action :create 39 | end 40 | 41 | # install zabbix PHP config file 42 | template ::File.join(conf_dir, 'zabbix.conf.php') do 43 | source 'zabbix_web.conf.php.erb' 44 | owner 'root' 45 | group 'root' 46 | mode '754' 47 | variables( 48 | :database => node['zabbix']['database'], 49 | :server => node['zabbix']['server'] 50 | ) 51 | notifies :restart, 'service[php-fpm]', :delayed 52 | end 53 | 54 | # install host for zabbix 55 | template '/etc/nginx/sites-available/zabbix' do 56 | source 'zabbix_nginx.erb' 57 | owner 'root' 58 | group 'root' 59 | mode '754' 60 | variables( 61 | :server_name => node['zabbix']['web']['fqdn'], 62 | :php_settings => node['zabbix']['web']['php']['settings'], 63 | :web_port => node['zabbix']['web']['port'], 64 | :web_dir => node['zabbix']['web_dir'], 65 | :fastcgi_listen => node['zabbix']['web']['php']['fastcgi_listen'] 66 | ) 67 | notifies :reload, 'service[nginx]' 68 | end 69 | 70 | php_fpm_pool 'zabbix' do 71 | listen node['zabbix']['web']['php']['fastcgi_listen'] 72 | end 73 | 74 | nginx_site 'zabbix' 75 | -------------------------------------------------------------------------------- /resources/item.rb: -------------------------------------------------------------------------------- 1 | actions :create 2 | default_action :create 3 | 4 | attribute :name, :kind_of => String, :name_attribute => true 5 | attribute :template, :kind_of => String, :required => true 6 | attribute :applications, :kind_of => Array, :required => true 7 | attribute :key, :kind_of => String, :required => true 8 | attribute :type, :kind_of => Chef::Zabbix::API::ItemType, :required => true 9 | attribute :value_type, :kind_of => Chef::Zabbix::API::ItemValueType, :required => true 10 | attribute :server_connection, :kind_of => Hash, :required => true 11 | 12 | attribute :delay, :kind_of => Fixnum, :default => 60 13 | attribute :description, :kind_of => String 14 | attribute :snmp_community, :kind_of => String, :default => '{}' 15 | attribute :snmp_oid, :kind_of => String, :default => '{}' 16 | attribute :port, :kind_of => String 17 | attribute :item_params, :kind_of => String 18 | attribute :status, :kind_of => Chef::Zabbix::API::ItemStatus, :default => Chef::Zabbix::API::ItemStatus.enabled 19 | attribute :multiplier, :kind_of => Fixnum 20 | attribute :history, :kind_of => Fixnum, :default => 90 21 | attribute :trends, :kind_of => Fixnum, :default => 365 22 | attribute :allowed_hosts, :kind_of => String 23 | attribute :units, :kind_of => String 24 | attribute :delta, :kind_of => Chef::Zabbix::API::Delta, :default => Chef::Zabbix::API::Delta.as_is 25 | attribute :snmpv3_securityname, :kind_of => String 26 | attribute :snmpv3_securitylevel, :kind_of => Chef::Zabbix::API::SNMPV3SecurityLevel, :default => Chef::Zabbix::API::SNMPV3SecurityLevel.no_auth_no_priv 27 | attribute :snmpv3_authpassphrase, :kind_of => String 28 | attribute :snmpv3_privpassphrase, :kind_of => String 29 | attribute :formula, :kind_of => Fixnum, :default => 1 30 | attribute :delay_flex, :kind_of => String 31 | attribute :ipmi_sensor, :kind_of => String 32 | attribute :data_type, :kind_of => Chef::Zabbix::API::DataType, :default => Chef::Zabbix::API::DataType.decimal 33 | attribute :authtype, :kind_of => Chef::Zabbix::API::AuthType, :default => Chef::Zabbix::API::AuthType.password 34 | attribute :username, :kind_of => String 35 | attribute :password, :kind_of => String 36 | attribute :publickey, :kind_of => String 37 | attribute :privatekey, :kind_of => String 38 | attribute :inventory_link, :kind_of => Fixnum, :default => 0 # TODO: Make an enumeration for this 39 | attribute :valuemap, :kind_of => String 40 | 41 | # Setting discovery_rule will cause the item to be created as a prototype 42 | attribute :discovery_rule_key, :kind_of => String, :default => nil 43 | -------------------------------------------------------------------------------- /providers/graph.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | 4 | new_resource.graph_items.each do |graph_item| 5 | if graph_item[:item_template] 6 | template_id = Zabbix::API.find_template_ids(connection, graph_item[:item_template]).first['templateid'] 7 | if new_resource.prototype 8 | item_ids = Zabbix::API.find_item_prototype_ids(connection, template_id, graph_item[:item_key]) 9 | else 10 | item_ids = Zabbix::API.find_item_ids(connection, template_id, graph_item[:item_key]) 11 | end 12 | else 13 | item_ids = Zabbix::API.find_item_ids_on_host(connection, graph_item[:host], graph_item[:item_key]) 14 | end 15 | graph_item[:itemid] = item_ids.first['itemid'] 16 | end 17 | 18 | params = { 19 | :name => new_resource.name, 20 | 21 | :width => new_resource.width, 22 | :height => new_resource.height, 23 | :yaxismin => new_resource.yaxismin, 24 | :yaxismax => new_resource.yaxismax, 25 | :percent_left => new_resource.percent_left, 26 | :percent_right => new_resource.percent_right, 27 | 28 | :show_work_period => new_resource.show_work_period ? '1' : '0', 29 | :show_triggers => new_resource.show_triggers ? '1' : '0', 30 | :show_legend => new_resource.show_legend ? '1' : '0', 31 | :show_3d => new_resource.show_3d ? '1' : '0', 32 | 33 | :type => new_resource.type.value, 34 | :ymin_type => new_resource.ymin_type.value, 35 | :ymax_type => new_resource.ymax_type.value, 36 | :ymin_item => new_resource.ymin_item.to_s, 37 | :ymax_item => new_resource.ymax_item.to_s, 38 | 39 | :gitems => new_resource.graph_items.map(&:to_hash) 40 | } 41 | 42 | noun = (new_resource.prototype) ? 'graphprototype' : 'graph' 43 | verb = 'create' 44 | 45 | if new_resource.prototype 46 | graph_ids = Zabbix::API.find_graph_prototype_ids(connection, new_resource.name) 47 | else 48 | graph_ids = Zabbix::API.find_graph_ids(connection, new_resource.name) 49 | end 50 | 51 | unless graph_ids.empty? 52 | verb = 'update' 53 | params[:graphid] = graph_ids.first['graphid'] 54 | end 55 | 56 | method = "#{noun}.#{verb}" 57 | connection.query( 58 | :method => method, 59 | :params => params 60 | ) 61 | end 62 | new_resource.updated_by_last_action(true) 63 | end 64 | 65 | def load_current_resource 66 | run_context.include_recipe 'zabbix::_providers_common' 67 | require 'zabbixapi' 68 | end 69 | -------------------------------------------------------------------------------- /attributes/agent.rb: -------------------------------------------------------------------------------- 1 | # Load default.rb to use node['zabbix']['etc_dir'] 2 | include_attribute 'zabbix' 3 | 4 | default['zabbix']['agent']['install'] = true 5 | default['zabbix']['agent']['service_state'] = [:start, :enable] 6 | 7 | default['zabbix']['agent']['branch'] = 'ZABBIX%20Latest%20Stable' 8 | default['zabbix']['agent']['version'] = '2.2.0' 9 | default['zabbix']['agent']['source_url'] = nil 10 | default['zabbix']['agent']['servers'] = [] 11 | default['zabbix']['agent']['servers_active'] = [] 12 | default['zabbix']['agent']['hostname'] = node['fqdn'] 13 | default['zabbix']['agent']['configure_options'] = ['--with-libcurl'] 14 | default['zabbix']['agent']['include_dir'] = ::File.join(node['zabbix']['etc_dir'], 'agent_include') 15 | default['zabbix']['agent']['enable_remote_commands'] = true 16 | default['zabbix']['agent']['listen_port'] = '10050' 17 | default['zabbix']['agent']['timeout'] = '3' 18 | 19 | default['zabbix']['agent']['config_file'] = ::File.join(node['zabbix']['etc_dir'], 'zabbix_agentd.conf') 20 | default['zabbix']['agent']['userparams_config_file'] = ::File.join(node['zabbix']['agent']['include_dir'], 'user_params.conf') 21 | 22 | default['zabbix']['agent']['groups'] = ['chef-agent'] 23 | 24 | case node['platform_family'] 25 | when 'rhel', 'debian' 26 | default['zabbix']['agent']['init_style'] = 'sysvinit' 27 | default['zabbix']['agent']['install_method'] = 'prebuild' 28 | default['zabbix']['agent']['pid_file'] = ::File.join(node['zabbix']['run_dir'], 'zabbix_agentd.pid') 29 | 30 | default['zabbix']['agent']['user'] = 'zabbix' 31 | default['zabbix']['agent']['group'] = node['zabbix']['agent']['user'] 32 | 33 | default['zabbix']['agent']['shell'] = node['zabbix']['shell'] 34 | when 'windows' 35 | default['zabbix']['agent']['init_style'] = 'windows' 36 | default['zabbix']['agent']['install_method'] = 'chocolatey' 37 | end 38 | 39 | default['zabbix']['agent']['log_file'] = nil # default (Syslog / windows event). 40 | # default['zabbix']['agent']['log_file'] = ::File.join(node['zabbix']['log_dir'], "zabbix_agentd.log" 41 | default['zabbix']['agent']['start_agents'] = nil # default (3) 42 | default['zabbix']['agent']['debug_level'] = nil # default (3) 43 | default['zabbix']['agent']['templates'] = [] 44 | default['zabbix']['agent']['interfaces'] = ['zabbix_agent'] 45 | default['zabbix']['agent']['jmx_port'] = '10052' 46 | default['zabbix']['agent']['zabbix_agent_port'] = '10050' 47 | default['zabbix']['agent']['snmp_port'] = '161' 48 | 49 | default['zabbix']['agent']['user_parameter'] = [] 50 | -------------------------------------------------------------------------------- /templates/default/zabbix_server.init-rh.erb: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # zabbix_server service script 4 | # 5 | # chkconfig: 345 70 45 6 | # description: The Zabbix Server 7 | # processname: zabbix_server 8 | # 9 | 10 | # Provides: zabbix_server 11 | ### BEGIN INIT INFO 12 | # Required-Start: $local_fs $remote_fs 13 | # Required-Stop: $local_fs $remote_fs 14 | # Default-Start: 2 3 4 5 15 | # Default-Stop: S 0 1 6 16 | # Short-Description: Zabbix server daemon 17 | # Description: Controls the Zabbix server daemon 18 | ### END INIT INFO 19 | 20 | # Define LSB functions. 21 | . /lib/lsb/init-functions 22 | 23 | NAME=zabbix_server 24 | PATH=/bin:/usr/bin:/sbin:/usr/sbin:<%= node.zabbix.install_dir %>/sbin 25 | DAEMON=<%= node.zabbix.install_dir %>/sbin/${NAME} 26 | OPTS="-c <%= node.zabbix.etc_dir %>/zabbix_server.conf" 27 | DESC="Zabbix server daemon" 28 | DIR=<%= node.zabbix.run_dir %> 29 | PID=<%= node.zabbix.run_dir %>/$NAME.pid 30 | LOCK=<%= node.zabbix.lock_dir %>/$NAME 31 | 32 | # Exit if the package is not installed 33 | if [ ! -x "$DAEMON" ]; then 34 | { 35 | echo "Couldn't find $DAEMON" 36 | exit 99 37 | } 38 | fi 39 | 40 | [ -d "$DIR" ] || mkdir "$DIR" 41 | chown -R zabbix:zabbix "$DIR" 42 | 43 | start() 44 | { 45 | start_daemon -p $PID $DAEMON $OPTS 46 | RETVAL=$? 47 | [ $RETVAL -eq 0 ] && touch $LOCK 48 | return $RETVAL 49 | } 50 | 51 | stop() 52 | { 53 | killproc -p $PID 54 | RETVAL="$?" 55 | [ $RETVAL -eq 0 ] && rm -f $PID $LOCK 56 | return "$RETVAL" 57 | } 58 | 59 | case "$1" in 60 | start) 61 | start 62 | if [ "$?" -gt 0 ]; 63 | then 64 | log_failure_msg "$NAME did not start" 65 | else 66 | log_success_msg "$NAME started" 67 | fi 68 | ;; 69 | stop) 70 | stop 71 | if [ "$?" -gt 0 ]; 72 | then 73 | log_failure_msg "$NAME did not stop" 74 | else 75 | log_success_msg "$NAME stopped" 76 | fi 77 | ;; 78 | restart) 79 | stop 80 | if [ "$?" -gt 0 ]; 81 | then 82 | log_failure_msg "$NAME did not stop" 83 | else 84 | sleep 5 85 | start 86 | if [ "$?" -gt 0 ]; 87 | then 88 | log_failure_msg "$NAME did not start" 89 | else 90 | log_success_msg "$NAME restarted" 91 | fi 92 | fi 93 | ;; 94 | status) 95 | PID_NUM=$(pidofproc -p $PID) 96 | if [ "$?" -gt 0 ]; 97 | then 98 | log_failure_msg "$NAME is not running" 99 | exit 1 100 | else 101 | log_success_msg "$NAME is running ($PID_NUM)" 102 | exit 0 103 | fi 104 | ;; 105 | *) 106 | echo "Usage: $NAME {start|stop|restart|status}" >&2 107 | exit 3 108 | ;; 109 | esac 110 | 111 | exit 0 -------------------------------------------------------------------------------- /templates/default/zabbix_agentd.init.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: zabbix_agentd 4 | # Required-Start: $remote_fs $network 5 | # Required-Stop: $remote_fs 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Start zabbix_agentd at boot time 9 | # Description: Zabbix agent. 10 | ### END INIT INFO 11 | # 12 | # Zabbix agent start/stop script. 13 | # 14 | # Written by Alexei Vladishev . 15 | # Add status support by Ovea Inc. 16 | 17 | NAME=zabbix_agentd 18 | PATH=/bin:/usr/bin:/sbin:/usr/sbin:<%= node['zabbix']['install_dir'] %>/sbin:<%= node['zabbix']['install_dir'] %>/bin 19 | DAEMON=<%= node['zabbix']['install_dir'] %>/sbin/${NAME} 20 | DESC="Zabbix agent daemon" 21 | DIR=<%= node['zabbix']['run_dir'] %> 22 | PID=<%= node['zabbix']['agent']['pid_file'] %> 23 | USER=<%= node['zabbix']['agent']['user'] %> 24 | GROUP=<%= node['zabbix']['agent']['group'] %> 25 | 26 | test -f $DAEMON || exit 0 27 | 28 | [ -d "$DIR" ] || mkdir "$DIR" 29 | chown -R $USER:$GROUP "$DIR" 30 | 31 | set -e 32 | 33 | case "$1" in 34 | start) 35 | echo "Starting $DESC: $NAME" 36 | start-stop-daemon --oknodo --start --pidfile $PID \ 37 | --user $USER \ 38 | --exec $DAEMON -- -c <%= node['zabbix']['agent']['config_file'] %> 39 | ;; 40 | 41 | stop) 42 | echo "Stopping $DESC: $NAME" 43 | start-stop-daemon --oknodo --stop --pidfile $PID \ 44 | --exec $DAEMON 45 | ;; 46 | restart|force-reload) 47 | # 48 | # If the "reload" option is implemented, move the "force-reload" 49 | # option to the "reload" entry above. If not, "force-reload" is 50 | # just the same as "restart". 51 | # 52 | # echo -n "Restarting $DESC: zabbix_agent" 53 | $0 stop 54 | sleep 5 55 | $0 start 56 | # start-stop-daemon --stop --quiet --pidfile \ 57 | # $PID --user zabbix --exec $DAEMON 58 | # sleep 1 59 | # start-stop-daemon --start --quiet --pidfile \ 60 | # $PID --user zabbix --exec $DAEMON 61 | # echo "$NAME." 62 | ;; 63 | status) 64 | if [ -f "$PID" ]; then 65 | echo "zabbix_agentd is running (pid $PID)." 66 | PIDVALID=$(ps --pid `cat $PID` -o pid=) 67 | if [ $PIDVALID ]; then 68 | exit 0 69 | else 70 | echo "pid file exist but zabbix_agentd is NOT running." 71 | fi 72 | else 73 | echo "zabbix_agentd is NOT running." 74 | exit 1 75 | fi 76 | ;; 77 | 78 | *) 79 | N=/etc/init.d/$NAME 80 | # echo "Usage: $N {start|stop|restart|force-reload}" >&2 81 | echo "Usage: $N {start|stop|restart|force-reload}" >&2 82 | exit 1 83 | ;; 84 | esac 85 | 86 | exit 0 87 | -------------------------------------------------------------------------------- /providers/item.rb: -------------------------------------------------------------------------------- 1 | action :create do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | template_ids = Zabbix::API.find_template_ids(connection, new_resource.template) 4 | if template_ids.empty? 5 | Chef::Application.fatal! "Could not find a template named #{new_resource.template}" 6 | end 7 | 8 | template_id = template_ids.first['hostid'] 9 | 10 | application_ids = new_resource.applications.map do |application| 11 | app_ids = Zabbix::API.find_application_ids(connection, application, template_id) 12 | if app_ids.empty? 13 | Chef::Application.fatal! "Could not find an application named #{application}" 14 | end 15 | app_ids.map { |app_id| app_id['applicationid'] } 16 | end.flatten 17 | 18 | noun = (new_resource.discovery_rule_key.nil?) ? 'item' : 'itemprototype' 19 | verb = 'create' 20 | 21 | params = {} 22 | simple_value_keys = [ 23 | :name, :delay, :description, :snmp_community, :snmp_oid, 24 | :port, :params, :multiplier, :history, :trends, :allowed_hosts, 25 | :units, :snmpv3_securityname, :snmpv3_authpassphrase, :snmpv3_privpassphrase, 26 | :formula, :delay_flex, :ipmi_sensor, :username, :password, 27 | :publickey, :privatekey, :inventory_link, :valuemap, 28 | ] 29 | simple_value_keys.each do |key| 30 | params[key] = new_resource.send(key) 31 | end 32 | 33 | enum_value_keys = [ 34 | :type, :value_type, :status, :delta, :snmpv3_securitylevel, 35 | :data_type, :authtype, 36 | ] 37 | enum_value_keys.each do |key| 38 | params[key] = new_resource.send(key).value 39 | end 40 | 41 | params[:params] = new_resource.item_params 42 | params[:key_] = new_resource.key 43 | params[:hostid] = template_id 44 | params[:applications] = application_ids 45 | unless new_resource.discovery_rule_key.nil? 46 | discovery_rule_id = Zabbix::API.find_lld_rule_ids(connection, template_id, new_resource.discovery_rule_key).first['itemid'] 47 | params[:ruleid] = discovery_rule_id 48 | end 49 | 50 | if new_resource.discovery_rule_key.nil? 51 | item_ids = Zabbix::API.find_item_ids(connection, template_id, new_resource.key, new_resource.name) 52 | else 53 | item_ids = Zabbix::API.find_item_prototype_ids(connection, template_id, new_resource.key, discovery_rule_id) 54 | end 55 | 56 | unless item_ids.empty? 57 | verb = 'update' 58 | params[:itemid] = item_ids.first['itemid'] 59 | end 60 | 61 | connection.query( 62 | :method => "#{noun}.#{verb}", 63 | :params => params 64 | ) 65 | end 66 | 67 | new_resource.updated_by_last_action(true) 68 | end 69 | 70 | def load_current_resource 71 | run_context.include_recipe 'zabbix::_providers_common' 72 | require 'zabbixapi' 73 | end 74 | -------------------------------------------------------------------------------- /templates/default/zabbix_agentd.init-rh.erb: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # zabbix_agentd service script 4 | # 5 | # chkconfig: 345 70 45 6 | # description: The Zabbix agent (daemon) 7 | # processname: zabbix_agentd 8 | # 9 | 10 | ### BEGIN INIT INFO 11 | # Provides: zabbix_agentd 12 | # Required-Start: $local_fs $remote_fs 13 | # Required-Stop: $local_fs $remote_fs 14 | # Default-Start: 2 3 4 5 15 | # Default-Stop: S 0 1 6 16 | # Short-Description: Zabbix agent daemon 17 | # Description: Controls the Zabbix agent daemon 18 | ### END INIT INFO 19 | 20 | # Define LSB functions. 21 | . /lib/lsb/init-functions 22 | 23 | NAME=zabbix_agentd 24 | PATH=/bin:/usr/bin:/sbin:/usr/sbin:<%= node.zabbix.install_dir %>/sbin:<%= node.zabbix.install_dir %>/bin 25 | DAEMON=<%= node.zabbix.install_dir %>/sbin/${NAME} 26 | DESC="Zabbix agent daemon" 27 | DIR=<%= node.zabbix.run_dir %> 28 | PID=<%= node['zabbix']['agent']['pid_file'] %> 29 | LOCK=<%= node.zabbix.lock_dir %>/$NAME 30 | USER=<%= node['zabbix']['agent']['user'] %> 31 | GROUP=<%= node['zabbix']['agent']['group'] %> 32 | 33 | # Exit if the package is not installed 34 | if [ ! -x "$DAEMON" ]; then 35 | { 36 | echo "Couldn't find $DAEMON" 37 | exit 99 38 | } 39 | fi 40 | 41 | [ -d "$DIR" ] || mkdir "$DIR" 42 | chown -R $USER:$GROUP "$DIR" 43 | 44 | start() 45 | { 46 | start_daemon -p $PID -u $USER $DAEMON -c <%= node['zabbix']['agent']['config_file'] %> 47 | RETVAL=$? 48 | [ $RETVAL -eq 0 ] && touch $LOCK 49 | return $RETVAL 50 | } 51 | 52 | stop() 53 | { 54 | killproc -p $PID 55 | RETVAL="$?" 56 | [ $RETVAL -eq 0 ] && rm -f $PID $LOCK 57 | return "$RETVAL" 58 | } 59 | 60 | case "$1" in 61 | start) 62 | start 63 | if [ "$?" -gt 0 ]; 64 | then 65 | log_failure_msg "$NAME did not start" 66 | else 67 | log_success_msg "$NAME started" 68 | fi 69 | ;; 70 | stop) 71 | stop 72 | if [ "$?" -gt 0 ]; 73 | then 74 | log_failure_msg "$NAME did not stop" 75 | else 76 | log_success_msg "$NAME stopped" 77 | fi 78 | ;; 79 | restart) 80 | stop 81 | if [ "$?" -gt 0 ]; 82 | then 83 | log_failure_msg "$NAME did not stop" 84 | else 85 | sleep 5 86 | start 87 | if [ "$?" -gt 0 ]; 88 | then 89 | log_failure_msg "$NAME did not start" 90 | else 91 | log_success_msg "$NAME restarted" 92 | fi 93 | fi 94 | ;; 95 | status) 96 | PID_NUM=$(pidofproc -p $PID) 97 | if [ "$?" -gt 0 ]; 98 | then 99 | log_failure_msg "$NAME is not running" 100 | exit 1 101 | else 102 | log_success_msg "$NAME is running ($PID_NUM)" 103 | exit 0 104 | fi 105 | ;; 106 | *) 107 | echo "Usage: $NAME {start|stop|restart|status}" >&2 108 | exit 3 109 | ;; 110 | esac 111 | 112 | exit 0 113 | -------------------------------------------------------------------------------- /libraries/chef_zabbix_errors.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: zabbix 3 | # Library:: chef_zabbix_errors 4 | # 5 | # Author:: Andrew Garson() 6 | # 7 | 8 | class Chef 9 | module Zabbix 10 | class ZabbixError < StandardError; end 11 | 12 | class InvalidMySqlConnectionInfoError < ZabbixError 13 | def initialize(bad_connection_info) 14 | @bad_connection_info = bad_connection_info 15 | end 16 | 17 | def to_s 18 | "MySql connection info must be a Hash containing :host, :dbname, :username and :root keys. Received: #{@bad_connection_info}" 19 | end 20 | end 21 | 22 | class InvalidZabbixServerSpecificationError < ZabbixError 23 | def initialize(bad_connection_spec) 24 | @bad_connection_spec = bad_connection_spec 25 | end 26 | 27 | def to_s 28 | "ZabbixApi connection info must be a Hash containing :url, :user and :password keys. Received: #{@bad_connection_spec}" 29 | end 30 | end 31 | 32 | class ServerNotReachableError < ZabbixError 33 | def initialize(ip, port) 34 | @ip = ip 35 | @port = port 36 | end 37 | 38 | def to_s 39 | "Zabbix Server not reachable on '#{@ip}:#{@port}'" 40 | end 41 | end 42 | 43 | class UnknownHostInterfaceTypeError < ZabbixError 44 | def initialize(type) 45 | @type = type 46 | end 47 | 48 | def to_s 49 | "Interface type must be one of [:agent, :snmp, :ipmi, :jmx] but received '#{@type}'" 50 | end 51 | end 52 | 53 | class HostGroupNotFoundError < ZabbixError 54 | def initialize(group) 55 | @group = group 56 | end 57 | 58 | def to_s 59 | "Could not find a HostGroup named '#{@group}'" 60 | end 61 | end 62 | 63 | class InvalidDataTypeError < ZabbixError 64 | def initialize(data_type) 65 | @data_type = data_type 66 | end 67 | 68 | def message 69 | "Data Type '#{data_type}' is not known.\n 70 | Known Data Types: \n 71 | -- hostgroups\n 72 | -- templates\n 73 | -- applications\n 74 | " 75 | end 76 | end 77 | 78 | class InvalidApiMethodError < ZabbixError 79 | def initialize(data_type, method) 80 | @data_type = data_type 81 | @method = method 82 | end 83 | 84 | def message 85 | "Method '#{@method}' is unknown for Data Type '#{@data_type}'" 86 | end 87 | end 88 | 89 | class InvalidParametersHashError < ZabbixError 90 | def initialize(bad_params) 91 | @bad_params = bad_params 92 | end 93 | 94 | def message 95 | "Expected parameters to be a Hash but got '#{@bad_params.class}': #{@bad_params}" 96 | end 97 | end 98 | end 99 | end 100 | -------------------------------------------------------------------------------- /recipes/database.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'zabbix::common' 2 | 3 | ::Chef::Recipe.send(:include, Opscode::OpenSSL::Password) 4 | 5 | include_recipe 'database::mysql' 6 | include_recipe 'mysql::client' 7 | 8 | # Generates passwords if they aren't already set 9 | # This is INSECURE because node.normal persists the passwords to the chef 10 | # server, making them visible to anybody with access 11 | # 12 | # Under chef_solo these must be set somehow because node.normal doesn't persist 13 | # between runs 14 | 15 | unless node['zabbix']['database']['dbpassword'] 16 | node.normal['zabbix']['database']['dbpassword'] = secure_password 17 | end 18 | 19 | case node['zabbix']['database']['install_method'] 20 | when 'rds_mysql' 21 | root_username = node['zabbix']['database']['rds_master_username'] 22 | root_password = node['zabbix']['database']['rds_master_password'] 23 | allowed_user_hosts = '%' 24 | provider = Chef::Provider::ZabbixDatabaseMySql 25 | when 'mysql' 26 | unless node['mysql']['server_root_password'] 27 | node.normal['mysql']['server_root_password'] = secure_password 28 | end 29 | root_username = 'root' 30 | root_password = node['mysql']['server_root_password'] 31 | allowed_user_hosts = node['zabbix']['database']['allowed_user_hosts'] 32 | provider = Chef::Provider::ZabbixDatabaseMySql 33 | when 'postgres' 34 | unless node['postgresql']['password']['postgres'] 35 | node.normal['postgresql']['password']['postgres'] = secure_password 36 | end 37 | root_username = 'postgres' 38 | root_password = node['postgresql']['password']['postgres'] 39 | provider = Chef::Provider::ZabbixDatabasePostgres 40 | when 'oracle' 41 | # No oracle database installation or configuration currently done 42 | # This recipe expects a fully configured Oracle DB with a Zabbix 43 | # user + schema. The instant client is just for compiling php-oci8 44 | # and Zabbix itself 45 | include_recipe 'oracle-instantclient' 46 | include_recipe 'oracle-instantclient::sdk' 47 | # Not used yet but needs to be set 48 | root_username = 'sysdba' 49 | root_password = 'not_applicable' 50 | provider = Chef::Provider::ZabbixDatabaseOracle 51 | end 52 | 53 | zabbix_database node['zabbix']['database']['dbname'] do 54 | provider provider 55 | host node['zabbix']['database']['dbhost'] 56 | port node['zabbix']['database']['dbport'].to_i 57 | username node['zabbix']['database']['dbuser'] 58 | password node['zabbix']['database']['dbpassword'] 59 | root_username root_username 60 | root_password root_password 61 | allowed_user_hosts allowed_user_hosts 62 | source_url node['zabbix']['server']['source_url'] 63 | server_version node['zabbix']['server']['version'] 64 | source_dir node['zabbix']['src_dir'] 65 | install_dir node['zabbix']['install_dir'] 66 | branch node['zabbix']['server']['branch'] 67 | version node['zabbix']['server']['version'] 68 | end 69 | -------------------------------------------------------------------------------- /recipes/agent_registration.rb: -------------------------------------------------------------------------------- 1 | # Author:: Guilhem Lettron () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: agent_registration 4 | # 5 | # Apache 2.0 6 | # 7 | 8 | if !Chef::Config[:solo] 9 | zabbix_server = search(:node, 'recipe:zabbix\\:\\:server').first 10 | else 11 | if node['zabbix']['web']['fqdn'] 12 | zabbix_server = node 13 | else 14 | Chef::Log.warn('This recipe uses search. Chef Solo does not support search.') 15 | Chef::Log.warn("If you did not set node['zabbix']['web']['fqdn'], the recipe will fail") 16 | return 17 | end 18 | end 19 | 20 | connection_info = { 21 | :url => "http://#{zabbix_server['zabbix']['web']['fqdn']}/api_jsonrpc.php", 22 | :user => zabbix_server['zabbix']['web']['login'], 23 | :password => zabbix_server['zabbix']['web']['password'] 24 | } 25 | 26 | ip_address = node['ipaddress'] 27 | if node['zabbix']['agent']['network_interface'] 28 | target_interface = node['zabbix']['agent']['network_interface'] 29 | if node['network']['interfaces'][target_interface] 30 | ip_address = node['network']['interfaces'][target_interface]['addresses'].keys[1] 31 | Chef::Log.debug "zabbix::agent_registration : Using ip address of #{ip_address} for host" 32 | else 33 | Chef::Log.warn "zabbix::agent_registration : Could not find interface address for #{target_interface}, falling back to default" 34 | end 35 | end 36 | 37 | interface_definitions = { 38 | :zabbix_agent => { 39 | :type => 1, 40 | :main => 1, 41 | :useip => 1, 42 | :ip => ip_address, 43 | :dns => node['fqdn'], 44 | :port => node['zabbix']['agent']['zabbix_agent_port'] 45 | }, 46 | :jmx => { 47 | :type => 4, 48 | :main => 1, 49 | :useip => 1, 50 | :ip => ip_address, 51 | :dns => node['fqdn'], 52 | :port => node['zabbix']['agent']['jmx_port'] 53 | }, 54 | :snmp => { 55 | :type => 2, 56 | :main => 1, 57 | :useip => 1, 58 | :ip => ip_address, 59 | :dns => node['fqdn'], 60 | :port => node['zabbix']['agent']['snmp_port'] 61 | } 62 | } 63 | 64 | interface_list = node['zabbix']['agent']['interfaces'] 65 | 66 | interface_data = [] 67 | interface_list.each do |interface| 68 | if interface_definitions.key?(interface.to_sym) 69 | interface_data.push(interface_definitions[interface.to_sym]) 70 | else 71 | Chef::Log.warn "WARNING: Interface #{interface} is not defined in agent_registration.rb" 72 | end 73 | end 74 | 75 | zabbix_host node['zabbix']['agent']['hostname'] do 76 | create_missing_groups true 77 | server_connection connection_info 78 | parameters( 79 | :host => node['hostname'], 80 | :groupNames => node['zabbix']['agent']['groups'], 81 | :templates => node['zabbix']['agent']['templates'], 82 | :interfaces => interface_data 83 | ) 84 | action :nothing 85 | end 86 | 87 | log 'Delay agent registration to wait for server to be started' do 88 | level :debug 89 | notifies :create_or_update, "zabbix_host[#{node['zabbix']['agent']['hostname']}]", :delayed 90 | end 91 | -------------------------------------------------------------------------------- /providers/source.rb: -------------------------------------------------------------------------------- 1 | action :extract_only do 2 | tar_path = zabbix_tar_path(new_resource.code_dir, new_resource.branch, new_resource.version) 3 | 4 | if !::File.exist?(tar_path) 5 | Chef::Log.info("Zabbix tar: #{tar_path} does't exist") 6 | remote_file tar_path do 7 | source new_resource.source_url 8 | mode '0644' 9 | action :create 10 | end 11 | new_resource.updated_by_last_action(true) 12 | else 13 | Chef::Log.info("Zabbix tar: #{tar_path} already exists") 14 | end 15 | 16 | extract_to = extract_dir(new_resource.code_dir, new_resource.target_dir) 17 | tmp_dir = ::File.join('/tmp', "zabbix-#{new_resource.version}") 18 | if !::File.exist?(extract_to) 19 | Chef::Log.info("Zabbix extract: #{extract_to} doesn't exist") 20 | script "extract Zabbix to #{extract_to}" do 21 | interpreter 'bash' 22 | user 'root' 23 | code <<-EOH 24 | rm -rf #{tmp_dir} 25 | tar xvfz #{tar_path} -C /tmp 26 | mv #{tmp_dir} #{extract_to} 27 | EOH 28 | 29 | not_if { ::File.exist?(extract_to) } 30 | end 31 | new_resource.updated_by_last_action(true) 32 | else 33 | Chef::Log.info("Zabbix extract: #{extract_to} already exists") 34 | end 35 | end 36 | 37 | action :install_server do 38 | action_extract_only 39 | 40 | source_dir = extract_dir(new_resource.code_dir, new_resource.target_dir) 41 | unless ::File.exist?(::File.join(source_dir, 'already_built')) 42 | Chef::Log.info("Compiling Zabbix Server with options '#{new_resource.configure_options}") 43 | script "install_zabbix_server_#{zabbix_source_identifier(new_resource.branch, new_resource.version)}" do 44 | interpreter 'bash' 45 | user 'root' 46 | code <<-EOH 47 | (cd #{source_dir} && ./configure --enable-server --prefix=#{new_resource.install_dir} #{new_resource.configure_options}) 48 | (cd #{source_dir} && make install && touch already_built) 49 | EOH 50 | end 51 | new_resource.updated_by_last_action(true) 52 | end 53 | end 54 | 55 | action :install_agent do 56 | action_extract_only 57 | 58 | source_dir = extract_dir(new_resource.code_dir, new_resource.target_dir) 59 | unless ::File.exist?(::File.join(source_dir, 'already_built')) 60 | Chef::Log.info("Compiling Zabbix Agent with options '#{new_resource.configure_options}") 61 | script "install_zabbix_agent_#{zabbix_source_identifier(new_resource.branch, new_resource.version)}" do 62 | interpreter 'bash' 63 | user 'root' 64 | code <<-EOH 65 | (cd #{source_dir} && ./configure --enable-agent --prefix=#{new_resource.install_dir} #{new_resource.configure_options}) 66 | (cd #{source_dir} && make install && touch already_built) 67 | EOH 68 | end 69 | new_resource.updated_by_last_action(true) 70 | end 71 | end 72 | 73 | def load_current_resource 74 | run_context.include_recipe 'zabbix::_providers_common' 75 | require 'zabbixapi' 76 | end 77 | 78 | def zabbix_source_identifier(branch, version) 79 | "#{branch.gsub('%20', '-')}-#{version}" 80 | end 81 | 82 | def zabbix_tar_path(code_dir, branch, version) 83 | ::File.join(code_dir, "zabbix-#{zabbix_source_identifier(branch, version)}.tar.gz") 84 | end 85 | 86 | def extract_dir(code_dir, target_dir) 87 | ::File.join(code_dir, target_dir) 88 | end 89 | -------------------------------------------------------------------------------- /files/default/zabbix-java-gateway/init.debian: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: zabbix-java-gateway 4 | # Required-Start: $remote_fs $network 5 | # Required-Stop: $remote_fs 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Start zabbix-java-gateway daemon 9 | # Description: Control zabbix-java-gateway daemon 10 | ### END INIT INFO 11 | 12 | NAME=zabbix-java-gateway 13 | DAEMON=/usr/bin/java 14 | # Exit if executable is not installed 15 | [ -x $DAEMON ] || exit 0 16 | 17 | DIR="/var/run/zabbix" 18 | EXECDIR="/opt/zabbix/sbin/zabbix_java" 19 | PID_FILE=$DIR/$NAME.pid 20 | RETRY=TERM/30/KILL/5 21 | 22 | #if [ "$(id -u)" -ne 0 ]; then 23 | # echo "Error: root privileges are needed to run $0" 24 | # exit 1 25 | #fi 26 | 27 | # Source Zabbix java gateway configuration file 28 | . /etc/zabbix/zabbix_java_gateway.conf 29 | 30 | ZABBIX_OPTIONS="" 31 | if [ -n "$PID_FILE" ]; then 32 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.pidFile=$PID_FILE" 33 | fi 34 | if [ -n "$LISTEN_IP" ]; then 35 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.listenIP=$LISTEN_IP" 36 | fi 37 | if [ -n "$LISTEN_PORT" ]; then 38 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.listenPort=$LISTEN_PORT" 39 | fi 40 | if [ -n "$START_POLLERS" ]; then 41 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.startPollers=$START_POLLERS" 42 | fi 43 | 44 | CLASSPATH="$EXECDIR/lib" 45 | for jar in $EXECDIR/{lib,bin}/*.jar; do 46 | if [[ $jar != *junit* ]]; then 47 | CLASSPATH="$CLASSPATH:$jar" 48 | fi 49 | done 50 | 51 | DAEMON_ARGS="${JAVA_OPTIONS} -server ${ZABBIX_OPTIONS} -Dlogback.configurationFile=/etc/zabbix/zabbix_java_gateway.logback.xml -Djava.library.path=/usr/lib/jni -classpath $CLASSPATH com.zabbix.gateway.JavaGateway" 52 | 53 | # Load the VERBOSE setting and other rcS variables 54 | [ -f /etc/default/rcS ] && . /etc/default/rcS 55 | 56 | # define LSB log_* functions. 57 | . /lib/lsb/init-functions 58 | 59 | _ev_ () { 60 | [ "$VERBOSE" = "no" ] || eval $@ 61 | } 62 | 63 | [ -d "$DIR" ] || mkdir "$DIR" 64 | chown -R zabbix:zabbix "$DIR" 65 | export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" 66 | 67 | case "$1" in 68 | start) 69 | start-stop-daemon --start --pidfile $PID_FILE --exec $DAEMON --test --quiet > /dev/null 70 | [ $? -ne 0 ] && log_action_msg "$NAME is already running" && exit 0 71 | _ev_ log_action_begin_msg \"$NAME starting\" 72 | R=$(start-stop-daemon --start --background --make-pidfile --user zabbix --group zabbix --chuid zabbix --pidfile $PID_FILE --exec $DAEMON --oknodo -- ${DAEMON_ARGS} 2>&1) \ 73 | && _ev_ log_action_end_msg 0 \"$R\" \ 74 | || _ev_ log_action_end_msg 1 \"$R\" 75 | ;; 76 | stop) 77 | _ev_ log_action_begin_msg "$NAME stopping" 78 | R=$(start-stop-daemon --stop --pidfile $PID_FILE --oknodo --retry=$RETRY 2>&1) 79 | if [ $? -ne 0 ]; then 80 | _ev_ log_action_end_msg 1 \"$R\" 81 | else 82 | t=5 83 | while $0 status >/dev/null; do 84 | _ev_ log_action_cont_msg \"[$t]\" 85 | t=$(($t-1)) 86 | if [ $t -ne 0 ]; then 87 | sleep 1 88 | continue 89 | else 90 | break 91 | fi 92 | done 93 | $0 status >/dev/null \ 94 | && _ev_ log_action_end_msg 1 \"still running after 5 sec., unable to stop\" \ 95 | || _ev_ log_action_end_msg 0 \"$R\" 96 | fi 97 | ;; 98 | status) 99 | ## return status 0 if process is running. 100 | status_of_proc -p $PID_FILE "$DAEMON" "$NAME" 101 | ;; 102 | restart|force-reload) 103 | $0 stop 104 | $0 status >/dev/null \ 105 | && exit 1 \ 106 | || $0 start 107 | ;; 108 | *) 109 | echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}" >&2 110 | exit 1 111 | ;; 112 | esac 113 | -------------------------------------------------------------------------------- /providers/host.rb.good: -------------------------------------------------------------------------------- 1 | action :create_or_update do 2 | chef_gem "zabbixapi" do 3 | action :install 4 | version "~> 0.6.3" 5 | end 6 | 7 | require 'zabbixapi' 8 | 9 | 10 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 11 | 12 | hostId = connection.query( :method => "host.get", 13 | :params => 14 | { 15 | :filter => 16 | { 17 | :host => new_resource.hostname 18 | } 19 | }) 20 | if hostId.size == 0 21 | action :create 22 | else 23 | puts "doing an update" 24 | action :update 25 | end 26 | end 27 | end 28 | 29 | action :create do 30 | 31 | chef_gem "zabbixapi" do 32 | action :install 33 | version "~> 0.6.3" 34 | end 35 | 36 | require 'zabbixapi' 37 | 38 | 39 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 40 | 41 | connection.query( :method => "host.create", 42 | :params => { 43 | :host => new_resource.hostname, 44 | :interfaces => [ 45 | { 46 | :type => 1, 47 | :main => 1, 48 | :useip => 1, 49 | :ip => node['ipaddress'], 50 | :dns => node['fqdn'], 51 | :port => "10050", 52 | } 53 | ] 54 | } 55 | ) 56 | end 57 | new_resource.updated_by_last_action(true) 58 | end 59 | 60 | action :update do 61 | chef_gem "zabbixapi" do 62 | action :install 63 | version "~> 0.6.3" 64 | end 65 | 66 | require 'zabbixapi' 67 | 68 | puts node['ipaddress'] 69 | 70 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 71 | # Update the host 72 | connection.query( :method => "host.update", 73 | :params => new_resource.params 74 | ) 75 | end 76 | new_resource.updated_by_last_action(true) 77 | end 78 | 79 | action :link do 80 | chef_gem "zabbixapi" do 81 | action :install 82 | version "~> 0.6.3" 83 | end 84 | 85 | require 'zabbixapi' 86 | 87 | puts node['ipaddress'] 88 | 89 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 90 | puts new_resource.hostname 91 | hostId = connection.query( :method => "host.get", 92 | :params => { 93 | :filter => {:host => new_resource.hostname} 94 | }) 95 | puts hostId 96 | # get the IDS of the templates in the array 97 | templateId = [] 98 | linkTo = [] 99 | new_resource.templates.each do |template| 100 | puts template 101 | templateId = connection.query( :method => "template.get", 102 | :params => { 103 | :filter => { 104 | :host => template,}, 105 | }) 106 | puts templateId[0]['templateid'] 107 | linkTo.push( :templateid => templateId[0]['templateid'] ) 108 | end 109 | connection.query( :method => "host.update", 110 | :params => { 111 | :hostid => hostId[0]['hostid'], 112 | :templates => linkTo, 113 | }) 114 | end 115 | new_resource.updated_by_last_action(true) 116 | end 117 | -------------------------------------------------------------------------------- /files/default/zabbix-java-gateway/init.rhel: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # chkconfig: - 69 15 4 | # description: zabbix java gateway 5 | # 6 | 7 | ### BEGIN INIT INFO 8 | # Provides: zabbix 9 | # Required-Start: $local_fs $network 10 | # Required-Stop: $local_fs $network 11 | # Default-Start: 12 | # Default-Stop: 0 1 2 3 4 5 6 13 | # Short-Description: start and stop zabbix java gateway 14 | # Description: Zabbix Java Gateway 15 | ### END INIT INFO 16 | 17 | # Source function library. 18 | . /etc/rc.d/init.d/functions 19 | 20 | # Source networking configuration. 21 | . /etc/sysconfig/network 22 | 23 | # Source Zabbix Java Gateway configuration 24 | . /etc/zabbix/zabbix_java_gateway.conf 25 | 26 | # Check that networking is up. 27 | [ ${NETWORKING} = "no" ] && exit 0 28 | 29 | RETVAL=0 30 | EXECDIR="/opt/zabbix/sbin/zabbix_java" 31 | 32 | is_running() { 33 | if [ -n "$PID_FILE" -a -e "$PID_FILE" ]; then 34 | PID=$(cat $PID_FILE) 35 | # Fragile - convert this to systemd 36 | kill -0 $PID 2> /dev/null 37 | if (( $? == 0 )); then 38 | echo "zabbix java gateway is already running" 39 | return 1 40 | else 41 | rm $PID_FILE 42 | fi 43 | fi 44 | # Again, another reason to use systemd 45 | PID=$(ps auxww | grep com.zabbix.gateway.JavaGatewa[y] | awk '{print $2}') 46 | if [[ "$PID" != "" ]]; then 47 | echo "Zabbix java gateway is already running (found com.zabbix.gateway.JavaGateway process)." 48 | return 1 49 | fi 50 | } 51 | 52 | case "$1" in 53 | start) 54 | CLASSPATH="$EXECDIR/lib" 55 | for jar in $EXECDIR/{lib,bin}/*.jar; do 56 | if [[ $jar != *junit* ]]; then 57 | CLASSPATH="$CLASSPATH:$jar" 58 | fi 59 | done 60 | JAVA=${JAVA:-java} 61 | JAVA_OPTIONS="-server" 62 | 63 | ZABBIX_OPTIONS="" 64 | if [ -n "$PID_FILE" ]; then 65 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.pidFile=$PID_FILE" 66 | fi 67 | if [ -n "$LISTEN_IP" ]; then 68 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.listenIP=$LISTEN_IP" 69 | fi 70 | if [ -n "$LISTEN_PORT" ]; then 71 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.listenPort=$LISTEN_PORT" 72 | fi 73 | if [ -n "$START_POLLERS" ]; then 74 | ZABBIX_OPTIONS="$ZABBIX_OPTIONS -Dzabbix.startPollers=$START_POLLERS" 75 | fi 76 | 77 | echo -n "Starting zabbix java gateway: " 78 | is_running 79 | if (( $? == 1 )); then 80 | exit 1 81 | fi 82 | 83 | COMMAND_LINE="$JAVA $JAVA_OPTIONS -classpath $CLASSPATH $ZABBIX_OPTIONS -Dlogback.configurationFile=/etc/zabbix/zabbix_java_gateway.logback.xml com.zabbix.gateway.JavaGateway" 84 | 85 | if [ -n "$PID_FILE" ]; then 86 | PID=$(su -s /bin/bash -c "$COMMAND_LINE > /dev/null 2>&1 & echo \$!" zabbix) 87 | if ps -p $PID > /dev/null 2>&1; then 88 | echo $PID > $PID_FILE 89 | else 90 | echo "zabbix java gateway did not start" 91 | exit 1 92 | fi 93 | else 94 | exec $COMMAND_LINE 95 | RETVAL=$? 96 | fi 97 | ;; 98 | stop) 99 | echo -n "Shutting down zabbix java gateway: " 100 | if [ -n "$PID_FILE" ]; then 101 | if [ -e "$PID_FILE" ]; then 102 | kill `cat $PID_FILE` 103 | rm $PID_FILE 104 | else 105 | echo "zabbix java gateway is not running (or could not find PID file)" 106 | exit 1 107 | fi 108 | else 109 | echo "zabbix java gateway is not configured as a daemon: variable \$PID_FILE is not set" 110 | exit 1 111 | fi 112 | ;; 113 | restart) 114 | $0 stop 115 | $0 start 116 | RETVAL=$? 117 | ;; 118 | condrestart) 119 | if [ -n "$PID_FILE" -a -e "$PID_FILE" ]; then 120 | $0 stop 121 | $0 start 122 | fi 123 | RETVAL=$? 124 | ;; 125 | status) 126 | is_running 127 | if (( $? == 1 )); then 128 | exit 0 129 | fi 130 | echo "zabbix java gateway is not running" 131 | exit 1 132 | ;; 133 | *) 134 | echo "Usage: $0 {start|stop|restart|condrestart|status}" 135 | exit 1 136 | ;; 137 | esac 138 | 139 | [ "$RETVAL" -eq 0 ] && success $"$base startup" || failure $"$base startup" 140 | echo 141 | exit $RETVAL 142 | 143 | -------------------------------------------------------------------------------- /providers/database_my_sql.rb: -------------------------------------------------------------------------------- 1 | def whyrun_supported? 2 | true 3 | end 4 | 5 | def load_current_resource 6 | require 'mysql' 7 | @current_resource = Chef::Resource::ZabbixDatabase.new(@new_resource.dbname) 8 | @current_resource.dbname(@new_resource.dbname) 9 | @current_resource.host(@new_resource.host) 10 | @current_resource.port(@new_resource.port) 11 | @current_resource.root_username(@new_resource.root_username) 12 | @current_resource.root_password(@new_resource.root_password) 13 | 14 | @current_resource.exists = true if database_exists?( 15 | @current_resource.dbname, 16 | @current_resource.host, 17 | @current_resource.port, 18 | @current_resource.root_username, 19 | @current_resource.root_password) 20 | end 21 | 22 | def database_exists?(dbname, host, port, root_username, root_password) 23 | exists = false 24 | db = nil 25 | begin 26 | db = ::Mysql.new(host, root_username, root_password, dbname, port) 27 | exists = true 28 | Chef::Log.info("Connection to database '#{dbname}' on '#{host}' successful") 29 | rescue ::Mysql::Error 30 | Chef::Log.info("Connection to database '#{dbname}' on '#{host}' failed") 31 | ensure 32 | db.close unless db.nil? 33 | end 34 | exists 35 | end 36 | 37 | action :create do 38 | if @current_resource.exists 39 | Chef::Log.info("Create #{new_resource.dbname} already exists - Nothing to do") 40 | else 41 | converge_by("Create #{new_resource.dbname}") do 42 | create_new_database 43 | end 44 | end 45 | end 46 | 47 | def create_new_database 48 | # user_connection = { 49 | # :host => new_resource.host, 50 | # :port => new_resource.port, 51 | # :username => new_resource.username, 52 | # :password => new_resource.password 53 | # } 54 | root_connection = { 55 | :host => new_resource.host, 56 | :port => new_resource.port, 57 | :username => new_resource.root_username, 58 | :password => new_resource.root_password 59 | } 60 | 61 | zabbix_source 'extract_zabbix_database' do 62 | branch new_resource.branch 63 | version new_resource.branch 64 | source_url new_resource.source_url 65 | code_dir new_resource.source_dir 66 | target_dir "zabbix-#{new_resource.server_version}" 67 | install_dir new_resource.install_dir 68 | branch new_resource.branch 69 | version new_resource.version 70 | 71 | action :extract_only 72 | end 73 | 74 | ruby_block 'set_updated' do 75 | action :nothing 76 | block do 77 | new_resource.updated_by_last_action(true) 78 | end 79 | end 80 | 81 | # create zabbix database 82 | mysql_database new_resource.dbname do 83 | connection root_connection 84 | notifies :run, 'execute[zabbix_populate_schema]', :immediately 85 | notifies :run, 'execute[zabbix_populate_image]', :immediately 86 | notifies :run, 'execute[zabbix_populate_data]', :immediately 87 | notifies :create, "mysql_database_user[#{new_resource.username}]", :immediately 88 | notifies :grant, "mysql_database_user[#{new_resource.username}]", :immediately 89 | notifies :create, 'ruby_block[set_updated]', :immediately 90 | end 91 | 92 | # populate database 93 | executable = '/usr/bin/mysql' 94 | root_username = "-u #{new_resource.root_username}" 95 | root_password = "-p#{new_resource.root_password}" 96 | host = "-h #{new_resource.host}" 97 | port = "-P #{new_resource.port}" 98 | dbname = new_resource.dbname 99 | sql_command = "#{executable} #{root_username} #{root_password} #{host} #{port} #{dbname}" 100 | 101 | zabbix_path = ::File.join(new_resource.source_dir, "zabbix-#{new_resource.server_version}") 102 | sql_scripts = if new_resource.server_version.to_f < 2.0 103 | Chef::Log.info 'Version 1.x branch of zabbix in use' 104 | [ 105 | ['zabbix_populate_schema', ::File.join(zabbix_path, 'create', 'schema', 'mysql.sql')], 106 | ['zabbix_populate_data', ::File.join(zabbix_path, 'create', 'data', 'data.sql')], 107 | ['zabbix_populate_image', ::File.join(zabbix_path, 'create', 'data', 'images_mysql.sql')], 108 | ] 109 | else 110 | Chef::Log.info 'Version 2.x branch of zabbix in use' 111 | [ 112 | ['zabbix_populate_schema', ::File.join(zabbix_path, 'database', 'mysql', 'schema.sql')], 113 | ['zabbix_populate_data', ::File.join(zabbix_path, 'database', 'mysql', 'data.sql')], 114 | ['zabbix_populate_image', ::File.join(zabbix_path, 'database', 'mysql', 'images.sql')], 115 | ] 116 | end 117 | 118 | sql_scripts.each do |script_spec| 119 | script_name = script_spec.first 120 | script_path = script_spec.last 121 | 122 | execute script_name do 123 | command "#{sql_command} < #{script_path}" 124 | action :nothing 125 | end 126 | end 127 | 128 | # create and grant zabbix user 129 | mysql_database_user new_resource.username do 130 | connection root_connection 131 | password new_resource.password 132 | database_name new_resource.dbname 133 | host new_resource.allowed_user_hosts 134 | privileges [:select, :update, :insert, :create, :drop, :delete, :alter, :index] 135 | action :nothing 136 | end 137 | end 138 | -------------------------------------------------------------------------------- /providers/database_postgres.rb: -------------------------------------------------------------------------------- 1 | def whyrun_supported? 2 | true 3 | end 4 | 5 | def load_current_resource 6 | require 'pg' 7 | 8 | @current_resource = Chef::Resource::ZabbixDatabase.new(@new_resource.dbname) 9 | @current_resource.dbname(@new_resource.dbname) 10 | @current_resource.host(@new_resource.host) 11 | @current_resource.port(@new_resource.port) 12 | @current_resource.root_username(@new_resource.root_username) 13 | @current_resource.root_password(@new_resource.root_password) 14 | 15 | @current_resource.exists = true if database_exists?( 16 | @current_resource.dbname, 17 | @current_resource.host, 18 | @current_resource.port, 19 | @current_resource.root_username, 20 | @current_resource.root_password) 21 | end 22 | 23 | def database_exists?(dbname, host, port, root_username, root_password) 24 | exists = false 25 | db = nil 26 | begin 27 | db = ::PG.connect(:host => host, 28 | :port => port, 29 | :dbname => dbname, 30 | :user => root_username, 31 | :password => root_password) 32 | exists = true 33 | Chef::Log.info("Connection to database '#{dbname}' on '#{host}' successful") 34 | rescue ::PG::Error 35 | Chef::Log.info("Connection to database '#{dbname}' on '#{host}' failed") 36 | ensure 37 | db.close unless db.nil? 38 | end 39 | exists 40 | end 41 | 42 | action :create do 43 | if @current_resource.exists 44 | Chef::Log.info("Create #{new_resource.dbname} already exists - Nothing to do") 45 | else 46 | converge_by("Create #{new_resource.dbname}") do 47 | create_new_database 48 | end 49 | end 50 | end 51 | 52 | def create_new_database 53 | # user_connection = { 54 | # :host => new_resource.host, 55 | # :port => new_resource.port, 56 | # :username => new_resource.username, 57 | # :password => new_resource.password 58 | # } 59 | root_connection = { 60 | :host => new_resource.host, 61 | :port => new_resource.port, 62 | :username => new_resource.root_username, 63 | :password => new_resource.root_password 64 | } 65 | 66 | zabbix_source 'extract_zabbix_database' do 67 | branch new_resource.branch 68 | version new_resource.branch 69 | source_url new_resource.source_url 70 | code_dir new_resource.source_dir 71 | target_dir "zabbix-#{new_resource.server_version}" 72 | install_dir new_resource.install_dir 73 | branch new_resource.branch 74 | version new_resource.version 75 | 76 | action :extract_only 77 | end 78 | 79 | ruby_block 'set_updated' do 80 | action :nothing 81 | block do 82 | new_resource.updated_by_last_action(true) 83 | end 84 | end 85 | 86 | # create and grant zabbix user 87 | postgresql_database_user new_resource.username do 88 | connection root_connection 89 | password new_resource.password 90 | database_name new_resource.dbname 91 | privileges [:all] 92 | action :nothing 93 | end 94 | 95 | # create zabbix database 96 | postgresql_database new_resource.dbname do 97 | connection root_connection 98 | notifies :create, "postgresql_database_user[#{new_resource.username}]", :immediately 99 | notifies :grant, "postgresql_database_user[#{new_resource.username}]", :immediately 100 | notifies :run, 'execute[zabbix_populate_schema]', :immediately 101 | notifies :run, 'execute[zabbix_populate_image]', :immediately 102 | notifies :run, 'execute[zabbix_populate_data]', :immediately 103 | notifies :create, 'ruby_block[set_updated]', :immediately 104 | end 105 | 106 | # populate database 107 | set_password = "export PGPASSWORD=#{new_resource.password}" 108 | sql_command = '/usr/bin/psql' 109 | sql_command << " -U #{new_resource.username}" 110 | sql_command << " -h #{new_resource.host}" 111 | sql_command << " -p #{new_resource.port}" 112 | sql_command << " #{new_resource.dbname}" 113 | 114 | zabbix_path = ::File.join(new_resource.source_dir, "zabbix-#{new_resource.server_version}") 115 | sql_scripts = if new_resource.server_version.to_f < 2.0 116 | Chef::Log.info 'Version 1.x branch of zabbix in use' 117 | [ 118 | ['zabbix_populate_schema', ::File.join(zabbix_path, 'create', 'schema', 'postgresql.sql')], 119 | ['zabbix_populate_data', ::File.join(zabbix_path, 'create', 'data', 'data.sql')], 120 | ['zabbix_populate_image', ::File.join(zabbix_path, 'create', 'data', 'images_pgsql.sql')], 121 | ] 122 | else 123 | Chef::Log.info 'Version 2.x branch of zabbix in use' 124 | [ 125 | ['zabbix_populate_schema', ::File.join(zabbix_path, 'database', 'postgresql', 'schema.sql')], 126 | ['zabbix_populate_data', ::File.join(zabbix_path, 'database', 'postgresql', 'data.sql')], 127 | ['zabbix_populate_image', ::File.join(zabbix_path, 'database', 'postgresql', 'images.sql')], 128 | ] 129 | end 130 | 131 | sql_scripts.each do |script_spec| 132 | script_name = script_spec.first 133 | script_path = script_spec.last 134 | 135 | execute script_name do 136 | command "(#{set_password} && #{sql_command} < #{script_path} >> /opt/postgres.out)" 137 | action :nothing 138 | end 139 | end 140 | end 141 | -------------------------------------------------------------------------------- /libraries/chef_zabbix_enumerations.rb: -------------------------------------------------------------------------------- 1 | class Chef 2 | module Zabbix 3 | module API 4 | module Enumeration 5 | class << self 6 | def included(base) 7 | base.extend(ClassMethods) 8 | base.send(:include, ClassMethods) 9 | end 10 | 11 | def extended(base) 12 | base.send(:include, ClassMethods) 13 | end 14 | end 15 | 16 | module ClassMethods 17 | attr_reader :enumeration_values 18 | def enum(name, val) 19 | @enumeration_values ||= {} 20 | @enumeration_values[name] ||= new(val) 21 | # The better solution would be to just call define_singleton_method 22 | # but that doesn't work in 1.8.x and we want 1.8.x compatibility 23 | eigen_class = class << self; self; end 24 | eigen_class.send(:define_method, name) do 25 | @enumeration_values[name] 26 | end 27 | end 28 | end 29 | 30 | attr_reader :value 31 | def initialize(value) 32 | @value = value 33 | end 34 | end 35 | 36 | class AuthType 37 | include Enumeration 38 | enum :password, 0 39 | enum :private_key, 1 40 | end 41 | 42 | class DataType 43 | include Enumeration 44 | enum :decimal, 0 45 | enum :octal, 1 46 | enum :hexidecimal, 2 47 | enum :boolean, 3 48 | end 49 | 50 | class Delta 51 | include Enumeration 52 | enum :as_is, 0 53 | enum :speed_per_second, 1 54 | enum :simple_change, 2 55 | end 56 | 57 | class SNMPV3SecurityLevel 58 | include Enumeration 59 | enum :no_auth_no_priv, 0 60 | enum :auth_no_priv, 1 61 | enum :auth_priv, 2 62 | end 63 | 64 | class ItemType 65 | include Enumeration 66 | enum :zabbix_agent, 0 67 | enum :snmp_v1_agent, 1 68 | enum :zabbix_trapper, 2 69 | enum :simple_check, 3 70 | enum :snmp_v2_agent, 4 71 | enum :zabbix_internal, 5 72 | enum :snmp_v3_agent, 6 73 | enum :zabbix_agent_active_check, 7 74 | enum :zabbix_aggregate, 8 75 | enum :web_item, 9 76 | enum :externali_check, 10 77 | enum :database_monitor, 11 78 | enum :ipmi_agent, 12 79 | enum :ssh_agent, 13 80 | enum :telnet_agent, 14 81 | enum :calculated, 15 82 | enum :jmx_agent, 16 83 | enum :snmp_trap, 17 84 | end 85 | 86 | class ItemValueType 87 | include Enumeration 88 | enum :float, 0 89 | enum :character, 1 90 | enum :log, 2 91 | enum :unsigned, 3 92 | enum :text, 4 93 | end 94 | 95 | class TriggerPriority 96 | include Enumeration 97 | 98 | enum :not_classified, 0 99 | enum :information, 1 100 | enum :warning, 2 101 | enum :average, 3 102 | enum :high, 4 103 | enum :disaster, 5 104 | end 105 | 106 | class ItemStatus 107 | include Enumeration 108 | enum :enabled, 0 109 | enum :disabled, 1 110 | enum :not_supported, 2 111 | end 112 | 113 | class TriggerStatus 114 | include Enumeration 115 | enum :active, 0 116 | enum :disabled, 1 117 | end 118 | 119 | class TriggerType 120 | include Enumeration 121 | enum :normal, 0 122 | enum :multiple, 1 123 | end 124 | 125 | class GraphItemCalcFunction 126 | include Enumeration 127 | enum :min, 1 128 | enum :max, 2 129 | enum :average, 4 130 | enum :all, 7 131 | end 132 | 133 | class GraphItemType 134 | include Enumeration 135 | enum :simple, 0 136 | enum :aggregated, 1 137 | enum :graph, 2 138 | end 139 | 140 | class GraphType 141 | include Enumeration 142 | enum :normal, 0 143 | enum :stacked, 1 144 | enum :pie, 2 145 | enum :exploded, 3 146 | end 147 | 148 | class GraphAxisType 149 | include Enumeration 150 | enum :calculated, 0 151 | enum :fixed, 1 152 | # TODO: Update the graph provider to do an update after it has created 153 | # all of its item so that you can map an item id and support this value 154 | # enum :item, 2 155 | end 156 | 157 | class IPMIAuthType 158 | include Enumeration 159 | enum :default, -1 160 | enum :none, 0 161 | enum :md2, 1 162 | enum :md5, 2 163 | enum :straight, 3 164 | enum :oem, 4 165 | enum :rmcp_plus, 5 166 | end 167 | 168 | class IPMIPrivilege 169 | include Enumeration 170 | enum :callback, 1 171 | enum :user, 2 172 | enum :operator, 3 173 | enum :admin, 4 174 | enum :oem, 5 175 | end 176 | 177 | class HostInterfaceType 178 | include Enumeration 179 | enum :agent, 1 180 | enum :snmp, 2 181 | enum :ipmi, 3 182 | enum :jmx, 4 183 | end 184 | end 185 | end 186 | end 187 | -------------------------------------------------------------------------------- /recipes/server_source.rb: -------------------------------------------------------------------------------- 1 | # Author:: Nacer Laradji () 2 | # Cookbook Name:: zabbix 3 | # Recipe:: server_source 4 | # 5 | # Copyright 2011, Efactures 6 | # 7 | # Apache 2.0 8 | # 9 | 10 | include_recipe 'zabbix::common' 11 | include_recipe 'zabbix::server_common' 12 | 13 | packages = [] 14 | case node['platform'] 15 | when 'ubuntu', 'debian' 16 | packages = %w(fping libcurl4-openssl-dev libiksemel-utils libiksemel-dev libiksemel3 libsnmp-dev snmp php-pear) 17 | case node['zabbix']['database']['install_method'] 18 | when 'mysql', 'rds_mysql' 19 | packages.push('libmysql++-dev', 'libmysql++3', 'libcurl3', 'php5-mysql', 'php5-gd') 20 | when 'postgres' 21 | packages.push('libssh2-1-dev') 22 | # Oracle oci8 PECL package installed below 23 | when 'oracle' 24 | php_packages = %w(php-pear php-dev) 25 | packages.push(*php_packages) 26 | end 27 | init_template = 'zabbix_server.init.erb' 28 | when 'redhat', 'centos', 'scientific', 'amazon', 'oracle' 29 | include_recipe 'yum-epel' 30 | 31 | curldev = (node['platform_version'].to_i < 6) ? 'curl-devel' : 'libcurl-devel' 32 | 33 | packages = %w(fping iksemel-devel iksemel-utils net-snmp-libs net-snmp-devel openssl-devel redhat-lsb php-pear) 34 | packages.push(curldev) 35 | 36 | case node['zabbix']['database']['install_method'] 37 | when 'mysql', 'rds_mysql' 38 | php_packages = 39 | if node['platform_version'].to_i < 6 40 | %w(php53-mysql php53-gd php53-bcmath php53-mbstring php53-xml) 41 | else 42 | %w(php-mysql php-gd php-bcmath php-mbstring php-xml) 43 | end 44 | packages.push(*php_packages) 45 | when 'postgres' 46 | php_packages = 47 | if node['platform_version'].to_i < 6 48 | %w(php5-pgsql php5-gd php5-xml) 49 | else 50 | %w(php-pgsql php-gd php-bcmath php-mbstring php-xml) 51 | end 52 | packages.push(*php_packages) 53 | # Oracle oci8 PECL package installed below 54 | when 'oracle' 55 | php_packages = %w(php-pear php-devel) 56 | packages.push(*php_packages) 57 | end 58 | init_template = 'zabbix_server.init-rh.erb' 59 | end 60 | 61 | packages.each do |pck| 62 | package pck do 63 | action :install 64 | end 65 | end 66 | 67 | # Install the oci8 pecl - common to both Debian and RHEL families 68 | php_pear 'oci8' do 69 | preferred_state 'stable' 70 | action :install 71 | only_if { node['zabbix']['database']['install_method'] == 'oracle' } 72 | end 73 | 74 | configure_options = node['zabbix']['server']['configure_options'].dup 75 | configure_options = (configure_options || Array.new).delete_if do |option| 76 | option.match(/\s*--prefix(\s|=).+/) 77 | end 78 | case node['zabbix']['database']['install_method'] 79 | when 'mysql', 'rds_mysql' 80 | with_mysql = '--with-mysql' 81 | configure_options << with_mysql unless configure_options.include?(with_mysql) 82 | when 'postgres' 83 | with_postgresql = '--with-postgresql' 84 | configure_options << with_postgresql unless configure_options.include?(with_postgresql) 85 | when 'oracle' 86 | client_arch = node['kernel']['machine'] == 'x86_64' ? 'client64' : 'client' 87 | oracle_lib_path = "/usr/lib/oracle/#{node['oracle-instantclient']['version']}/#{client_arch}/lib" 88 | oracle_include_path = "/usr/include/oracle/#{node['oracle-instantclient']['version']}/#{client_arch}" 89 | with_oracle_lib = "--with-oracle-lib=#{oracle_lib_path}" 90 | with_oracle_include = "--with-oracle-include=#{oracle_include_path}" 91 | configure_options << '--with-oracle' unless configure_options.include?('--with-oracle') 92 | configure_options << with_oracle_lib unless configure_options.include?(with_oracle_lib) 93 | configure_options << with_oracle_include unless configure_options.include?(with_oracle_include) 94 | end 95 | 96 | if node['zabbix']['server']['java_gateway_enable'] == true 97 | include_recipe 'java' # install a JDK if not present 98 | configure_options << '--enable-java' unless configure_options.include?('--enable-java') 99 | end 100 | 101 | node.normal['zabbix']['server']['configure_options'] = configure_options 102 | 103 | zabbix_source 'install_zabbix_server' do 104 | branch node['zabbix']['server']['branch'] 105 | version node['zabbix']['server']['version'] 106 | source_url node['zabbix']['server']['source_url'] 107 | branch node['zabbix']['server']['branch'] 108 | version node['zabbix']['server']['version'] 109 | code_dir node['zabbix']['src_dir'] 110 | target_dir "zabbix-#{node['zabbix']['server']['version']}" 111 | install_dir node['zabbix']['install_dir'] 112 | configure_options configure_options.join(' ') 113 | 114 | action :install_server 115 | end 116 | 117 | # Install Init script 118 | template '/etc/init.d/zabbix_server' do 119 | source init_template 120 | owner 'root' 121 | group 'root' 122 | mode '755' 123 | notifies :restart, 'service[zabbix_server]', :delayed 124 | end 125 | 126 | # install zabbix server conf 127 | template "#{node['zabbix']['etc_dir']}/zabbix_server.conf" do 128 | source 'zabbix_server.conf.erb' 129 | owner 'root' 130 | group 'root' 131 | mode '644' 132 | variables( 133 | :dbhost => node['zabbix']['database']['dbhost'], 134 | :dbname => node['zabbix']['database']['dbname'], 135 | :dbuser => node['zabbix']['database']['dbuser'], 136 | :dbpassword => node['zabbix']['database']['dbpassword'], 137 | :dbport => node['zabbix']['database']['dbport'], 138 | :java_gateway => node['zabbix']['server']['java_gateway'], 139 | :java_gateway_port => node['zabbix']['server']['java_gateway_port'], 140 | :java_pollers => node['zabbix']['server']['java_pollers'] 141 | ) 142 | notifies :restart, 'service[zabbix_server]', :delayed 143 | end 144 | 145 | # Define zabbix_agentd service 146 | service 'zabbix_server' do 147 | supports :status => true, :start => true, :stop => true, :restart => true 148 | action [:start, :enable] 149 | end 150 | 151 | # Configure the Java Gateway 152 | if node['zabbix']['server']['java_gateway_enable'] == true 153 | include_recipe 'zabbix::java_gateway' 154 | end 155 | -------------------------------------------------------------------------------- /providers/user.rb: -------------------------------------------------------------------------------- 1 | action :create_or_update do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | get_user_request = { 4 | :method => 'user.get', 5 | :params => { 6 | :filter => { 7 | :alias => new_resource.alias 8 | } 9 | } 10 | } 11 | users = connection.query(get_user_request) 12 | 13 | if users.size == 0 14 | Chef::Log.info "Proceeding to create this user on the Zabbix server: '#{new_resource.alias}'" 15 | run_action :create 16 | new_resource.updated_by_last_action(true) 17 | else 18 | Chef::Log.debug "Going to update this user: '#{new_resource.alias}'" 19 | run_action :update 20 | end 21 | end 22 | end 23 | 24 | action :create do 25 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 26 | 27 | Chef::Application.fatal! "Please supply a password for creating this user: '#{new_resource.alias}'" if new_resource.password.nil? || new_resource.password.empty? 28 | 29 | groups = check_and_create_groups(new_resource, connection) 30 | 31 | request = { 32 | :method => 'user.create', 33 | :params => { 34 | :alias => new_resource.alias, 35 | :passwd => new_resource.password, 36 | :surname => new_resource.surname, 37 | :name => new_resource.first_name, 38 | :type => new_resource.type, 39 | :usrgrps => groups, 40 | :user_medias => new_resource.medias 41 | } 42 | } 43 | Chef::Log.info "Creating new user: '#{new_resource.alias}'" 44 | connection.query(request) 45 | end 46 | new_resource.updated_by_last_action(true) 47 | end 48 | 49 | action :update do 50 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 51 | 52 | get_user_request = { 53 | :method => 'user.get', 54 | :params => { 55 | :filter => { 56 | :alias => new_resource.alias 57 | }, 58 | :output => :extend, 59 | :selectUsrgrps => :shorten, 60 | :selectMedias => :extend 61 | } 62 | } 63 | user = connection.query(get_user_request).first 64 | if user.nil? || user.empty? 65 | Chef::Application.fatal! "Could not find user for update: '#{new_resource.alias}'" 66 | end 67 | 68 | groups = check_and_create_groups(new_resource, connection, true) 69 | 70 | need_to_update = false 71 | 72 | groups.each do |group| 73 | need_to_update = true if user['usrgrps'].select { |usergrp| usergrp['usrgrpid'] == group['usrgrpid'] }.empty? 74 | end 75 | { 'alias' => 'alias', 'first_name' => 'name', 'surname' => 'surname', 'type' => 'type', 'medias' => 'medias' }.each do |resource_attr_name, api_attr_name| 76 | if resource_attr_name != 'type' 77 | need_to_update = true if user[api_attr_name] != new_resource.send(resource_attr_name) 78 | else 79 | need_to_update = true if user[api_attr_name] != new_resource.send(resource_attr_name).to_s 80 | end 81 | end 82 | 83 | need_to_update = true if new_resource.force_update 84 | 85 | if need_to_update 86 | user_update_request = { 87 | :method => 'user.update', 88 | :params => { 89 | :userid => user['userid'], 90 | :alias => new_resource.alias, 91 | :passwd => new_resource.password, 92 | :surname => new_resource.surname, 93 | :name => new_resource.first_name, 94 | :type => new_resource.type, 95 | :usrgrps => groups, 96 | :user_medias => new_resource.medias 97 | } 98 | } 99 | Chef::Log.info "Updating user '#{new_resource.alias}'" 100 | connection.query(user_update_request) 101 | new_resource.updated_by_last_action(true) 102 | else 103 | Chef::Log.info "The attributes of user '#{new_resource.alias}' are already up-to-date, doing nothing" 104 | end 105 | 106 | end 107 | end 108 | 109 | action :delete do 110 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 111 | 112 | get_user_request = { 113 | :method => 'user.get', 114 | :params => { 115 | :filter => { 116 | :alias => new_resource.alias 117 | }, 118 | } 119 | } 120 | user = connection.query(get_user_request).first 121 | if user.nil? || user.empty? 122 | Chef::Application.fatal! "Could not find user for delete: '#{new_resource.alias}'" 123 | end 124 | 125 | user_delete_request = { 126 | :method => 'user.delete', 127 | :params => [ 128 | user['userid'] 129 | ] 130 | } 131 | Chef::Log.info "Deleting user '#{new_resource.alias}'" 132 | result = connection.query(user_delete_request) 133 | Application.fatal! "Error deleting user '#{new_resource.alias}', see Chef errors" if result.nil? || result.empty? || result['userids'].nil? || result['userids'].empty? || !result['userids'].include?(user['userid']) 134 | new_resource.updated_by_last_action(true) 135 | end 136 | end 137 | 138 | def load_current_resource 139 | run_context.include_recipe 'zabbix::_providers_common' 140 | require 'zabbixapi' 141 | end 142 | 143 | def check_and_create_groups(new_resource, connection, extended_results = false) 144 | groups = [] 145 | new_resource.groups.each do |current_user_group| 146 | Chef::Log.info "Checking for existence of group '#{current_user_group}'" 147 | get_user_group_request = { 148 | :method => 'usergroup.get', 149 | :params => { 150 | :filter => { 151 | :name => current_user_group 152 | } 153 | } 154 | } 155 | get_user_group_request[:params][:output] = :extend if extended_results 156 | group = connection.query(get_user_group_request) 157 | groups << evaluate_group_creation(group, current_user_group, connection, new_resource.create_missing_groups) 158 | end 159 | groups 160 | end 161 | 162 | def evaluate_group_creation(current_user_group_from_get, current_user_group_from_resource, connection, create_missing_groups) 163 | if current_user_group_from_get.length == 0 && create_missing_groups 164 | Chef::Log.info "Creating user group '#{current_user_group_from_resource}'" 165 | make_user_group_request = { 166 | :method => 'usergroup.create', 167 | :params => { 168 | :name => current_user_group_from_resource 169 | } 170 | } 171 | result = connection.query(make_user_group_request) 172 | Chef::Log.error("Error creating group '#{current_user_group_from_resource}', see Chef errors") if result.nil? || result.empty? 173 | # And now fetch the newly made user group to be sure it worked 174 | # and for later use 175 | connection.query(get_user_group_request).first 176 | elsif current_user_group_from_get.length == 1 177 | Chef::Log.info "Group '#{current_user_group_from_resource}' already exists" 178 | current_user_group_from_get.first 179 | else 180 | Chef::Application.fatal! "Could not find user group '#{current_user_group_from_resource}' for user '#{new_resource.alias}' and \"create_missing_groups\" is False (or unset)" 181 | end 182 | end 183 | -------------------------------------------------------------------------------- /libraries/chef_zabbix_api.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | class Chef 4 | module Zabbix 5 | module API 6 | class GraphItem 7 | extend Forwardable 8 | def_delegators :@options, :[], :[]=, :delete 9 | def initialize(options) 10 | if options[:item_template].to_s.empty? && options[:host].to_s.empty? 11 | Chef::Application.fatal! ':item_template or :host is required' 12 | end 13 | Chef::Application.fatal! ':item_key is required' if options[:item_key].to_s.empty? 14 | Chef::Application.fatal! ':calc_function must be a Zabbix::API::GraphItemCalcFunction' unless options[:calc_function].is_a?(GraphItemCalcFunction) 15 | Chef::Application.fatal! ':type must be a Zabbix::API::GraphItemType' unless options[:type].is_a?(GraphItemType) 16 | @options = options 17 | end 18 | 19 | def to_hash 20 | unless @options[:itemid] 21 | Chef::Application.fatal! ":itemid was never set. This probably means that an item with key '#{@options[:item_key]}' couldn't be found on template '#{@options[:item_template]}'" 22 | end 23 | { 24 | :itemid => @options[:itemid], 25 | :color => @options[:color], 26 | :calc_fnc => @options[:calc_function].value, 27 | :type => @options[:type].value, 28 | :periods_cnt => @options[:period_count] 29 | } 30 | end 31 | end 32 | 33 | class HostInterface 34 | class << self 35 | def from_api_response(options) 36 | options['type'] = Zabbix::API::HostInterfaceType.enumeration_values.find { |value| value[1].value == options['type'].to_i }[1] 37 | options['main'] = (options['main'].to_i == 1) 38 | options['useip'] = (options['useip'].to_i == 1) 39 | new(options) 40 | end 41 | end 42 | 43 | attr_reader :options 44 | 45 | extend Forwardable 46 | def_delegators :@options, :[], :[]=, :delete 47 | def initialize(options) 48 | options = symbolize(options) 49 | if options[:type].is_a?(Fixnum) 50 | end 51 | validate!(options) 52 | @options = options 53 | end 54 | 55 | def to_hash 56 | { 57 | :dns => @options[:dns].to_s, 58 | :ip => @options[:ip].to_s, 59 | :useip => (@options[:useip]) ? 1 : 0, 60 | :main => (@options[:main]) ? 1 : 0, 61 | :port => @options[:port].to_s, 62 | :type => @options[:type].value 63 | } 64 | end 65 | 66 | def ==(other) 67 | this = to_hash 68 | this[:main] == other[:main].to_i && 69 | this[:useip] == other[:useip].to_i && 70 | this[:ip] == other[:ip].to_s && 71 | this[:dns] == other[:dns].to_s && 72 | this[:port] == other[:port].to_s && 73 | this[:type] == other[:type].to_i 74 | end 75 | 76 | private 77 | 78 | def validate!(options) 79 | options = symbolize(options) 80 | search = options[:useip] ? :ip : :dns 81 | Chef::Application.fatal!("#{search} must be set when :useip is #{options[:useip]}") unless options[search] 82 | Chef::Application.fatal!(':port is required') unless options[:port] 83 | Chef::Application.fatal!(':type must be a Chef::Zabbix::API:HostInterfaceType') unless options[:type].is_a?(Chef::Zabbix::API::HostInterfaceType) 84 | end 85 | 86 | def symbolize(options) 87 | symbolized = {} 88 | options.each_key do |key| 89 | symbolized[key.to_sym] = options[key] 90 | end 91 | symbolized 92 | end 93 | end 94 | 95 | class << self 96 | def find_hostgroup_ids(connection, hostgroup) 97 | group_id_request = { 98 | :method => 'hostgroup.get', 99 | :params => { 100 | :filter => { 101 | :name => hostgroup 102 | } 103 | } 104 | } 105 | connection.query(group_id_request) 106 | end 107 | 108 | def find_template_ids(connection, template) 109 | get_template_request = { 110 | :method => 'template.get', 111 | :params => { 112 | :filter => { 113 | :host => template, 114 | } 115 | } 116 | } 117 | connection.query(get_template_request) 118 | end 119 | 120 | def find_application_ids(connection, application, template_id) 121 | request = { 122 | :method => 'application.get', 123 | :params => { 124 | :hostids => template_id, 125 | :filter => { 126 | :name => application 127 | } 128 | } 129 | } 130 | connection.query(request) 131 | end 132 | 133 | def find_lld_rule_ids(connection, template_id, key) 134 | request = { 135 | :method => 'discoveryrule.get', 136 | :params => { 137 | :templated => true, 138 | :templateids => template_id, 139 | :search => { 140 | :key_ => key 141 | } 142 | } 143 | } 144 | connection.query(request) 145 | end 146 | 147 | def find_trigger_ids(connection, description) 148 | request = { 149 | :method => 'trigger.get', 150 | :params => { 151 | :search => { 152 | :description => description 153 | } 154 | } 155 | } 156 | connection.query(request) 157 | end 158 | 159 | def find_trigger_prototype_ids(connection, description) 160 | request = { 161 | :method => 'triggerprototype.get', 162 | :params => { 163 | :search => { 164 | :description => description 165 | } 166 | } 167 | } 168 | connection.query(request) 169 | end 170 | 171 | def find_item_ids(connection, template_id, key, name = nil) 172 | request = { 173 | :method => 'item.get', 174 | :params => { 175 | :hostids => template_id, 176 | :search => { 177 | :key_ => key 178 | } 179 | } 180 | } 181 | unless name.to_s.empty? 182 | request[:filter] = { 183 | :name => name 184 | } 185 | end 186 | 187 | connection.query(request) 188 | end 189 | 190 | def find_item_prototype_ids(connection, template_id, key, discovery_rule_id = nil) 191 | request = { 192 | :method => 'itemprototype.get', 193 | :params => { 194 | :templateids => template_id, 195 | :search => { 196 | :key_ => key 197 | } 198 | } 199 | } 200 | if discovery_rule_id 201 | request[:params][:discoveryids] = discovery_rule_id 202 | end 203 | connection.query(request) 204 | end 205 | 206 | def find_item_ids_on_host(connection, host, key) 207 | request = { 208 | :method => 'item.get', 209 | :params => { 210 | :host => host, 211 | :search => { 212 | :key_ => key 213 | } 214 | } 215 | } 216 | connection.query(request) 217 | end 218 | 219 | def find_graph_ids(connection, name) 220 | request = { 221 | :method => 'graph.get', 222 | :params => { 223 | :filter => { 224 | :name => name 225 | } 226 | } 227 | } 228 | connection.query(request) 229 | end 230 | 231 | def find_graph_prototype_ids(connection, name) 232 | request = { 233 | :method => 'graphprototype.get', 234 | :params => { 235 | :filter => { 236 | :name => name 237 | } 238 | } 239 | } 240 | connection.query(request) 241 | end 242 | end 243 | end 244 | end 245 | end 246 | -------------------------------------------------------------------------------- /providers/host.rb: -------------------------------------------------------------------------------- 1 | action :create_or_update do 2 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 3 | get_host_request = { 4 | :method => 'host.get', 5 | :params => { 6 | :filter => { 7 | :host => new_resource.hostname 8 | } 9 | } 10 | } 11 | hosts = connection.query(get_host_request) 12 | 13 | if hosts.size == 0 14 | Chef::Log.info 'Proceeding to register this node to the Zabbix server' 15 | run_action :create 16 | else 17 | Chef::Log.debug 'Going to update this host' 18 | run_action :update 19 | end 20 | end 21 | new_resource.updated_by_last_action(true) 22 | end 23 | 24 | action :create do 25 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 26 | 27 | all_are_host_interfaces = new_resource.interfaces.all? { |interface| interface.is_a?(Chef::Zabbix::API::HostInterface) } 28 | unless all_are_host_interfaces 29 | Chef::Application.fatal!(':interfaces must only contain Chef::Zabbix::API::HostInterface') 30 | end 31 | 32 | Chef::Log.error('Please supply a group for this host!') if new_resource.groups.empty? && new_resource.parameters[:groupNames].empty? 33 | 34 | if new_resource.groups.empty? 35 | group_names = new_resource.parameters[:groupNames] 36 | else 37 | group_names = new_resource.groups 38 | end 39 | 40 | groups = [] 41 | group_names.each do |current_group| 42 | Chef::Log.info "Checking for existence of group #{current_group}" 43 | get_groups_request = { 44 | :method => 'hostgroup.get', 45 | :params => { 46 | :filter => { 47 | :name => current_group 48 | } 49 | } 50 | } 51 | groups = connection.query(get_groups_request) 52 | if groups.length == 0 && new_resource.create_missing_groups 53 | Chef::Log.info "Creating group #{current_group}" 54 | make_groups_request = { 55 | :method => 'hostgroup.create', 56 | :params => { 57 | :name => current_group 58 | } 59 | } 60 | result = connection.query(make_groups_request) 61 | # And now fetch the newly made group to be sure it worked 62 | # and for later use 63 | groups = connection.query(get_groups_request) 64 | Chef::Log.error('Error creating groups, see Chef errors') if result.nil? 65 | elsif groups.length == 1 66 | Chef::Log.info "Group #{current_group} already exists" 67 | else 68 | Chef::Application.fatal! "Could not find group, #{current_group}, for this host and \"create_missing_groups\" is False (or unset)" 69 | end 70 | end 71 | 72 | if new_resource.templates.empty? && new_resource.parameters[:templates].empty? 73 | Chef::Log.warn 'Empty Zabbix template list for this host - not searching to see if templates exist' 74 | templates = {} 75 | else 76 | if new_resource.templates.empty? 77 | template_names = new_resource.parameters[:templates] 78 | else 79 | template_names = new_resource.templates 80 | end 81 | get_templates_request = { 82 | :method => 'template.get', 83 | :params => { 84 | :output => 'extend', 85 | :filter => { 86 | :name => template_names 87 | } 88 | } 89 | } 90 | 91 | templates = Hash[connection.query(get_templates_request).map { |template| [template['templateid'], template['name']] }] 92 | if templates.length != template_names.length 93 | missing_elements = template_names - templates.values 94 | Chef::Application.fatal! "Cannot find all templates associated with host, missing : #{missing_elements}" 95 | end 96 | end 97 | 98 | templates_to_send = [] 99 | templates.keys.each do |key| 100 | templates_to_send.concat([{ 'templateid' => key }]) 101 | end 102 | 103 | if new_resource.interfaces.empty? 104 | interfaces = new_resource.parameters[:interfaces] 105 | else 106 | interfaces = new_resource.interfaces 107 | end 108 | 109 | request = { 110 | :method => 'host.create', 111 | :params => { 112 | :host => new_resource.hostname, 113 | :groups => groups, 114 | :templates => templates_to_send, 115 | :interfaces => interfaces.map(&:to_hash), 116 | :macros => format_macros(new_resource.macros) 117 | } 118 | } 119 | Chef::Log.info 'Creating new Zabbix entry for this host' 120 | connection.query(request) 121 | end 122 | new_resource.updated_by_last_action(true) 123 | end 124 | 125 | action :update do 126 | Chef::Zabbix.with_connection(new_resource.server_connection) do |connection| 127 | 128 | get_host_request = { 129 | :method => 'host.get', 130 | :params => { 131 | :filter => { 132 | :host => new_resource.hostname 133 | }, 134 | :selectInterfaces => 'extend', 135 | :selectGroups => 'extend', 136 | :selectParentTemplates => 'extend' 137 | } 138 | } 139 | host = connection.query(get_host_request).first 140 | if host.nil? 141 | Chef::Application.fatal! "Could not find host #{new_resource.hostname}" 142 | end 143 | 144 | if new_resource.groups.empty? 145 | group_names = new_resource.parameters[:groupNames] 146 | else 147 | group_names = new_resource.groups 148 | end 149 | 150 | desired_groups = group_names.reduce([]) do |acc, desired_group| 151 | get_desired_groups_request = { 152 | :method => 'hostgroup.get', 153 | :params => { 154 | :filter => { 155 | :name => desired_group 156 | } 157 | } 158 | } 159 | group = connection.query(get_desired_groups_request).first 160 | if group.nil? 161 | Chef::Application.fatal! "Could not find group '#{desired_group}'" 162 | end 163 | acc << group 164 | end 165 | 166 | if new_resource.templates.empty? 167 | template_names = new_resource.parameters[:templates] 168 | else 169 | template_names = new_resource.templates 170 | end 171 | desired_templates = template_names.reduce([]) do |acc, desired_template| 172 | get_desired_templates_request = { 173 | :method => 'template.get', 174 | :params => { 175 | :filter => { 176 | :host => desired_template 177 | } 178 | } 179 | } 180 | template = connection.query(get_desired_templates_request) 181 | acc << template 182 | end 183 | 184 | if new_resource.interfaces.empty? 185 | interfaces = new_resource.parameters[:interfaces] 186 | else 187 | interfaces = new_resource.interfaces 188 | end 189 | 190 | existing_interfaces = host['interfaces'].map { |interface| Chef::Zabbix::API::HostInterface.from_api_response(interface).to_hash } 191 | new_host_interfaces = determine_new_host_interfaces(existing_interfaces, interfaces.map(&:to_hash)) 192 | 193 | host_update_request = { 194 | :method => 'host.update', 195 | :params => { 196 | :hostid => host['hostid'], 197 | :groups => desired_groups, 198 | :templates => desired_templates.flatten, 199 | } 200 | } 201 | connection.query(host_update_request) 202 | 203 | new_host_interfaces.each do |interface| 204 | create_interface_request = { 205 | :method => 'hostinterface.create', 206 | :params => interface.merge(:hostid => host['hostid']) 207 | 208 | } 209 | connection.query(create_interface_request) 210 | end 211 | 212 | end 213 | new_resource.updated_by_last_action(true) 214 | end 215 | 216 | def load_current_resource 217 | run_context.include_recipe 'zabbix::_providers_common' 218 | require 'zabbixapi' 219 | end 220 | 221 | def determine_new_host_interfaces(existing_interfaces, desired_interfaces) 222 | desired_interfaces.reject do |desired_interface| 223 | existing_interfaces.any? do |existing_interface| 224 | existing_interface['type'] == desired_interface['type'] && 225 | existing_interface['port'] == desired_interface['port'] 226 | end 227 | end 228 | end 229 | 230 | def format_macros(macros) 231 | macros.map do |macro, value| 232 | macro_name = (macro[0] == '{') ? macro : "{$#{macro}}" 233 | { 234 | :macro => macro_name, 235 | :value => value 236 | } 237 | end 238 | end 239 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2012-2013 Nacer Laradji 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/laradji/zabbix.png?branch=master)](https://travis-ci.org/laradji/zabbix) 2 | 3 | # DESCRIPTION 4 | [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/laradji/zabbix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 | 6 | This cookbook install zabbix-agent and zabbix-server. 7 | 8 | By defaut the cookbook installs zabbix-agent, check the attribute for enable/disable zabbix_server / web or disable zabbix_agent installation. 9 | 10 | Default login password for zabbix frontend is admin / zabbix CHANGE IT ! 11 | 12 | # USAGE 13 | 14 | Be careful when you update your server version, you need to run the sql patch in /opt/zabbix-$VERSION. 15 | 16 | If you do not specify source\_url attributes for agent or server they will be set to download the specified 17 | branch and version from the official Zabbix source repository. If you want to upgrade later, you need to 18 | either nil out the source\_url attributes or set them to the url you wish to download from. 19 | 20 | node['zabbix']['agent']['source_url'] = nil 21 | node['zabbix']['server']['source_url'] = nil 22 | 23 | Please include the default recipe before using any other recipe. 24 | 25 | Installing the Agent : 26 | 27 | "recipe[zabbix]" 28 | 29 | Installing the Server : 30 | 31 | "recipe[zabbix]", 32 | "recipe[zabbix::server]" 33 | 34 | Installing the Database : 35 | 36 | "recipe[mysql::server]", 37 | "recipe[zabbix]", 38 | "recipe[zabbix::database]" 39 | 40 | Installing all 3 - Database MUST come before Server 41 | 42 | "recipe[database::mysql]", 43 | "recipe[mysql::server]", 44 | "recipe[zabbix]", 45 | "recipe[zabbix::database]", 46 | "recipe[zabbix::server]" 47 | 48 | NOTE: 49 | 50 | If you are running on Redhat, Centos, Scientific or Amazon, you will need packages from EPEL. 51 | Include "recipe[yum::epel]" in your runlist or satisfy these requirements some other way. 52 | 53 | "recipe[yum::epel]" 54 | 55 | # ATTRIBUTES 56 | 57 | Don't forget to set : 58 | 59 | node.set['zabbix']['agent']['servers'] = ["Your_zabbix_server.com","secondaryserver.com"] 60 | node.set['zabbix']['web']['fqdn'] or you will not have the zabbix web interface 61 | 62 | Note : 63 | 64 | A Zabbix agent running on the Zabbix server will need to : 65 | 66 | * use a different account than the on the server uses or it will be able to spy on private data. 67 | * specify the local Zabbix server using the localhost (127.0.0.1, ::1) address. 68 | 69 | example : 70 | 71 | ## Server 72 | 73 | node.set['zabbix']['server']['branch'] = "ZABBIX%20Latest%20Stable" 74 | node.set['zabbix']['server']['version'] = "2.0.0" 75 | node.set['zabbix']['server']['source_url'] = nil 76 | ndoe.set['zabbix']['server']['install_method'] = "source" 77 | 78 | ## Agent 79 | 80 | node.set['zabbix']['agent']['branch'] = "ZABBIX%20Latest%20Stable" 81 | node.set['zabbix']['agent']['version'] = "2.0.0" 82 | node.set['zabbix']['agent']['source_url'] = nil 83 | node.set['zabbix']['agent']['install_method'] = "prebuild" 84 | 85 | ## Database 86 | 87 | node.set['zabbix']['database']['install_method'] = 'mysql' 88 | node.set['zabbix']['database']['dbname'] = "zabbix" 89 | node.set['zabbix']['database']['dbuser'] = "zabbix" 90 | node.set['zabbix']['database']['dbhost'] = "localhost" 91 | node.set['zabbix']['database']['dbpassword'] = 'password' 92 | node.set['zabbix']['database']['dbport'] = "3306" 93 | 94 | If you are using AWS RDS 95 | 96 | node.set['zabbix']['database']['install_method'] = 'rds_mysql' 97 | node.set['zabbix']['database']['rds_master_user'] = 'username' 98 | node.set['zabbix']['database']['rds_master_password'] = 'password' 99 | 100 | 101 | 102 | # RECIPES 103 | 104 | ## default 105 | 106 | The default recipe creates the Zabbix user and directories used by all Zabbix components. 107 | 108 | Optionally, it installs the Zabbix agent. 109 | 110 | You can control the agent install with the following attributes: 111 | 112 | node['zabbix']['agent']['install'] = true 113 | node['zabbix']['agent']['install_method'] = 'source' 114 | 115 | ## agent\_prebuild 116 | 117 | Downloads and installs the Zabbix agent from a pre built package 118 | 119 | If you are on a machine in the RHEL family of platforms, then you must have your 120 | package manager setup to allow installation of: 121 | 122 | package "redhat-lsb" 123 | 124 | You can control the agent version with: 125 | 126 | node['zabbix']['agent']['version'] 127 | 128 | ## agent\_source 129 | 130 | Downloads and installs the Zabbix agent from source 131 | 132 | If you are on a machine in the RHEL family of platforms, then you will 133 | need to install packages from the EPEL repository. The easiest way to do this 134 | is to add the following recipe to your runlist before zabbix::agent\_source 135 | 136 | recipe "yum::epel" 137 | 138 | You can control the agent install with: 139 | 140 | node['zabbix']['agent']['branch'] 141 | node['zabbix']['agent']['version'] 142 | node['zabbix']['agent']['configure_options'] 143 | 144 | ## database 145 | 146 | WARNING: This recipe persists your database credentials back to the Chef server 147 | as plaintext node attributes. To prevent this, consume the `zabbix_database` 148 | LWRP in your own wrapper cookbook. 149 | 150 | Creates and initializes the Zabbix database 151 | 152 | Currenly only supports MySql and RDS MySql databases 153 | 154 | If they are not already set, this recipe will generate the following attributes: 155 | 156 | node['zabbix']['database']['dbpassword'] 157 | node['mysql']['server_root_password'] # Not generated if you are using RDS 158 | 159 | You can control the database version with: 160 | 161 | node['zabbix']['server']['branch'] 162 | node['zabbix']['server']['version'] 163 | 164 | The database setup uses the following attributes: 165 | 166 | node['zabbix']['database']['dbhost'] 167 | node['zabbix']['database']['dbname'] 168 | node['zabbix']['database']['dbuser'] 169 | node['zabbix']['database']['dbpassword'] 170 | 171 | node['zabbix']['database']['install_method'] 172 | 173 | If `install_method` is 'mysql' you also need: 174 | 175 | node['mysql']['server_root_password'] 176 | 177 | If `install_method` is 'rds\_mysql' you also need: 178 | 179 | node['zabbix']['database']['rds_master_username'] 180 | node['zabbix']['database']['rds_master_password'] 181 | 182 | ## firewall 183 | 184 | Opens firewall rules to allow Zabbix nodes to communicate with each other. 185 | 186 | ## server 187 | 188 | Delegates to other recipes to install the Zabbix server and Web components. 189 | 190 | You can control the server and web installs with the following attributes: 191 | 192 | node['zabbix']['server']['install'] = true 193 | node['zabbix']['server']['install_method'] = 'source' 194 | node['zabbix']['web']['install'] = true 195 | 196 | If you are using a MySql or RDS MySql database make sure your runlist 197 | includes: 198 | 199 | "recipe[database::mysql]", 200 | "recipe[mysql::client]" 201 | 202 | If you are user a Postgres database make sure your runlist includes: 203 | 204 | "recipe[database::postgresql]", 205 | "recipe[postgresql::client]", 206 | 207 | ## server\_source 208 | 209 | Downloads and installs the Zabbix Server component from source 210 | 211 | If you are on a machine in the RHEL family of platforms, then you will 212 | need to install packages from the EPEL repository. The easiest way to do this 213 | is to add the following recipe to your runlist before zabbix::server\_source 214 | 215 | recipe "yum::epel" 216 | 217 | You can control the server install with: 218 | 219 | node['zabbix']['server']['branch'] 220 | node['zabbix']['server']['version'] 221 | node['zabbix']['server']['configure_options'] 222 | 223 | The server also needs to know about: 224 | 225 | node['zabbix']['database']['dbhost'] 226 | node['zabbix']['database']['dbname'] 227 | node['zabbix']['database']['dbuser'] 228 | node['zabbix']['database']['dbpassword'] 229 | node['zabbix']['database']['dbport'] 230 | 231 | ## web 232 | 233 | Creates an Apache site for the Zabbix Web component 234 | 235 | # LWRPs 236 | 237 | ## database 238 | 239 | ### resources/database 240 | 241 | Installs the Zabbix Database 242 | 243 | The default provider is Chef::Provider::ZabbixDatabaseMySql in "providers/database_my_sql". 244 | If you want a different provider, make sure you set the following in your resource call. 245 | 246 | provider Chef::Provider::SomeProviderClass 247 | 248 | #### Actions 249 | 250 | * `create` (Default Action) - Creates the Zabbix Database 251 | 252 | #### Attributes 253 | 254 | * `dbname` (Name Attribute) - Name of the Zabbix databse to create 255 | * `host` - Host to create the database on 256 | * `port` - Port to connext to the database over 257 | * `username` - Name of the Zabbix database user 258 | * `password` - Password for the Zabbix database user 259 | * `root_username` - Name of the root user for the database server 260 | * `root_password` - Password for the database root user 261 | * `allowed_user_hosts` (Default: '') - Where users can connect to the database from 262 | * `server_branch` - Which branch of server code you are using 263 | * `server_version` - Which version of server code you are using 264 | * `source_dir` - Where Zabbix source code should be stored on the host 265 | * `install_dir` - Where Zabbix should be installed to 266 | 267 | ### providers/database\_my\_sql 268 | 269 | Installs a MySql or RDS MySql Zabbix Database 270 | 271 | This is the default provider for `resources/database` 272 | 273 | If you are using MySQL make sure you set 274 | 275 | root_username "root" 276 | root_password "your root password" 277 | 278 | If you are using RDS MySql make sure you set 279 | 280 | root_username "your rds master username" 281 | root_password "your rds master password" 282 | 283 | ### providers/database\_postgres 284 | 285 | Installs a Postgres Zabbix Database 286 | 287 | Call the `zabbix_database` resource with 288 | 289 | provider Chef::Provider::ZabbixDatabasePostgres 290 | 291 | Make sure you set 292 | 293 | root_username 'postgres' 294 | root_pasword 'your postgres admin password' 295 | 296 | The `allowed_user_hosts` attribute is ignored 297 | 298 | ### resources/source 299 | 300 | Fetchs the Zabbix source tar and does something with it 301 | 302 | #### Actions 303 | * `extract_only` (Default Action) - Just fetch and extract the tar 304 | * `install_server` - Fetch the tar then compile the source as a Server 305 | * `install_agent` - Fetch the tar then compile the source as an Agent 306 | 307 | #### Attributes 308 | * `name` (Name Attribute) - An arbitrary name for the resource 309 | * `branch` - The branch of Zabbix to grab code for 310 | * `version` - The version of Zabbix to grab code for 311 | * `code_dir` - Where Zabbix source code should be stored on the host 312 | * `target_dir` - A sub directory under `code_dir` where you want the source extracted 313 | * `install_dir` (Optional) - Where Zabbix should be installed to 314 | * `configure_options` (Optional) - Flags to use when compiling Zabbix 315 | 316 | ### providers/source: 317 | 318 | Default implementation of how to Fetch and handle the Zabbix source code. 319 | 320 | 321 | # TODO 322 | 323 | * Support more platform on agent side windows ? 324 | * LWRP Magic ? 325 | 326 | # CHANGELOG 327 | 328 | ### 0.8.0 329 | * This version is a big change with a lot of bugfix and change. Please be careful if you are updated from previous version 330 | 331 | ### 0.0.42 332 | * Adds Berkshelf/Vagrant 1.1 compatibility (andrewGarson) 333 | * Moves recipe[yum::epel] to a documented runlist dependency instead of forcing you to use it via include_recipe 334 | 335 | ### 0.0.41 336 | * Format metadata and add support for Oracle linux (Thanks to tas50 and his love for oracle Linux) 337 | * Fix about redhat LSB in agent-prebuild recipe (Thanks nutznboltz) 338 | * Fix Add missing shabang for init file. (Thanks justinabrahms) 339 | * Fix FC045 foodcritic 340 | * new dependencies version on database and mysql cookbook 341 | * Add support for custom config file location to zabbix_agentd.init-rh.erb (Thanks charlesjohnson) 342 | 343 | ### 0.0.40 344 | * Refactoring for passing foodcritic with help from dkarpenko 345 | * Added new attribute for server service : log_level 346 | * Added new attribute for server service : max_housekeeper_delete & housekeeping_frequency 347 | * Modified firewall recipe to accept connection to localhost zabbix_server 348 | 349 | ### 0.0.39 350 | * Added zabbix bin patch in init script (deprecate change made in 0.0.38) 351 | * Changed default zabbix version to 2.0.3 352 | 353 | ### 0.0.38 354 | * Added zabbix_agent bin dir into PATH for Debian/Ubuntu (Some script need zabbix_sender) 355 | 356 | ### 0.0.37 357 | * Having run dir in /tmp is not so good (Guilhem Lettron) 358 | 359 | ### 0.0.36 360 | * added restart option to zabbix_agentd service definitions (Paul Rossman Patch) 361 | 362 | ### 0.0.35 363 | * Fix from Amiando about server_alias how should be a Array. 364 | * Fix from Guilhem about default run_dir be /tmp,it can be a big problem. 365 | 366 | ### 0.0.34 367 | * remove the protocol filter on firewall. 368 | 369 | ### 0.0.33 370 | * Added ServerActive configuration option for Zabbix agents (Paul Rossman Patch) 371 | 372 | ### 0.0.32 373 | * Fix a issue about order in the declaration of service and the template for recipes agent_* 374 | 375 | ### 0.0.31 376 | * Readme typo 377 | 378 | ### 0.0.30 379 | * Thanks to Paul Rossman for this release 380 | * Zabbix default install version is now 2.0.0 381 | * Option to install Zabbix database on RDS node (default remains localhost MySQL) 382 | * MySQL client now installed with Zabbix server 383 | * Added missing node['zabbix']['server']['dbport'] to templates/default/zabbix_web.conf.php.erb 384 | * Fixed recipe name typo in recipes/web.rb 385 | 386 | ### 0.0.29 387 | * Thanks to Steffen Gebert for this release 388 | * WARNING! this can break stuff : typo error on attribute file default['zabbix']['agent']['server'] -> default['zabbix']['agent']['servers'] 389 | * Evaluate node.zabbix.agent.install as boolean, not as string 390 | * Respect src_dir in mysql_setup 391 | 392 | ### 0.0.28 393 | * Thanks to Steffen Gebert for this release 394 | * Use generic sourceforge download URLs 395 | * Fix warning string literal in condition 396 | * Deploy zabbix.conf.php file for web frontend 397 | * Add "status" option to zabbix_server init script 398 | * Make MySQL populate scripts compatible with zabbix 2.0 399 | * Add example for Chef Solo usage to Vagrantfile 400 | 401 | ### 0.0.27 402 | * Configuration error about include_dir in zabbix_agentd.conf.erb 403 | 404 | ### 0.0.26 405 | * zabbix agent and zabbix server don't want the same include_dir, be careful if you use include_dir 406 | * noob error on zabbix::server 407 | 408 | ### 0.0.25 409 | * Don't try to use String as Interger ! 410 | 411 | ### 0.0.24 412 | * Markdown Format for Readme.md 413 | 414 | ### 0.0.23 415 | * Some Foodcritic 416 | 417 | ### 0.0.22 418 | * Bug in metadata dependencies 419 | * Firewall does not fix the protocol anymore 420 | 421 | ### 0.0.21 422 | * Added Patch from Harlan Barnes his patch include centos/redhat zabbix_server support. 423 | * Added Patch from Harlan Barnes his patch include directory has attribute. 424 | * Force a minimum version for apache2 cookbook 425 | 426 | 427 | ### 0.0.20 428 | * Added Patch from Harlan Barnes his patch include centos/redhat zabbix_agent support. 429 | 430 | ### 0.0.19 431 | * Fix README 432 | 433 | ### 0.0.18 434 | * Fix sysconfdir to point to /etc/zabbix on recipe server_source 435 | * Fix right for folder frontends/php on recipe web 436 | * Hardcode the PATH of conf file in initscript 437 | * Agent source need to build on a other folder 438 | * Add --prefix option to default attributes when using *-source recipe 439 | 440 | ### 0.0.17 441 | * Don't mess with te PID, PID are now in /tmp 442 | 443 | ### 0.0.16 444 | * Add depencies for recipe agent_source 445 | * Add AlertScriptsPath folder and option for server. 446 | 447 | ### 0.0.15 448 | * Add firewall magic for communication between client and server 449 | 450 | ### 0.0.14 451 | * Correction on documentation 452 | 453 | ### 0.0.13 454 | * Fix some issue on web receipe. 455 | 456 | ### 0.0.12 457 | * Change default value of zabbix.server.dbpassword to nil 458 | 459 | ### 0.0.11 460 | * Remove mikoomo 461 | * Still refactoring 462 | 463 | ### 0.0.10 464 | * Preparation for multiple type installation and some refactoring 465 | * Support the installation of a beta version when using the install_method == source and changing the attribute branch 466 | 467 | ### 0.0.9 468 | * Tune of mikoomi for running on agent side. 469 | 470 | ### 0.0.8 471 | * Fix some major issu 472 | 473 | ### 0.0.7 474 | * Add some love to php value 475 | * Now recipe mysql_setup populate the database 476 | * Minor fix 477 | 478 | ### 0.0.6 479 | * Change the name of the web_app to fit the fqdn 480 | --------------------------------------------------------------------------------