nagira 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 $?