nagi 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Nagi
2
+
3
+ A Ruby DSL for writing Nagios plugins. It handles the tedium of argument
4
+ parsing, exit statuses, output formatting and such, and lets you focus on
5
+ writing the actual check.
6
+
7
+ Written by Erik Grinaker <erik@bengler.no>, and licensed under the
8
+ GNU GPL v3.
9
+
10
+ ## Example
11
+
12
+ A typical plugin looks like this:
13
+
14
+ ```ruby
15
+ #!/usr/bin/env ruby
16
+
17
+ require 'nagi'
18
+ require Resolv
19
+
20
+ Nagi do
21
+ name 'check_dns'
22
+ version '0.1'
23
+ prefix 'DNS'
24
+ argument :hostname
25
+ switch :ip, '-i', '--ip IP', 'Expected IP address'
26
+
27
+ check do |args|
28
+ begin
29
+ ip = Resolv.getaddress(args[:hostname])
30
+ rescue Resolv::ResolvError => e
31
+ critical e.message
32
+ end
33
+
34
+ if args[:ip] and ip != args[:ip]
35
+ critical "#{args[:hostname]} resolves to #{ip}, expected #{args[:ip]}
36
+ else
37
+ ok "#{args[:hostname]} resolves to #{ip}"
38
+ end
39
+ end
40
+ end
41
+ ```
42
+
43
+ Here we first set up some basic info like name and version, and specify a few
44
+ command-line options. Then we write a block of code containing the actual
45
+ check, which is given the parsed command-line options as a hash, and returns a
46
+ status via methods like `ok` and `critical`.
47
+
48
+ To run the plugin, type `./check_dns.rb --ip 127.0.0.1 localhost`, or try
49
+ `./check_dns.rb --help` for more info.
50
+
51
+ ## Reference
52
+
53
+ ### Metadata
54
+
55
+ These describe the program, and are usually given first, if necessary.
56
+
57
+ * `name` *name*: the program name.
58
+ * `version` *version*: the program version.
59
+ * `prefix` *prefix*: a prefix for the check output.
60
+
61
+ ### Command-line arguments
62
+
63
+ Command-line arguments can be specified, and will be parsed automatically and
64
+ passed to the `check` method as a hash, with keys given by the argument name.
65
+
66
+ * `argument` *name*: a mandatory, positional argument.
67
+ * `switch` *name*, *args*: an optional switch. *args* are passed directory to
68
+ the standard Ruby OptionParser class - see its documentation for details.
69
+
70
+ Command-line arguments for -h/--help and -V/--version are added and handled
71
+ automatically.
72
+
73
+ ### Check
74
+
75
+ The check is given as a code block to the `check` method, and is passed the
76
+ parsed command-line arguments as a hash. It should use one of the methods `ok`,
77
+ `warning`, `critical`, or `unknown` to return a status. If no status is given,
78
+ or the block raises an unhandled exception, an Unknown status will be returned.
79
+
80
+ * `check` *block*: the code block the the check. Parsed command-line arguments
81
+ are passed as a hash.
82
+ * `ok` *message*: returns an OK status.
83
+ * `warning` *message*: returns a Warning status.
84
+ * `critical` *message*: returns a Critical status.
85
+ * `unknown` *message*: returns an Unknown status.
86
+ * `execute` *command*: executes a shell command, and returns any output (both
87
+ stdout and stderr). If the command exits with a non-zero status, it will
88
+ throw an exception. The shell is set to use the `pipefail` option, so non-zero
89
+ exit statuses in pipelines are detected as well.
90
+
91
+ ## License
92
+
93
+ This program is free software: you can redistribute it and/or modify
94
+ it under the terms of the GNU General Public License as published by
95
+ the Free Software Foundation, either version 3 of the License, or
96
+ (at your option) any later version.
97
+
98
+ This program is distributed in the hope that it will be useful,
99
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
100
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
101
+ GNU General Public License for more details.
102
+
103
+ You should have received a copy of the GNU General Public License
104
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/lib/nagi/dsl.rb ADDED
@@ -0,0 +1,57 @@
1
+ module Nagi
2
+ class DSL
3
+ attr_reader :plugin
4
+
5
+ def initialize(&block)
6
+ @plugin = Nagi::Plugin.new
7
+ instance_eval &block
8
+ end
9
+
10
+ def argument(name)
11
+ @plugin.optionparser.argument(name)
12
+ end
13
+
14
+ def check(&block)
15
+ p = class << @plugin; self; end
16
+ p.send(:define_method, :check) do |options|
17
+ return catch(:status) { block.call(options) }
18
+ end
19
+ end
20
+
21
+ def critical(message)
22
+ throw :status, Nagi::Status::Critical.new(message)
23
+ end
24
+
25
+ def execute(command)
26
+ return Nagi::Utility.execute(command)
27
+ end
28
+
29
+ def name(name)
30
+ @plugin.name = name
31
+ end
32
+
33
+ def ok(message)
34
+ throw :status, Nagi::Status::OK.new(message)
35
+ end
36
+
37
+ def prefix(prefix)
38
+ @plugin.prefix = prefix
39
+ end
40
+
41
+ def switch(name, *args)
42
+ @plugin.optionparser.switch(name, *args)
43
+ end
44
+
45
+ def unknown(message)
46
+ throw :status, Nagi::Status::Unknown.new(message)
47
+ end
48
+
49
+ def version(version)
50
+ @plugin.version = version
51
+ end
52
+
53
+ def warning(message)
54
+ throw :status, Nagi::Status::Warning.new(message)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,48 @@
1
+ module Nagi
2
+ class OptionParser < ::OptionParser
3
+
4
+ def initialize(*args, &block)
5
+ @arguments = []
6
+ @options = {}
7
+
8
+ super(*args, &block)
9
+
10
+ self.banner = "Usage: #{$0} [options]"
11
+
12
+ self.on_tail('-h', '--help', 'Display this help message') do
13
+ puts help
14
+ exit 0
15
+ end
16
+
17
+ self.on_tail('-V', '--version', 'Display version information') do
18
+ puts "#{program_name} #{version or "(unknown version)"}".strip
19
+ exit 0
20
+ end
21
+ end
22
+
23
+ def argument(name)
24
+ @arguments.push(name)
25
+ self.banner += " <#{name}>"
26
+ end
27
+
28
+ def parse!(args)
29
+ begin
30
+ @options.clear
31
+ super(args)
32
+ @arguments.each do |a|
33
+ @options[a] = args.shift or raise ArgumentError.new("Argument '#{a}' not given")
34
+ end
35
+ raise ArgumentError.new("Too many arguments") if args.length > 0
36
+ rescue ::OptionParser::ParseError => e
37
+ raise ArgumentError.new(e.message)
38
+ end
39
+ return @options
40
+ end
41
+
42
+ def switch(name, *args)
43
+ on(*args) do |value|
44
+ @options[name] = value
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,49 @@
1
+ module Nagi
2
+ class Plugin
3
+ attr_accessor :name, :optionparser, :prefix, :version
4
+
5
+ def initialize
6
+ @optionparser = Nagi::OptionParser.new
7
+ end
8
+
9
+ def check(options)
10
+ raise NotImplementedError.new('No check defined')
11
+ end
12
+
13
+ def name=(value)
14
+ @name = value
15
+ @optionparser.program_name = value
16
+ end
17
+
18
+ def run(args)
19
+ options = @optionparser.parse(args)
20
+ begin
21
+ status = self.check(options)
22
+ rescue StandardError => e
23
+ status = Nagi::Status::Unknown.new(e.message)
24
+ end
25
+ if not status.is_a?Nagi::Status::Status
26
+ status = Nagi::Status::Unknown.new('Check did not provide a status')
27
+ end
28
+ return status
29
+ end
30
+
31
+ def run!
32
+ begin
33
+ status = run(ARGV)
34
+ puts "#{@prefix.upcase if @prefix} #{status}".strip
35
+ exit status.code
36
+ rescue ArgumentError => e
37
+ STDERR.puts("Error: #{e.message}")
38
+ puts ""
39
+ puts @optionparser
40
+ exit 4
41
+ end
42
+ end
43
+
44
+ def version=(value)
45
+ @version = value
46
+ @optionparser.version = value
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,42 @@
1
+ module Nagi
2
+ module Status
3
+ class Status
4
+ attr_accessor :message
5
+ attr_reader :code, :name
6
+
7
+ def initialize(code, name, message)
8
+ @code = code
9
+ @name = name
10
+ @message = message
11
+ end
12
+
13
+ def to_s
14
+ return "#{@name.upcase}: #{@message}"
15
+ end
16
+ end
17
+
18
+ class Critical < Status
19
+ def initialize(message)
20
+ super(2, 'Critical', message)
21
+ end
22
+ end
23
+
24
+ class OK < Status
25
+ def initialize(message)
26
+ super(0, 'OK', message)
27
+ end
28
+ end
29
+
30
+ class Unknown < Status
31
+ def initialize(message)
32
+ super(3, 'Unknown', message)
33
+ end
34
+ end
35
+
36
+ class Warning < Status
37
+ def initialize(message)
38
+ super(1, 'Warning', message)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ module Nagi
2
+ module Utility
3
+ module_function
4
+
5
+ def execute(command)
6
+ output, status = Open3.capture2e("/bin/bash -o pipefail -c '#{command}'")
7
+ raise "Shell failure, '#{output.gsub(/^\/bin\/bash: /, '').strip}'" if status.exitstatus != 0
8
+ return output.strip
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Nagi
2
+ VERSION = '0.1.0'
3
+ end
data/lib/nagi.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'open3'
2
+ require 'optparse'
3
+
4
+ require 'nagi/dsl'
5
+ require 'nagi/optionparser'
6
+ require 'nagi/plugin'
7
+ require 'nagi/status'
8
+ require 'nagi/utility'
9
+ require 'nagi/version'
10
+
11
+ module Nagi
12
+ end
13
+
14
+ def Nagi(&block)
15
+ Nagi::DSL.new(&block).plugin.run!
16
+ end
data/nagi.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'nagi/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'nagi'
7
+ s.version = Nagi::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Erik Grinaker']
10
+ s.email = ['erik@bengler.no']
11
+ s.homepage = 'http://github.com/bengler/nagi'
12
+ s.summary = 'A DSL for writing Nagios plugins'
13
+ s.description = 'A DSL for writing Nagios plugins'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_development_dependency 'rake'
21
+ s.add_development_dependency 'rspec'
22
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nagi::DSL do
4
+ before(:each) do
5
+ @dsl = Nagi::DSL.new do
6
+ end
7
+ end
8
+
9
+ describe '#plugin' do
10
+ it 'contains a Nagi::Plugin' do
11
+ @dsl.plugin.class.should eq Nagi::Plugin
12
+ end
13
+
14
+ it 'is read-only' do
15
+ lambda { @sdl.plugin = nil }.should raise_error NoMethodError
16
+ end
17
+ end
18
+
19
+ describe '.argument' do
20
+ it 'sends argument to parser.optionparser' do
21
+ @dsl.argument(:name)
22
+ @dsl.plugin.optionparser.help.should match /<name>/
23
+ end
24
+ end
25
+
26
+ describe '.check' do
27
+ it 'sets the code block on plugin.check' do
28
+ @dsl.check do |options|
29
+ $nagi = options
30
+ end
31
+ @dsl.plugin.check({'a' => 1})
32
+ $nagi.should eq Hash['a' => 1]
33
+ end
34
+
35
+ it 'catches throwns :status and returns payload' do
36
+ @dsl.check do |options|
37
+ throw :status, 'status'
38
+ end
39
+ @dsl.plugin.check({}).should eq 'status'
40
+ end
41
+ end
42
+
43
+ describe '.critical' do
44
+ it 'throws :status with critical status' do
45
+ catch(:status) do
46
+ @dsl.critical('message')
47
+ end.class.should eq Nagi::Status::Critical
48
+ end
49
+ end
50
+
51
+ describe '.execute' do
52
+ it 'executes a command with Nagi::Utility.execute' do
53
+ @dsl.execute('echo test >&2').should eq 'test'
54
+ end
55
+ end
56
+
57
+ describe '.name' do
58
+ it 'sets plugin name' do
59
+ @dsl.name('name')
60
+ @dsl.plugin.name.should eq 'name'
61
+ end
62
+ end
63
+
64
+ describe '.ok' do
65
+ it 'throws :status with ok status' do
66
+ catch(:status) do
67
+ @dsl.ok('message')
68
+ end.class.should eq Nagi::Status::OK
69
+ end
70
+ end
71
+
72
+ describe '.prefix' do
73
+ it 'sets plugin prefix' do
74
+ @dsl.prefix('prefix')
75
+ @dsl.plugin.prefix.should eq 'prefix'
76
+ end
77
+ end
78
+
79
+ describe '.switch' do
80
+ it 'adds optionparser switch' do
81
+ @dsl.switch(:switch, '-s', '--switch', 'Test switch')
82
+ @dsl.plugin.optionparser.top.list[-1].short[0].should eq '-s'
83
+ @dsl.plugin.optionparser.top.list[-1].long[0].should eq '--switch'
84
+ end
85
+ end
86
+
87
+ describe '.unknown' do
88
+ it 'throws :status with unknown status' do
89
+ catch(:status) do
90
+ @dsl.unknown('message')
91
+ end.class.should eq Nagi::Status::Unknown
92
+ end
93
+ end
94
+
95
+ describe '.version' do
96
+ it 'sets plugin version' do
97
+ @dsl.version('version')
98
+ @dsl.plugin.version.should eq 'version'
99
+ end
100
+ end
101
+
102
+ describe '.warning' do
103
+ it 'throws :status with warning status' do
104
+ catch(:status) do
105
+ @dsl.warning('message')
106
+ end.class.should eq Nagi::Status::Warning
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nagi::OptionParser do
4
+ before(:each) do
5
+ @parser = Nagi::OptionParser.new
6
+ end
7
+
8
+ it 'subclasses OptionParser' do
9
+ @parser.is_a?(::OptionParser).should eq true
10
+ end
11
+
12
+ describe '.initialize' do
13
+ it 'set proper banner' do
14
+ @parser.banner.should eq "Usage: #{$0} [options]"
15
+ end
16
+
17
+ it 'sets up -h, --help' do
18
+ @parser.base.list[-2].short[0].should eq '-h'
19
+ @parser.base.list[-2].long[0].should eq '--help'
20
+ end
21
+
22
+ it 'sets up -V, --version' do
23
+ @parser.base.list[-1].short[0].should eq '-V'
24
+ @parser.base.list[-1].long[0].should eq '--version'
25
+ end
26
+ end
27
+
28
+ describe '.argument' do
29
+ it 'modifies banner' do
30
+ @parser.argument('test')
31
+ @parser.banner.should eq "Usage: #{$0} [options] <test>"
32
+ end
33
+ end
34
+
35
+ describe '.parse!' do
36
+ it 'parses arguments' do
37
+ @parser.argument(:test)
38
+ @parser.parse!(['testvalue']).should eq Hash[:test => 'testvalue']
39
+ end
40
+
41
+ it 'parses switches' do
42
+ @parser.switch(:test, '-t', '--test', 'Test switch')
43
+ @parser.parse!(['-t']).should eq Hash[:test => true]
44
+ end
45
+
46
+ it 'parses switches with value' do
47
+ @parser.switch(:test, '-t', '--test VALUE', 'Test switch')
48
+ @parser.parse!(['-t', 'testvalue']).should eq Hash[:test => 'testvalue']
49
+ end
50
+
51
+ it 'modifies input array' do
52
+ args = ['-t', 'testvalue', 'argument']
53
+ @parser.argument(:arg)
54
+ @parser.switch(:test, '-t', '--test VALUE', 'Test switch')
55
+ @parser.parse!(args)
56
+ args.should eq []
57
+ end
58
+
59
+ it 'raises ArgumentError on invalid switch' do
60
+ lambda { @parser.parse!(['-x']) }.should raise_error ArgumentError
61
+ end
62
+
63
+ it 'raises ArgumentError on too few arguments' do
64
+ @parser.argument(:test)
65
+ lambda { @parser.parse!([]) }.should raise_error ArgumentError
66
+ end
67
+
68
+ it 'raises ArgumentError on too many arguments' do
69
+ @parser.argument(:test)
70
+ lambda { @parser.parse!(['x', 'y']) }.should raise_error ArgumentError
71
+ end
72
+ end
73
+
74
+ describe '.switch' do
75
+ it 'adds a switch' do
76
+ @parser.switch('name', '-t', '--test TEST',) do |value|
77
+ end
78
+
79
+ @parser.top.list[-1].short[0].should eq '-t'
80
+ @parser.top.list[-1].long[0].should eq '--test'
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nagi::Plugin do
4
+ before(:each) do
5
+ @plugin = Nagi::Plugin.new
6
+ end
7
+
8
+ describe '#optionparser' do
9
+ it 'contains OptionParser' do
10
+ @plugin.optionparser.class.should eq Nagi::OptionParser
11
+ end
12
+ end
13
+
14
+ describe '#name' do
15
+ it 'sets name' do
16
+ @plugin.name = 'name'
17
+ @plugin.name.should eq 'name'
18
+ end
19
+
20
+ it 'sets optionparser.program_name' do
21
+ @plugin.name = 'name'
22
+ @plugin.optionparser.program_name.should eq 'name'
23
+ end
24
+ end
25
+
26
+ describe '#prefix' do
27
+ it 'sets prefix' do
28
+ @plugin.prefix = 'prefix'
29
+ @plugin.prefix.should eq 'prefix'
30
+ end
31
+ end
32
+
33
+ describe '#version' do
34
+ it 'sets version' do
35
+ @plugin.version = 'version'
36
+ @plugin.version.should eq 'version'
37
+ end
38
+
39
+ it 'sets optionparser.version' do
40
+ @plugin.version = 'version'
41
+ @plugin.optionparser.version.should eq 'version'
42
+ end
43
+ end
44
+
45
+ describe '.check' do
46
+ it 'raises NotImplementedError' do
47
+ lambda { @plugin.check({}) }.should raise_error NotImplementedError
48
+ end
49
+ end
50
+
51
+ describe '.run' do
52
+ it 'passes parsed options to check' do
53
+ class << @plugin
54
+ def check(options)
55
+ $nagi = options
56
+ end
57
+ end
58
+ @plugin.optionparser.argument(:arg)
59
+ @plugin.optionparser.switch(:switch, '-s', '--switch VALUE', 'Test switch')
60
+ @plugin.run(['-s', 'value', 'argument'])
61
+ $nagi.should eq Hash[:arg => 'argument', :switch => 'value']
62
+ end
63
+
64
+ it 'returns check status' do
65
+ class << @plugin
66
+ def check(options)
67
+ return Nagi::Status::OK.new('ok')
68
+ end
69
+ end
70
+ @plugin.run([]).class.should eq Nagi::Status::OK
71
+ end
72
+
73
+ it 'returns unknown status on check exception' do
74
+ class << @plugin
75
+ def check(options)
76
+ raise StandardError.new('error')
77
+ end
78
+ end
79
+ @plugin.run([]).class.should eq Nagi::Status::Unknown
80
+ end
81
+
82
+ it 'doesnt catch errors from optionparser' do
83
+ lambda { @plugin.run(['--invalid']) }.should raise_error ArgumentError
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nagi::Status::Status do
4
+ before(:each) do
5
+ @status = Nagi::Status::Status.new(0, 'name', 'message')
6
+ end
7
+
8
+ describe '.code' do
9
+ it 'contains status code' do
10
+ @status.code.should eq 0
11
+ end
12
+
13
+ it 'is read-only' do
14
+ lambda { @status.code = 1 }.should raise_error NoMethodError
15
+ end
16
+ end
17
+
18
+ describe '.message' do
19
+ it 'contains message' do
20
+ @status.message.should eq 'message'
21
+ end
22
+
23
+ it 'is writable' do
24
+ @status.message = 'test'
25
+ @status.message.should eq 'test'
26
+ end
27
+ end
28
+
29
+ describe '.name' do
30
+ it 'contains name' do
31
+ @status.name.should eq 'name'
32
+ end
33
+
34
+ it 'is read-only' do
35
+ lambda { @status.name = 'test' }.should raise_error NoMethodError
36
+ end
37
+ end
38
+
39
+ describe '.to_s' do
40
+ it 'formats the status' do
41
+ @status.to_s.should eq 'NAME: message'
42
+ end
43
+ end
44
+ end
45
+
46
+ describe Nagi::Status::Critical do
47
+ before(:each) do
48
+ @status = Nagi::Status::Critical.new('message')
49
+ end
50
+
51
+ describe '.code' do
52
+ it 'is 2' do
53
+ @status.code.should eq 2
54
+ end
55
+ end
56
+
57
+ describe '.message' do
58
+ it 'contains message' do
59
+ @status.message.should eq 'message'
60
+ end
61
+ end
62
+
63
+ describe '.name' do
64
+ it 'is Critical' do
65
+ @status.name.should eq 'Critical'
66
+ end
67
+ end
68
+ end
69
+
70
+ describe Nagi::Status::OK do
71
+ before(:each) do
72
+ @status = Nagi::Status::OK.new('message')
73
+ end
74
+
75
+ describe '.code' do
76
+ it 'is 0' do
77
+ @status.code.should eq 0
78
+ end
79
+ end
80
+
81
+ describe '.message' do
82
+ it 'contains message' do
83
+ @status.message.should eq 'message'
84
+ end
85
+ end
86
+
87
+ describe '.name' do
88
+ it 'is OK' do
89
+ @status.name.should eq 'OK'
90
+ end
91
+ end
92
+ end
93
+
94
+ describe Nagi::Status::Unknown do
95
+ before(:each) do
96
+ @status = Nagi::Status::Unknown.new('message')
97
+ end
98
+
99
+ describe '.code' do
100
+ it 'is 3' do
101
+ @status.code.should eq 3
102
+ end
103
+ end
104
+
105
+ describe '.message' do
106
+ it 'contains message' do
107
+ @status.message.should eq 'message'
108
+ end
109
+ end
110
+
111
+ describe '.name' do
112
+ it 'is Unknown' do
113
+ @status.name.should eq 'Unknown'
114
+ end
115
+ end
116
+ end
117
+
118
+ describe Nagi::Status::Warning do
119
+ before(:each) do
120
+ @status = Nagi::Status::Warning.new('message')
121
+ end
122
+
123
+ describe '.code' do
124
+ it 'is 1' do
125
+ @status.code.should eq 1
126
+ end
127
+ end
128
+
129
+ describe '.message' do
130
+ it 'contains message' do
131
+ @status.message.should eq 'message'
132
+ end
133
+ end
134
+
135
+ describe '.name' do
136
+ it 'is Warning' do
137
+ @status.name.should eq 'Warning'
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Nagi::Utility::execute' do
4
+ it 'raises exception on non-zero status' do
5
+ lambda { Nagi::Utility.execute('exit 1') }.should raise_error StandardError
6
+ end
7
+
8
+ it 'raises exception on non-zero status in pipelines' do
9
+ lambda { Nagi::Utility.execute('false | true') }.should raise_error StandardError
10
+ end
11
+
12
+ it 'returns command stdout' do
13
+ Nagi::Utility.execute('echo test').should eq 'test'
14
+ end
15
+
16
+ it 'returns command stderr' do
17
+ Nagi::Utility.execute('echo test >&2').should eq 'test'
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ $:.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'nagi'
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nagi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Erik Grinaker
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70154071720240 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70154071720240
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70154071719820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70154071719820
36
+ description: A DSL for writing Nagios plugins
37
+ email:
38
+ - erik@bengler.no
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - README.md
46
+ - Rakefile
47
+ - lib/nagi.rb
48
+ - lib/nagi/dsl.rb
49
+ - lib/nagi/optionparser.rb
50
+ - lib/nagi/plugin.rb
51
+ - lib/nagi/status.rb
52
+ - lib/nagi/utility.rb
53
+ - lib/nagi/version.rb
54
+ - nagi.gemspec
55
+ - spec/nagi/dsl_spec.rb
56
+ - spec/nagi/optionparser_spec.rb
57
+ - spec/nagi/plugin_spec.rb
58
+ - spec/nagi/status_spec.rb
59
+ - spec/nagi/utility_spec.rb
60
+ - spec/spec_helper.rb
61
+ homepage: http://github.com/bengler/nagi
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 1.8.11
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: A DSL for writing Nagios plugins
85
+ test_files:
86
+ - spec/nagi/dsl_spec.rb
87
+ - spec/nagi/optionparser_spec.rb
88
+ - spec/nagi/plugin_spec.rb
89
+ - spec/nagi/status_spec.rb
90
+ - spec/nagi/utility_spec.rb
91
+ - spec/spec_helper.rb