nagios-promoo 0.0.1

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.
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: []