nagios-promoo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 37eb72c6a72643b3f6cbd46813aefd70cc7ba0dc
4
+ data.tar.gz: 15040ffff6884f1a2520cdaae33bcbcbe0a6bfd8
5
+ SHA512:
6
+ metadata.gz: 21dc3378b775714ae7821dd33662361502ef80e65a1e3fd961b3d57298cb259839ba0fb9b818fd4a5e70a43b4c4e7f04cc98ce1677971e9856209ba1f73cd3b3
7
+ data.tar.gz: 23a0400d4f4f12aa26f429da56bb1effe143eec86defbd87aa5c147a345490b6c5d42a7db4ae03154eae290488527055ea7c224cead96def6de38e5276e9cc29
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nagios-promoo.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,17 @@
1
+ The work represented by this source file was partially or entirely funded
2
+ by the EGI-InSPIRE project through the European Commission's 7th Framework
3
+ Programme (contract # INFSO-RI-261323)
4
+
5
+ Copyright (c) 2012-2016 CESNET
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.
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # Nagios Probes for Monitoring OpenNebula and OCCI
2
+
3
+ ## Installation
4
+
5
+ $ gem install nagios-promoo
6
+
7
+ ## Usage
8
+
9
+ $ nagios-promoo help
10
+
11
+ ## Contributing
12
+
13
+ 1. Fork it ( https://github.com/EGI-FCTF/nagios-promoo/fork )
14
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
15
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
16
+ 4. Push to the branch (`git push origin my-new-feature`)
17
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/nagios-promoo ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ###########################################################################
4
+ # Copyright (c) 2012-2016 CESNET
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ ###########################################################################
18
+
19
+ require 'nagios/promoo'
20
+
21
+ Nagios::Promoo::Master.start(ARGV)
@@ -0,0 +1,14 @@
1
+ # Global deps
2
+ require 'thor'
3
+ require 'timeout'
4
+ require 'multi_xml'
5
+ require 'multi_json'
6
+ require 'httparty'
7
+
8
+ # Define modules
9
+ module Nagios; end
10
+ module Nagios::Promoo; end
11
+
12
+ # Include necessary files
13
+ require "nagios/promoo/version"
14
+ require "nagios/promoo/master"
@@ -0,0 +1,29 @@
1
+ # Deps
2
+ ## None
3
+
4
+ # Include available probe modules
5
+ Dir.glob(File.join(File.dirname(__FILE__), '*', 'master.rb')) { |mod| require mod.chomp('.rb') }
6
+
7
+ class Nagios::Promoo::Master < ::Thor
8
+ class_option :debug, type: :boolean, desc: 'Turn on debugging mode', default: false
9
+ class_option :ca_path, type: :string, desc: 'Path to a directory with CA certificates', default: '/etc/grid-security/certificates'
10
+ class_option :ca_file, type: :string, desc: 'Path to a file with CA certificates'
11
+ class_option :insecure, type: :boolean, desc: 'Turn on insecure mode (without SSL client validation)', default: false
12
+ class_option :timeout, type: :numeric, desc: 'Timeout for all internal connections and other processes (in seconds)', default: 720
13
+
14
+ desc 'opennebula PROBE', 'Run the given probe for OpenNebula'
15
+ subcommand 'opennebula', Nagios::Promoo::Opennebula::Master
16
+
17
+ desc 'occi PROBE', 'Run the given probe for OCCI'
18
+ subcommand 'occi', Nagios::Promoo::Occi::Master
19
+
20
+ desc 'version', 'Print PROMOO version'
21
+ def version
22
+ puts Nagios::Promoo::VERSION
23
+ end
24
+
25
+ class << self
26
+ # Force thor to exit with a non-zero return code on failure
27
+ def exit_on_failure?; true; end
28
+ end
29
+ end
File without changes
@@ -0,0 +1,45 @@
1
+ # Deps
2
+ require 'occi-api'
3
+
4
+ # Internal deps
5
+ require File.join(File.dirname(__FILE__), 'version')
6
+
7
+ # Define modules
8
+ module Nagios::Promoo::Occi; end
9
+ module Nagios::Promoo::Occi::Probes; end
10
+ Dir.glob(File.join(File.dirname(__FILE__), 'probes', '*.rb')) { |probe| require probe.chomp('.rb') }
11
+
12
+ class Nagios::Promoo::Occi::Master < ::Thor
13
+ class << self
14
+ # Hack to override the help message produced by Thor.
15
+ # https://github.com/wycats/thor/issues/261#issuecomment-16880836
16
+ def banner(command, namespace = nil, subcommand = nil)
17
+ "#{basename} occi #{command.usage}"
18
+ end
19
+
20
+ def available_probes
21
+ Nagios::Promoo::Occi::Probes.constants.collect { |probe| Nagios::Promoo::Occi::Probes.const_get(probe) }.reject { |probe| !probe.runnable? }
22
+ end
23
+ end
24
+
25
+ class_option :endpoint, type: :string, desc: 'OCCI-enabled endpoint', default: 'http://localhost:3000/'
26
+ class_option :auth, type: :string, desc: 'Authentication mechanism', enum: %w(x509-voms), default: 'x509-voms'
27
+ class_option :token, type: :string, desc: 'Authentication token', default: "file:///tmp/x509up_u#{`id -u`.strip}"
28
+
29
+ available_probes.each do |probe|
30
+ desc *probe.description
31
+ probe.options.each do |opt|
32
+ option opt.first, opt.last
33
+ end
34
+ class_eval %Q^
35
+ def #{probe.declaration}(*args)
36
+ #{probe}.new.run(options, args)
37
+ end
38
+ ^
39
+ end
40
+
41
+ desc 'version', 'Print version of the OCCI probe set'
42
+ def version
43
+ puts Nagios::Promoo::Occi::VERSION
44
+ end
45
+ end
File without changes
@@ -0,0 +1,23 @@
1
+ class Nagios::Promoo::Occi::Probes::BaseProbe
2
+ class << self
3
+ def runnable?; false; end
4
+ end
5
+
6
+ def client(options)
7
+ @client ||= Occi::Api::Client::ClientHttp.new({
8
+ :endpoint => options[:endpoint],
9
+ :auth => {
10
+ :type => options[:auth].gsub('-voms', ''),
11
+ :user_cert => options[:token].gsub('file://', ''),
12
+ :user_cert_password => nil,
13
+ :ca_path => options[:ca_path],
14
+ :voms => options[:auth] == 'x509-voms' ? true : false
15
+ },
16
+ :log => {
17
+ :level => options[:debug] ? Occi::Api::Log::DEBUG : Occi::Api::Log::ERROR,
18
+ :logger => nil,
19
+ :out => '/dev/null',
20
+ }
21
+ })
22
+ end
23
+ end
@@ -0,0 +1,167 @@
1
+ # Internal deps
2
+ require File.join(File.dirname(__FILE__), 'base_probe')
3
+
4
+ class Nagios::Promoo::Occi::Probes::ComputeProbe < Nagios::Promoo::Occi::Probes::BaseProbe
5
+ class << self
6
+ def description
7
+ ['compute', 'Run a probe creating a compute instance via OCCI']
8
+ end
9
+
10
+ def options
11
+ [
12
+ [:mpuri, { type: :string, required: true, desc: 'AppDB MPURI referencing a virtual appliance' }],
13
+ [:cache_expiration, { type: :numeric, default: 7200, desc: 'AppDB cache expiration (in seconds)' }],
14
+ [:compute_timeout, { type: :numeric, default: 359, desc: 'Timeout for compute instantiation (in seconds)' }],
15
+ [:appdb_timeout, { type: :numeric, default: 359, desc: 'Timeout for AppDB queries (in seconds)' }],
16
+ [:cleanup, { type: :boolean, default: true, desc: 'Perform clean-up before launching a new instance' }],
17
+ ]
18
+ end
19
+
20
+ def declaration
21
+ "compute"
22
+ end
23
+
24
+ def runnable?; true; end
25
+ end
26
+
27
+ COMPUTE_NAME_PREFIX = "sam-nagios-promoo"
28
+ CACHE_DIR = '/tmp/nagios-promoo_cache'
29
+ APPDB_PROXY_URL = 'https://appdb.egi.eu/api/proxy'
30
+ APPDB_REQUEST_FORM = 'version=1.0&resource=broker&data=%3Cappdb%3Abroker%20xmlns%3Axs%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20xmlns%3Aappdb%3D%22http%3A%2F%2Fappdb.egi.eu%2Fapi%2F1.0%2Fappdb%22%3E%3Cappdb%3Arequest%20id%3D%22vaproviders%22%20method%3D%22GET%22%20resource%3D%22va_providers%22%3E%3Cappdb%3Aparam%20name%3D%22listmode%22%3Edetails%3C%2Fappdb%3Aparam%3E%3C%2Fappdb%3Arequest%3E%3C%2Fappdb%3Abroker%3E'
31
+
32
+ def run(options, args = [])
33
+ fail "Timeout (#{options[:timeout]}) must be higher than compute-timeout (#{options[:compute_timeout]}) "\
34
+ "+ appdb-timeout (#{options[:appdb_timeout]})" if options[:timeout] <= (options[:compute_timeout] + options[:appdb_timeout])
35
+
36
+ link = begin
37
+ Timeout::timeout(options[:timeout]) { compute_create(*appdb_information(options), options) }
38
+ rescue Timeout::Error => ex
39
+ puts "COMPUTE CRITICAL - Probe execution timed out [#{options[:timeout]}s]"
40
+ exit 2
41
+ end
42
+
43
+ puts "COMPUTE OK - Instance #{link.inspect} created & cleaned up"
44
+ end
45
+
46
+ private
47
+
48
+ def compute_create(os_tpl, resource_tpl, options)
49
+ link = nil
50
+
51
+ begin
52
+ 2.times { client(options).delete('compute') } if options[:cleanup]
53
+ compute = client(options).get_resource('compute')
54
+ compute.title = compute.hostname = "#{COMPUTE_NAME_PREFIX}-#{Time.now.to_i}"
55
+
56
+ compute.mixins << client(options).get_mixin(os_tpl, 'os_tpl', true)
57
+ compute.mixins << client(options).get_mixin(resource_tpl, 'resource_tpl', true)
58
+
59
+ link = client(options).create(compute)
60
+ wait4compute(link, options)
61
+ rescue => ex
62
+ puts "COMPUTE CRITICAL - #{ex.message}"
63
+ puts ex.backtrace if options[:debug]
64
+ exit 2
65
+ ensure
66
+ begin
67
+ client(options).delete(link) unless link.blank?
68
+ rescue => ex
69
+ ## ignoring
70
+ end
71
+ end
72
+
73
+ link
74
+ end
75
+
76
+ def wait4compute(link, options)
77
+ state = 'inactive'
78
+
79
+ begin
80
+ Timeout::timeout(options[:compute_timeout]) {
81
+ while state != 'active' do
82
+ state = client(options).describe(link).first.state
83
+ fail 'Failed to deploy an instance (resulting OCCI state was "error")' if state == 'error'
84
+ sleep 5
85
+ end
86
+ }
87
+ rescue Timeout::Error => ex
88
+ puts "COMPUTE WARNING - Execution timed out while waiting for the instance to become active [#{options[:compute_timeout]}s]"
89
+ exit 1
90
+ end
91
+ end
92
+
93
+ def appdb_information(options)
94
+ begin
95
+ Timeout::timeout(options[:appdb_timeout]) {
96
+ [appdb_appliance(options), appdb_smallest_size(options)]
97
+ }
98
+ rescue => ex
99
+ puts "COMPUTE UNKNOWN - #{ex.message}"
100
+ puts ex.backtrace if options[:debug]
101
+ exit 3
102
+ end
103
+ end
104
+
105
+ def appdb_appliance(options)
106
+ appliance = appdb_provider(options)['image'].select do |image|
107
+ image['mp_uri'] && (normalize_mpuri(image['mp_uri']) == normalize_mpuri(options[:mpuri]))
108
+ end.first
109
+ fail "No such appliance is published in AppDB" if appliance.blank?
110
+
111
+ appliance['va_provider_image_id'].split('#').last
112
+ end
113
+
114
+ def appdb_smallest_size(options)
115
+ sizes = []
116
+ appdb_provider(options)['template'].each do |template|
117
+ sizes << [
118
+ template['resource_name'].split('#').last,
119
+ template['main_memory_size'].to_i + template['physical_cpus'].to_i
120
+ ]
121
+ end
122
+ fail "No appliance sizes available in AppDB" if sizes.blank?
123
+ sizes.sort! { |x,y| x.last <=> y.last }
124
+
125
+ sizes.first.first
126
+ end
127
+
128
+ def appdb_provider(options)
129
+ return @provider if @provider
130
+
131
+ parsed_response = cache_fetch('appdb-sites', options[:cache_expiration]) do
132
+ response = HTTParty.post(APPDB_PROXY_URL, { :body => APPDB_REQUEST_FORM })
133
+ fail "Could not get appliance"\
134
+ "details from AppDB [#{response.code}]" unless response.success?
135
+ response.parsed_response
136
+ end
137
+
138
+ @provider = parsed_response['broker']['reply']['appdb']['provider'].select do |prov|
139
+ prov['endpoint_url'] && (prov['endpoint_url'].chomp('/') == options[:endpoint].chomp('/'))
140
+ end.first
141
+ fail "Could not locate site by endpoint #{options[:endpoint]} in AppDB" unless @provider
142
+
143
+ @provider
144
+ end
145
+
146
+ def cache_fetch(key, expiration = 3600)
147
+ fail 'You have to provide a block!' unless block_given?
148
+ FileUtils.mkdir_p CACHE_DIR
149
+ filename = File.join(CACHE_DIR, key)
150
+
151
+ if cache_valid?(filename, expiration)
152
+ File.open(filename, 'r') { |file| JSON.parse file.read }
153
+ else
154
+ data = yield
155
+ File.open(filename, 'w') { |file| file.write JSON.pretty_generate(data) }
156
+ data
157
+ end
158
+ end
159
+
160
+ def cache_valid?(filename, expiration)
161
+ File.exists?(filename) && ((Time.now - expiration) < File.stat(filename).mtime)
162
+ end
163
+
164
+ def normalize_mpuri(mpuri)
165
+ mpuri.gsub(/\/+$/, '').gsub(/:\d+$/, '')
166
+ end
167
+ end
@@ -0,0 +1,56 @@
1
+ # Internal deps
2
+ require File.join(File.dirname(__FILE__), 'base_probe')
3
+
4
+ class Nagios::Promoo::Occi::Probes::KindsProbe < Nagios::Promoo::Occi::Probes::BaseProbe
5
+ class << self
6
+ def description
7
+ ['kinds', 'Run a probe checking for mandatory OCCI kind definitions']
8
+ end
9
+
10
+ def options
11
+ [
12
+ [:kinds, { type: :string, enum: %w(core infra all), default: 'all', desc: 'Collection of mandatory kinds to check' }],
13
+ [:optional, { type: :array, default: [], desc: 'Identifiers of optional kinds (optional by force)' }]
14
+ ]
15
+ end
16
+
17
+ def declaration
18
+ "kinds"
19
+ end
20
+
21
+ def runnable?; true; end
22
+ end
23
+
24
+ CORE_KINDS = %w(
25
+ http://schemas.ogf.org/occi/core#entity
26
+ http://schemas.ogf.org/occi/core#resource
27
+ http://schemas.ogf.org/occi/core#link
28
+ )
29
+
30
+ INFRA_KINDS = %w(
31
+ http://schemas.ogf.org/occi/infrastructure#compute
32
+ http://schemas.ogf.org/occi/infrastructure#storage
33
+ http://schemas.ogf.org/occi/infrastructure#network
34
+ http://schemas.ogf.org/occi/infrastructure#storagelink
35
+ http://schemas.ogf.org/occi/infrastructure#networkinterface
36
+ )
37
+
38
+ def run(options, args = [])
39
+ kinds = []
40
+ kinds += CORE_KINDS if %w(core all).include?(options[:kinds])
41
+ kinds += INFRA_KINDS if %w(infra all).include?(options[:kinds])
42
+ kinds -= options[:optional] if options[:optional]
43
+
44
+ begin
45
+ Timeout::timeout(options[:timeout]) {
46
+ kinds.each { |kind| fail "#{kind.inspect} is missing" unless client(options).model.get_by_id(kind, true) }
47
+ }
48
+ rescue => ex
49
+ puts "KINDS CRITICAL - #{ex.message}"
50
+ puts ex.backtrace if options[:debug]
51
+ exit 2
52
+ end
53
+
54
+ puts 'KINDS OK - All specified OCCI kinds were found'
55
+ end
56
+ end
@@ -0,0 +1,52 @@
1
+ # Internal deps
2
+ require File.join(File.dirname(__FILE__), 'base_probe')
3
+
4
+ class Nagios::Promoo::Occi::Probes::MixinsProbe < Nagios::Promoo::Occi::Probes::BaseProbe
5
+ class << self
6
+ def description
7
+ ['mixins', 'Run a probe checking for mandatory OCCI mixin definitions']
8
+ end
9
+
10
+ def options
11
+ [
12
+ [:mixins, { type: :string, enum: %w(infra context all), default: 'all', desc: 'Collection of mandatory mixins to check' }],
13
+ [:optional, { type: :array, default: [], desc: 'Identifiers of optional mixins (optional by force)' }]
14
+ ]
15
+ end
16
+
17
+ def declaration
18
+ "mixins"
19
+ end
20
+
21
+ def runnable?; true; end
22
+ end
23
+
24
+ INFRA_MIXINS = %w(
25
+ http://schemas.ogf.org/occi/infrastructure#os_tpl
26
+ http://schemas.ogf.org/occi/infrastructure#resource_tpl
27
+ )
28
+
29
+ CONTEXT_MIXINS = %w(
30
+ http://schemas.openstack.org/instance/credentials#public_key
31
+ http://schemas.openstack.org/compute/instance#user_data
32
+ )
33
+
34
+ def run(options, args = [])
35
+ mixins = []
36
+ mixins += INFRA_MIXINS if %w(infra all).include?(options[:mixins])
37
+ mixins += CONTEXT_MIXINS if %w(context all).include?(options[:mixins])
38
+ mixins -= options[:optional] if options[:optional]
39
+
40
+ begin
41
+ Timeout::timeout(options[:timeout]) {
42
+ mixins.each { |mixin| fail "#{mixin.inspect} is missing" unless client(options).model.get_by_id(mixin, true) }
43
+ }
44
+ rescue => ex
45
+ puts "MIXINS CRITICAL - #{ex.message}"
46
+ puts ex.backtrace if options[:debug]
47
+ exit 2
48
+ end
49
+
50
+ puts 'MIXINS OK - All specified OCCI mixins were found'
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ module Nagios
2
+ module Promoo
3
+ module Occi
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
File without changes
@@ -0,0 +1,44 @@
1
+ # Deps
2
+ require 'opennebula'
3
+
4
+ # Internal deps
5
+ require File.join(File.dirname(__FILE__), 'version')
6
+
7
+ # Define modules
8
+ module Nagios::Promoo::Opennebula; end
9
+ module Nagios::Promoo::Opennebula::Probes; end
10
+ Dir.glob(File.join(File.dirname(__FILE__), 'probes', '*.rb')) { |probe| require probe.chomp('.rb') }
11
+
12
+ class Nagios::Promoo::Opennebula::Master < ::Thor
13
+ class << self
14
+ # Hack to override the help message produced by Thor.
15
+ # https://github.com/wycats/thor/issues/261#issuecomment-16880836
16
+ def banner(command, namespace = nil, subcommand = nil)
17
+ "#{basename} opennebula #{command.usage}"
18
+ end
19
+
20
+ def available_probes
21
+ Nagios::Promoo::Opennebula::Probes.constants.collect { |probe| Nagios::Promoo::Opennebula::Probes.const_get(probe) }.reject { |probe| !probe.runnable? }
22
+ end
23
+ end
24
+
25
+ class_option :endpoint, type: :string, desc: 'OpenNebula XML-RPC endpoint', default: 'http://localhost:2633/RPC2'
26
+ class_option :token, type: :string, desc: 'Authentication token', default: "file://#{ENV['HOME']}/.one/one_auth"
27
+
28
+ available_probes.each do |probe|
29
+ desc *probe.description
30
+ probe.options.each do |opt|
31
+ option opt.first, opt.last
32
+ end
33
+ class_eval %Q^
34
+ def #{probe.declaration}(*args)
35
+ #{probe}.new.run(options, args)
36
+ end
37
+ ^
38
+ end
39
+
40
+ desc 'version', 'Print version of the OpenNebula probe set'
41
+ def version
42
+ puts Nagios::Promoo::Opennebula::VERSION
43
+ end
44
+ end
File without changes
@@ -0,0 +1,12 @@
1
+ class Nagios::Promoo::Opennebula::Probes::BaseProbe
2
+ class << self
3
+ def runnable?; false; end
4
+ end
5
+
6
+ def client(options)
7
+ return @client if @client
8
+
9
+ token = options[:token].start_with?('file://') ? File.read(options[:token].gsub('file://', '')) : options[:token]
10
+ @client = OpenNebula::Client.new("#{token}", options[:endpoint])
11
+ end
12
+ end
@@ -0,0 +1,108 @@
1
+ # Internal deps
2
+ require File.join(File.dirname(__FILE__), 'base_probe')
3
+
4
+ class Nagios::Promoo::Opennebula::Probes::VirtualMachineProbe < Nagios::Promoo::Opennebula::Probes::BaseProbe
5
+ class << self
6
+ def description
7
+ ['virtual-machine', 'Run a probe instantiating a test instance in OpenNebula']
8
+ end
9
+
10
+ def options
11
+ [
12
+ [:template, { type: :string, default: 'monitoring', desc: 'Name referencing a template used for monitoring purposes' }],
13
+ [:vm_timeout, { type: :numeric, default: 180, desc: 'Timeout for VM instantiation (in seconds)' }],
14
+ [:cleanup, { type: :boolean, default: true, desc: 'Perform clean-up before launching a new instance' }],
15
+ ]
16
+ end
17
+
18
+ def declaration
19
+ "virtual_machine"
20
+ end
21
+
22
+ def runnable?; true; end
23
+ end
24
+
25
+ VM_NAME_PREFIX = "nagios-promoo"
26
+
27
+ def run(options, args = [])
28
+ fail "Timeout (#{options[:timeout]}) must be higher than "\
29
+ "vm-timeout (#{options[:vm_timeout]}) " if options[:timeout] <= options[:vm_timeout]
30
+
31
+ vm = nil
32
+ begin
33
+ Timeout::timeout(options[:timeout]) {
34
+ cleanup(options) if options[:cleanup]
35
+ vm = create(options)
36
+ wait4running(options, vm)
37
+ }
38
+ rescue => ex
39
+ puts "VirtualMachine CRITICAL - #{ex.message}"
40
+ puts ex.backtrace if options[:debug]
41
+ exit 2
42
+ ensure
43
+ begin
44
+ cleanup(options, vm) unless vm.blank?
45
+ rescue => ex
46
+ ## ignoring
47
+ end
48
+ end
49
+
50
+ puts "VirtualMachine OK - Instance #{vm.id.inspect} of template "\
51
+ "#{options[:template].inspect} successfully created & cleaned up"
52
+ end
53
+
54
+ private
55
+
56
+ def cleanup(options, vm = nil)
57
+ (vm && vm.id) ? shutdown_or_delete(vm) : search_and_destroy(options)
58
+ end
59
+
60
+ def create(options)
61
+ template_pool = OpenNebula::TemplatePool.new(client(options))
62
+ rc = template_pool.info_all
63
+ fail rc.message if OpenNebula.is_error?(rc)
64
+
65
+ template = template_pool.select { |tpl| tpl.name == options[:template] }.first
66
+ fail "Template #{options[:template].inspect} could not be found" unless template
67
+ vm_id = template.instantiate("#{VM_NAME_PREFIX}-#{Time.now.to_i}")
68
+ fail vm_id.message if OpenNebula.is_error?(vm_id)
69
+
70
+ vm = OpenNebula::VirtualMachine.new(OpenNebula::VirtualMachine.build_xml(vm_id), client(options))
71
+ rc = vm.info
72
+ fail rc.message if OpenNebula.is_error?(rc)
73
+
74
+ vm
75
+ end
76
+
77
+ def wait4running(options, vm)
78
+ begin
79
+ Timeout::timeout(options[:vm_timeout]) {
80
+ while vm.lcm_state_str != 'RUNNING' do
81
+ fail 'Instance deployment failed (resulting state is "FAILED")' if vm.state_str == 'FAILED'
82
+ rc = vm.info
83
+ fail rc.message if OpenNebula.is_error?(rc)
84
+ end
85
+ }
86
+ rescue Timeout::Error => ex
87
+ puts "VirtualMachine WARNING - Execution timed out while waiting for "\
88
+ "the instance to become active [#{options[:vm_timeout]}s]"
89
+ exit 1
90
+ end
91
+ end
92
+
93
+ def search_and_destroy(options)
94
+ vm_pool = OpenNebula::VirtualMachinePool.new(client(options))
95
+ rc = vm_pool.info_mine
96
+ fail rc.message if OpenNebula.is_error?(rc)
97
+
98
+ candidates = vm_pool.select { |vm| vm.name.start_with?(VM_NAME_PREFIX) }
99
+ candidates.each { |vm| shutdown_or_delete(vm) }
100
+
101
+ candidates.count
102
+ end
103
+
104
+ def shutdown_or_delete(vm)
105
+ rc = (vm.lcm_state_str == 'RUNNING') ? vm.shutdown(true) : vm.delete
106
+ fail rc.message if OpenNebula.is_error?(rc)
107
+ end
108
+ end
@@ -0,0 +1,34 @@
1
+ # Internal deps
2
+ require File.join(File.dirname(__FILE__), 'base_probe')
3
+
4
+ class Nagios::Promoo::Opennebula::Probes::XmlrpcHealthProbe < Nagios::Promoo::Opennebula::Probes::BaseProbe
5
+ class << self
6
+ def description
7
+ ['xmlrpc-health', 'Run a probe checking OpenNebula\'s XML RPC service']
8
+ end
9
+
10
+ def options
11
+ []
12
+ end
13
+
14
+ def declaration
15
+ "xmlrpc_health"
16
+ end
17
+
18
+ def runnable?; true; end
19
+ end
20
+
21
+ def run(options, args = [])
22
+ rc = nil
23
+ begin
24
+ rc = Timeout::timeout(options[:timeout]) { client(options).get_version }
25
+ fail rc.message if OpenNebula.is_error?(rc)
26
+ rescue => ex
27
+ puts "XMLRPC CRITICAL - #{ex.message}"
28
+ puts ex.backtrace if options[:debug]
29
+ exit 2
30
+ end
31
+
32
+ puts "XMLRPC OK - OpenNebula #{rc} daemon is up and running"
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ module Nagios
2
+ module Promoo
3
+ module Opennebula
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module Nagios
2
+ module Promoo
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'nagios/promoo/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'nagios-promoo'
8
+ spec.version = Nagios::Promoo::VERSION
9
+ spec.authors = ['Boris Parak']
10
+ spec.email = ['parak@cesnet.cz']
11
+ spec.summary = %q{Nagios Probes for Monitoring OpenNebula and OCCI}
12
+ spec.description = %q{Nagios Probes for Monitoring OpenNebula and OCCI}
13
+ spec.homepage = 'https://github.com/EGI-FCTF/nagios-promoo'
14
+ spec.license = 'Apache License, Version 2.0'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_runtime_dependency 'occi-api', '~> 4.3'
22
+ spec.add_runtime_dependency 'opennebula', '~> 4.14'
23
+ spec.add_runtime_dependency 'thor'
24
+ spec.add_runtime_dependency 'yell'
25
+ spec.add_runtime_dependency 'activesupport'
26
+ spec.add_runtime_dependency 'httparty'
27
+ spec.add_runtime_dependency 'multi_xml'
28
+ spec.add_runtime_dependency 'multi_json'
29
+
30
+ spec.add_development_dependency 'bundler', '~> 1.7'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.0'
33
+ spec.add_development_dependency 'simplecov', '~> 0.9'
34
+ spec.add_development_dependency 'rubygems-tasks', '~> 0.2'
35
+ spec.add_development_dependency 'rubocop', '~> 0.32'
36
+ spec.add_development_dependency 'pry', '~> 0.10'
37
+
38
+ spec.required_ruby_version = '>= 1.9.3'
39
+ end
metadata ADDED
@@ -0,0 +1,280 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nagios-promoo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Boris Parak
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: occi-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: opennebula
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.14'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yell
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: httparty
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: multi_xml
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: multi_json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: bundler
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.7'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.7'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rake
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '10.0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '10.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.9'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.9'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubygems-tasks
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.2'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.2'
195
+ - !ruby/object:Gem::Dependency
196
+ name: rubocop
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.32'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.32'
209
+ - !ruby/object:Gem::Dependency
210
+ name: pry
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '0.10'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '0.10'
223
+ description: Nagios Probes for Monitoring OpenNebula and OCCI
224
+ email:
225
+ - parak@cesnet.cz
226
+ executables:
227
+ - nagios-promoo
228
+ extensions: []
229
+ extra_rdoc_files: []
230
+ files:
231
+ - ".gitignore"
232
+ - Gemfile
233
+ - LICENSE.txt
234
+ - README.md
235
+ - Rakefile
236
+ - bin/nagios-promoo
237
+ - lib/nagios/promoo.rb
238
+ - lib/nagios/promoo/master.rb
239
+ - lib/nagios/promoo/occi/.keep
240
+ - lib/nagios/promoo/occi/master.rb
241
+ - lib/nagios/promoo/occi/probes/.keep
242
+ - lib/nagios/promoo/occi/probes/base_probe.rb
243
+ - lib/nagios/promoo/occi/probes/compute_probe.rb
244
+ - lib/nagios/promoo/occi/probes/kinds_probe.rb
245
+ - lib/nagios/promoo/occi/probes/mixins_probe.rb
246
+ - lib/nagios/promoo/occi/version.rb
247
+ - lib/nagios/promoo/opennebula/.keep
248
+ - lib/nagios/promoo/opennebula/master.rb
249
+ - lib/nagios/promoo/opennebula/probes/.keep
250
+ - lib/nagios/promoo/opennebula/probes/base_probe.rb
251
+ - lib/nagios/promoo/opennebula/probes/virtual_machine_probe.rb
252
+ - lib/nagios/promoo/opennebula/probes/xmlrpc_health_probe.rb
253
+ - lib/nagios/promoo/opennebula/version.rb
254
+ - lib/nagios/promoo/version.rb
255
+ - nagios-promoo.gemspec
256
+ homepage: https://github.com/EGI-FCTF/nagios-promoo
257
+ licenses:
258
+ - Apache License, Version 2.0
259
+ metadata: {}
260
+ post_install_message:
261
+ rdoc_options: []
262
+ require_paths:
263
+ - lib
264
+ required_ruby_version: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: 1.9.3
269
+ required_rubygems_version: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - ">="
272
+ - !ruby/object:Gem::Version
273
+ version: '0'
274
+ requirements: []
275
+ rubyforge_project:
276
+ rubygems_version: 2.4.6
277
+ signing_key:
278
+ specification_version: 4
279
+ summary: Nagios Probes for Monitoring OpenNebula and OCCI
280
+ test_files: []