nagira 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/History.md +89 -0
  2. data/Rakefile +128 -0
  3. data/bin/nagira +11 -0
  4. data/bin/nagira-setup +6 -0
  5. data/config/defaults.rb +74 -0
  6. data/config/environment.rb +44 -0
  7. data/config/nagira.defaults +66 -0
  8. data/config/nagira.init_d +133 -0
  9. data/lib/app.rb +330 -0
  10. data/lib/app/routes/get/config.rb +22 -0
  11. data/lib/app/routes/get/objects.rb +71 -0
  12. data/lib/app/routes/get/status.rb +153 -0
  13. data/lib/app/routes/put.rb +52 -0
  14. data/lib/app/routes/put/status.rb +139 -0
  15. data/lib/nagira.rb +55 -0
  16. data/lib/nagira/background_parse.rb +28 -0
  17. data/lib/nagira/nagios.rb +20 -0
  18. data/lib/nagira/timed_parse.rb +77 -0
  19. data/spec/00_configuration_spec.rb +62 -0
  20. data/spec/01_nagira_response_spec.rb +122 -0
  21. data/spec/02_0_status_spec.rb +53 -0
  22. data/spec/02_nagira_data_spec.rb +101 -0
  23. data/spec/03_api_spec.rb +48 -0
  24. data/spec/spec_helper.rb +4 -0
  25. data/test/benchmark.rb +26 -0
  26. data/test/data/bad/README +1 -0
  27. data/test/data/bad/nagios.cfg +1305 -0
  28. data/test/data/bad/objects.cache +1868 -0
  29. data/test/data/bad/status.dat +1766 -0
  30. data/test/data/json/GET.txt +15 -0
  31. data/test/data/json/README.txt +9 -0
  32. data/test/data/json/host_check.json +4 -0
  33. data/test/data/json/host_check.sh +4 -0
  34. data/test/data/json/ping.json +5 -0
  35. data/test/data/json/ping_and_http.json +12 -0
  36. data/test/data/json/ping_and_http_check.sh +4 -0
  37. data/test/data/json/ping_check.sh +4 -0
  38. data/test/data/nagios.cfg +1305 -0
  39. data/test/data/objects.cache +1868 -0
  40. data/test/data/status.dat +1652 -0
  41. data/version.txt +1 -0
  42. metadata +384 -0
data/History.md ADDED
@@ -0,0 +1,89 @@
1
+ ### v.0.2.5
2
+
3
+ * Fri Mar 15 2013 -- Dmytro Kovalov
4
+ - Environment variables support and defaults file:
5
+ - `NAGIRA_TTL`
6
+ - `NAGIRA_BG_PARSING`
7
+ - `NAGIRA_PORT` - see Sinatra `set :port`
8
+ - `NAGIRA_BIND` - see Sinatra `set :bind`
9
+ - Packaged as gem
10
+ - nagira and nagira-setup binaries
11
+ - cleaner init.d script, support for Debian and RedHat
12
+ - defaults file in `/etc/sysconfig` or `/etc/default`
13
+ - tasks to check configuration by user
14
+ - Add partial ActiveSupport routes
15
+ - `/_objects/host` works as well as `/_objects/hosts`
16
+ - selection objects by ID is TODO
17
+ * Feb 19, 2013 -- Dmytro Kovalov
18
+ - Background parser.
19
+
20
+ To avoid delays on HTTP request from user. All data are parsed in separate thread.
21
+ - configurable TTL for background parsing
22
+ - can be disabled
23
+ - Start-up section for the Nagira app.
24
+
25
+ All Nagios files are validated at start-up, rather than on first HTTP request.
26
+
27
+ If there are permission problem or file don't exist error is reported to user.
28
+ * Feb 9, 2013
29
+ - Merge all custom changes to `ruby-nagios` into upstream, use `ruby-nagios` as gem, not git sub-module
30
+ - `nagios.cfg` file selection is in `ruby-nagios` now.
31
+
32
+ Look for config in `/etc/nagios*/` and `/usr/local/nagios/etc/`. Can be overridden by `NAGIOS_CFG_FILE` environment.
33
+
34
+ ### v.0.2.1
35
+
36
+ * Wed Dec 19 2012 - Dmytro Kovalov
37
+ - fix for DOS formatted and spaces in config ; better error reporting for spec. fixes #8
38
+ - Switch to markdown in documentation: README, CONFIGURAION etc.
39
+ - Configuration documentation. Examples of usage for JSON: example files and scripts.
40
+ - Nagira::INSTALL configuration constant. Use Nagira::INSTALL for init.d creation.
41
+ - ERB template for /etc/init./d file
42
+ - Fixes for YARD formatting
43
+ - Use Travis CI for Nagira testing
44
+ * Thu Oct 4 19:45:00 JST 2012
45
+
46
+ ### v.0.2.0
47
+
48
+ - lot of bug fixes
49
+ - API: first working PUT API for process host status and process service status external commands
50
+ * 2012-09-28 Dmytro Kovalov - v. 0.1.5
51
+ - many changes for testing files nagios.cfg, objects, status. Tested to work both in dev/test and production environments.
52
+ - more documentation
53
+ - API: additional modifier for output: `_full`. By default now `/_status` returns Hash with hoststatus only. Use ../_full to get both hoststatus and sevicestatus.
54
+
55
+ ### v. 0.1.4
56
+
57
+ * 2012-09-26 Dmytro Kovalov -
58
+ - added support for JSON-P parameters (?callback=<nam>)
59
+ - change API to have all keywords underscored, to avoid clashes with object names (`/_status`, `_objects`, `/_status/_list` etc).
60
+
61
+ ### v. 0.1.3
62
+
63
+ * 2012-06-8 Dmytro Kovalov
64
+ - specs for /config, /status, /objects - simple page loads and data
65
+ checks;
66
+ - /api route;
67
+ - bugfixes;
68
+ - YARD documentation;
69
+
70
+ ### v. 0.1.2
71
+
72
+ * 2012-06-2 Dmytro Kovalov
73
+ - spec for configuration files
74
+ - spec for basic responses from Sinatra (`GET /objects`, `GET /status`)
75
+ - CONFIGURATION.rdoc
76
+ - configuration cleanup
77
+ * 2012-05-22 Dmytro Kovalov
78
+ - start using Gemfile
79
+ - INSTALL.rdoc - simple description of installation procedure
80
+ * 2012-01-12 Dmytro Kovalov
81
+ - History.rdoc and version.txt files
82
+ - Routes for objects configuration GET's
83
+ - FEATURES.rdoc
84
+ - YARD documentation
85
+ * 2012-01-02 Dmytro Kovalov
86
+ - First Sinatra application to return service state information
87
+ * 2011-12-25 @dmytro
88
+ - Started Github project
89
+
data/Rakefile ADDED
@@ -0,0 +1,128 @@
1
+ require 'fileutils'
2
+ require_relative 'lib/nagira'
3
+
4
+ def log_user msg
5
+ puts "#{Time.now} -- #{msg.chomp}"
6
+ end
7
+
8
+ namespace :doc do
9
+
10
+ desc 'Generate YARD documentation'
11
+ task :yard do
12
+ sh 'yardoc'
13
+ end
14
+
15
+ end
16
+
17
+ namespace :config do
18
+
19
+ @nagira_root = File.dirname File.expand_path __FILE__ # Where Nagira installed
20
+ @nagira_config = File.join(@nagira_root, 'config') # Config directory of Nagira installation
21
+
22
+ target_os = nil
23
+
24
+ %x{ sherlock }.split($\).each do |line|
25
+ next unless line =~ /^FAMILY=/
26
+ l,target_os = line.chomp.split '='
27
+ target_os = target_os.chomp.strip.to_sym
28
+ end
29
+
30
+ namespace :test do
31
+
32
+ desc "Test Nagira production config: Nagios files in proper locations and parseable"
33
+ task :prod do
34
+ ENV['RACK_ENV'] = 'production'
35
+ Rake::Task['config:test:test'].invoke
36
+ end
37
+
38
+ desc "Test Nagira installation: test Nagios files and parse"
39
+ task :install do
40
+ ENV['RACK_ENV'] = 'test'
41
+ Rake::Task['config:test:test'].invoke
42
+ end
43
+
44
+ task :test do
45
+ p "Starting test in #{ENV['RACK_ENV']} environment"
46
+ sh "rspec --format doc --color spec/00_configuration_spec.rb"
47
+ end
48
+
49
+ end
50
+
51
+ desc "Create Nagira configuration, allow start on boot and start it"
52
+ task :all => [:config, :chkconfig, :start]
53
+
54
+ def test?
55
+ ENV['RAKE_ENV'] == 'test'
56
+ end
57
+
58
+ etc = test? ? 'tmp/etc' : "/etc"
59
+ init_d = File.join etc, 'init.d'
60
+
61
+ directory etc
62
+ directory init_d
63
+
64
+
65
+ desc "Create configuration for Nagira in /etc"
66
+ task :config => [:init_d, :defaults]
67
+
68
+
69
+ #desc "Install /etc/init.d startup file for Nagira"
70
+ task :init_d => init_d do
71
+ src = File.join(@nagira_config, 'nagira.init_d')
72
+ dst = "#{init_d}/nagira"
73
+
74
+ FileUtils.copy src, dst
75
+ FileUtils.chown 0, 0, dst unless test?
76
+ FileUtils.chmod 0755, dst
77
+
78
+ log_user "Installed startup file at #{dst}"
79
+ end
80
+
81
+ #desc "Install defaults file for Nagira service in /etc"
82
+ task :defaults do
83
+ src = File.join(@nagira_config, 'nagira.defaults')
84
+ dst = case target_os
85
+ when :rh
86
+ '/etc/sysconfig/nagira'
87
+ when :debian
88
+ '/etc/default/nagira'
89
+ else
90
+ log_user "Unknown or unsupported target OS: #{target_os}"
91
+ log_user " >>> Skipped defaults file installation"
92
+ next
93
+ end
94
+ unless File.exists? dst
95
+ FileUtils.copy src, dst
96
+ FileUtils.chown 0, 0, dst unless test?
97
+ FileUtils.chmod 0644, dst
98
+
99
+ log_user "Installed new defaults file for Nagira in #{dst}."
100
+ log_user " >>> You might want to tune some of the variables."
101
+ end
102
+ end
103
+
104
+ desc "Start Nagira API service"
105
+ task :start => [:init_d, :defaults] do
106
+ log_user "Starting Nagira for the first time"
107
+ sh "/etc/init.d/nagira start"
108
+ end
109
+
110
+ desc "Configure Nagira to start on system boot"
111
+ task :chkconfig => [:init_d, :defaults] do
112
+
113
+ log_user "Configuring Nagira to start at boot"
114
+ case target_os
115
+ when :rh
116
+ sh "/sbin/chkconfig --add nagira"
117
+ sh "/sbin/chkconfig nagira on"
118
+ when :debian
119
+ sh "/usr/sbin/update-rc.d nagira defaults"
120
+ else
121
+ abort "Unknown or unsupported target OS: #{target_os}"
122
+ end
123
+ log_user "[OK]"
124
+ end
125
+
126
+ end
127
+
128
+
data/bin/nagira ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ begin
4
+ require 'app.rb'
5
+ rescue LoadError => e
6
+ require 'rubygems'
7
+ path = File.expand_path '../../lib', __FILE__
8
+ $:.unshift(path) if File.directory?(path) && !$:.include?(path)
9
+ require 'app.rb'
10
+ end
11
+ Nagira.run!
data/bin/nagira-setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ path = File.expand_path '..', __FILE__
5
+
6
+ print %x{ cd #{path} && rake #{ARGV[0] || '-T'} }.gsub(/^rake/, File.basename(__FILE__))
@@ -0,0 +1,74 @@
1
+
2
+
3
+ ##
4
+ # This file sets some constants, that are used as defaults in Nagira
5
+ # application. Instead of changing this please modify
6
+ # config/environment.rb file to match your requirements. Settings in
7
+ # environment.rb file override these defaults.
8
+ #
9
+ # Exception is ::DEFAULT[:ttl] which is not overriden by environment.rb
10
+ # and should be changed here.
11
+
12
+
13
+ DEFAULT = {
14
+
15
+ format_extensions: '\.(json|yaml|xml)$', # Regex for available
16
+ # formats: xml, json, yaml
17
+
18
+ format: :xml, # default format for application to send output, if
19
+ # format is not specified
20
+
21
+
22
+ # No path to file configuration file by default. Main nagios config
23
+ # is defined by +nagios_cfg_glob+ or by Sintra's
24
+ # +settings.nagios_cfg+ variable.
25
+ #
26
+ # status_cfg and objects_cfg are defined by parsing of nagios_cfg
27
+ # file. Sinatra's setting override parsed values.
28
+ nagios_cfg: nil,
29
+ status_cfg: nil,
30
+ objects_cfg: nil,
31
+ command_file: nil,
32
+
33
+ ##
34
+ # ttl used in Nagios::TimedParse module - extension
35
+ # to Nagios modules.
36
+ #
37
+ # @see Nagios::TimedParse
38
+ #
39
+ # Set some minimum interval for re-parsing of the status file: even
40
+ # if file changes often, we do not want to parse it more often, then
41
+ # this number of seconds. To disable timed parsing, set
42
+ # ttl to 0 or negative number.
43
+
44
+ ttl: ENV['NAGIRA_TTL'].to_i || 5,
45
+
46
+ ##
47
+ # start_background_parser used in Nagios::BackgroundParse class.
48
+ #
49
+ # @see Nagios::BackgroundParse
50
+ #
51
+ # If set to true then use background parser. This will prevent
52
+ # parsing delays on client request. Background parserruns on
53
+ # intervals slightly shorter than `ttl` to ensure that data are
54
+ # always updated. So, `ttl` should be larger than 1.
55
+ #
56
+ start_background_parser: (ENV['NAGIRA_BG_PARSING'] == '1')
57
+ }
58
+
59
+ require 'sinatra'
60
+ class Nagira < Sinatra::Base
61
+
62
+ ##
63
+ # For every key in the DEFAULT hash create setting with the same name
64
+ # and value. Values can be overrriden in environment.rb file if
65
+ # required.
66
+ # @method define_methods_for_defaults
67
+ configure do
68
+ ::DEFAULT.each do |key,val|
69
+ set key,val
70
+ end
71
+ end
72
+
73
+
74
+ end
@@ -0,0 +1,44 @@
1
+
2
+ class Nagira < Sinatra::Base
3
+
4
+ disable :protection
5
+ enable :logging
6
+
7
+ set :port, ENV['NAGIRA_PORT'].to_i if ENV['NAGIRA_PORT']
8
+ set :bind, ENV['NAGIRA_BIND'] if ENV['NAGIRA_BIND']
9
+
10
+ configure do
11
+ set :format, :json
12
+ end
13
+
14
+ if development?
15
+ require 'sinatra/reloader'
16
+ register Sinatra::Reloader
17
+ also_reload(File.dirname(File.dirname(__FILE__))+"/*.rb")
18
+ also_reload(File.dirname(File.dirname(__FILE__))+"/{app,lib}/**/*.rb")
19
+ end
20
+
21
+ ##
22
+ # Development and test environments use local files located in the
23
+ # development tree: ./test/data.
24
+ configure :development, :test do
25
+
26
+ dir = File.expand_path(File.dirname(__FILE__) + '/../test/data/')
27
+
28
+ set :nagios_cfg, "#{dir}/nagios.cfg"
29
+ set :status_cfg, "#{dir}/status.dat"
30
+ set :objects_cfg, "#{dir}/objects.cache"
31
+ set :command_file, "/tmp/nagios.cmd"
32
+
33
+ set :show_exceptions, false
34
+ end
35
+
36
+
37
+ # configure :production do
38
+ # # If your nagios.cfg file is in 'standard' location (in RH and
39
+ # # Debian it usially installed under /etc/nagios(3)?) you don't need
40
+ # # to define nagios_cfg.
41
+ # set :nagios_cfg, nil
42
+ # end
43
+
44
+ end
@@ -0,0 +1,66 @@
1
+ #
2
+ # Defaults configuration file for Nagira
3
+ # --------------------------------------------
4
+ #
5
+ # ----------------------
6
+ # Port. Default 4567
7
+ # ----------------------
8
+ # NAGIRA_PORT=
9
+ #
10
+ # ----------------------
11
+ # BIND
12
+ # ----------------------
13
+ # String specifying the hostname or IP address of the interface to
14
+ # listen on when the :run setting is enabled. The default value –
15
+ # '0.0.0.0' – causes the server to listen on all available
16
+ # interfaces. To listen on the loopback interface only, use: 'localhost'
17
+ #
18
+ # NAGIRA_BIND=localhost
19
+ #
20
+ # ----------------------
21
+ # Environment
22
+ # ----------------------
23
+ # Usually needs to be production
24
+ #
25
+ # RACK_ENV=production
26
+ #
27
+ # ----------------------
28
+ # Nagira user
29
+ # ----------------------
30
+ # Usually nagira process should be run by same user ID as Nagios. In
31
+ # many cases this is nagios user.
32
+ #
33
+ # NAGIRA_USER=nagios
34
+ #
35
+ # ----------------------
36
+ # RVM
37
+ # ----------------------
38
+ # RVM_STRING="rvm use default"
39
+ #
40
+ # ----------------------
41
+ # Log file
42
+ # ----------------------
43
+ # NAGIRA_LOG=/var/log/nagios/nagira.log
44
+ #
45
+ # ----------------------
46
+ # TTL for data
47
+ # ----------------------
48
+ # Number of seconds between re-parses. All Nagios file are parsed no
49
+ # more often than this. Default is 5 sec. Setting this to 0 or
50
+ # negative number disables TTL and backgroiund prser as well.
51
+ #
52
+ # NAGIRA_TTL=20
53
+ #
54
+ # ----------------------
55
+ # Background parsing
56
+ # ----------------------
57
+ # Set this to 0, to disable background parsing.
58
+ # NAGIRA_BG_PARSING=1
59
+ #
60
+ # ----------------------
61
+ # Nagios configuration file
62
+ # ----------------------
63
+ # Where main Nagios configuration file is located. usually this does
64
+ # not need to change.
65
+ #
66
+ # NAGIOS_CFG_FILE=/etc/nagios/nagios.cfg
@@ -0,0 +1,133 @@
1
+ #!/bin/bash
2
+ ### BEGIN INIT INFO
3
+ # Provides: nagira
4
+ # Required-Start:
5
+ # Required-Stop:
6
+ # Default-Start: 2 3 4 5
7
+ # Default-Stop: 0 1 6
8
+ # Short-Description: Nagira API application for Nagios
9
+ # Description: Controls Nagira API application for Nagios
10
+ ### END INIT INFO
11
+ #
12
+ # nagira:
13
+ #
14
+ # Version: 1
15
+ #
16
+ # chkconfig: - 20 99
17
+ # description: Start-up file for Nagira monitoring component, Nagios RESTful API. See also: http://dmytro.github.com/nagira
18
+ # processname: ruby /.../nagira
19
+ # config: /etc/sysconfig/nagira, /etc/default/nagira
20
+
21
+ process_name="Sinatra Nagira services"
22
+
23
+ pid_file=/var/run/nagira.pid
24
+
25
+
26
+ load_defaults () {
27
+ which sherlock > /dev/null 2>&1 && eval $(sherlock | grep FAMILY) || { echo "sherlock not found"; exit 2; }
28
+
29
+ case $FAMILY in
30
+ 'rh')
31
+ DEFAULTS=/etc/sysconfig/nagira ;;
32
+ 'debian')
33
+ DEFAULTS=/etc/default/nagira ;;
34
+ *)
35
+ echo "Unknown OS or distribution version: $FAMILY"
36
+ exit 1
37
+ ;;
38
+ esac
39
+ source $DEFAULTS || { echo "Can not load defaults file" ; exit 1 ; }
40
+ }
41
+
42
+
43
+ ##
44
+ # Some reasonable defaults if not set in defaults file
45
+ #
46
+ RACK_ENV=${RACK_ENV:-production}
47
+ NAGIRA_USER=${NAGIRA_USER:-nagios}
48
+ RVM_STRING=${RVM_STRING:-"true"} # i.e. do nothing special
49
+ NAGIRA_LOG=${NAGIRA_LOG:-/var/log/nagios/nagira.log}
50
+ # There's no default for NAGIOS_CFG_FILE. Default is actually to have
51
+ # it unset, Nagira would be able to find nagios config if it is in one
52
+ # of the standard locations (/etc or /usr/local). If your Nagios
53
+ # installation is less than standard, you can override it by setting
54
+ # NAGIOS_CFG_FILE
55
+ #
56
+ # NAGIOS_CFG_FILE=...
57
+
58
+ export RACK_ENV NAGIRA_LOG NAGIRA_USER RVM_STRING
59
+
60
+ get_pid () {
61
+ # ps -U ${
62
+ # ps -C ruby -o pid,comm,cmd
63
+ #echo $(ps axo pid,command | awk '$2 ~ /ruby/ && $3 ~ /nagira/ {print $1}')
64
+ echo $(ps -C ruby -o pid,cmd | awk '$2 ~ /^\/usr.*bin\/nagira *$/ {print $1}')
65
+ }
66
+
67
+
68
+ start() {
69
+ [ ! -z "$(get_pid)" ] && { status; return 1; }
70
+ echo -n "Starting ${process_name}: "
71
+ load_defaults
72
+ su - $NAGIRA_USER -s /bin/bash -c "$RVM_STRING ; RACK_ENV=$RACK_ENV nagira&" > $NAGIRA_LOG 2>&1
73
+ sleep 5
74
+ process=$(get_pid)
75
+ if [ -z "$process" ]; then
76
+ echo "[FAIL]"
77
+ else
78
+ echo $process > $pid_file
79
+ echo "[OK]"
80
+ status
81
+ fi
82
+ }
83
+
84
+ stop() {
85
+ local process=$(get_pid)
86
+ [ -z "$process" ] && { status; return 1; }
87
+
88
+ echo -n $"Shutting down ${process_name}: "
89
+
90
+ kill $process
91
+ \rm -f $pid_file
92
+ RETVAL=$?
93
+ sleep 2
94
+ [ -z "$(get_pid)" ] && { echo OK; return $RETVAL; }
95
+ echo FAIL
96
+ }
97
+
98
+ status () {
99
+ local process=$(get_pid)
100
+ if [ -z "$process" ]; then
101
+ echo "Process $process_name is not running"
102
+ else
103
+ echo "Process $process_name is running with PID: $process"
104
+ fi
105
+ }
106
+
107
+ restart() {
108
+ stop
109
+ start
110
+ }
111
+
112
+ RETVAL=0
113
+
114
+ # See how we were called.
115
+ case "$1" in
116
+ start)
117
+ start
118
+ ;;
119
+ stop)
120
+ stop
121
+ ;;
122
+ status)
123
+ status
124
+ ;;
125
+ restart|force-reload)
126
+ restart
127
+ ;;
128
+ *)
129
+ echo $"Usage: $0 {start|stop|status|restart|force-reload}"
130
+ exit 1
131
+ esac
132
+
133
+ exit $?