cloudstack-nagios 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 +6 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +21 -0
- data/README.md +57 -0
- data/bin/cs-nagios +6 -0
- data/cloudstack-nagios.gemspec +28 -0
- data/lib/cloudstack-client/client.rb +136 -0
- data/lib/cloudstack-client/commands/account.rb +22 -0
- data/lib/cloudstack-client/commands/capacity.rb +19 -0
- data/lib/cloudstack-client/commands/cluster.rb +19 -0
- data/lib/cloudstack-client/commands/disk_offering.rb +49 -0
- data/lib/cloudstack-client/commands/domain.rb +22 -0
- data/lib/cloudstack-client/commands/host.rb +28 -0
- data/lib/cloudstack-client/commands/ip_address.rb +82 -0
- data/lib/cloudstack-client/commands/iso.rb +64 -0
- data/lib/cloudstack-client/commands/job.rb +29 -0
- data/lib/cloudstack-client/commands/load_balancer_rule.rb +61 -0
- data/lib/cloudstack-client/commands/network.rb +128 -0
- data/lib/cloudstack-client/commands/pod.rb +19 -0
- data/lib/cloudstack-client/commands/port_forwarding_rule.rb +49 -0
- data/lib/cloudstack-client/commands/project.rb +32 -0
- data/lib/cloudstack-client/commands/router.rb +89 -0
- data/lib/cloudstack-client/commands/server.rb +311 -0
- data/lib/cloudstack-client/commands/service_offering.rb +98 -0
- data/lib/cloudstack-client/commands/snapshot.rb +40 -0
- data/lib/cloudstack-client/commands/ssh_key_pair.rb +106 -0
- data/lib/cloudstack-client/commands/template.rb +60 -0
- data/lib/cloudstack-client/commands/user.rb +32 -0
- data/lib/cloudstack-client/commands/volume.rb +20 -0
- data/lib/cloudstack-client/commands/zone.rb +57 -0
- data/lib/cloudstack-client/version.rb +3 -0
- data/lib/cloudstack-nagios/base.rb +69 -0
- data/lib/cloudstack-nagios/cli.rb +100 -0
- data/lib/cloudstack-nagios/commands/nagios_config.rb +13 -0
- data/lib/cloudstack-nagios/helper.rb +17 -0
- data/lib/cloudstack-nagios/templates/cloudstack_routers_hosts.cfg.erb +36 -0
- data/lib/cloudstack-nagios/templates/cloudstack_routers_services.cfg.erb +35 -0
- data/lib/cloudstack-nagios/version.rb +3 -0
- data/lib/cloudstack_client.rb +2 -0
- data/lib/cloudstack_nagios.rb +4 -0
- metadata +155 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
module CloudstackClient
|
2
|
+
|
3
|
+
module Snapshot
|
4
|
+
|
5
|
+
##
|
6
|
+
# Lists snapshots.
|
7
|
+
|
8
|
+
def list_snapshots(args = {})
|
9
|
+
params = {
|
10
|
+
'command' => 'listSnapshots',
|
11
|
+
'isrecursive' => 'true'
|
12
|
+
}
|
13
|
+
params['name'] = args[:name] if args[:name]
|
14
|
+
|
15
|
+
if args[:project]
|
16
|
+
project = get_project(args[:project])
|
17
|
+
unless project
|
18
|
+
puts "Error: project #{args[:project]} not found."
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
params['projectid'] = project['id']
|
22
|
+
end
|
23
|
+
if args[:account]
|
24
|
+
account = list_accounts({name: args[:account]}).first
|
25
|
+
unless account
|
26
|
+
puts "Error: Account #{args[:account]} not found."
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
params['domainid'] = account["domainid"]
|
30
|
+
params['account'] = args[:account]
|
31
|
+
end
|
32
|
+
params['listall'] = args[:listall] if args[:listall]
|
33
|
+
|
34
|
+
json = send_request(params)
|
35
|
+
json['snapshot'] || []
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module CloudstackClient
|
2
|
+
|
3
|
+
module SshKeyPair
|
4
|
+
|
5
|
+
##
|
6
|
+
# Lists ssh key pairs.
|
7
|
+
#
|
8
|
+
|
9
|
+
def list_ssh_key_pairs(args = {})
|
10
|
+
params = {
|
11
|
+
'command' => 'listSSHKeyPairs',
|
12
|
+
'isrecursive' => true
|
13
|
+
}
|
14
|
+
params['listall'] = true if args[:listall]
|
15
|
+
params['name'] = args[:name] if args[:name]
|
16
|
+
|
17
|
+
if args[:project]
|
18
|
+
project = get_project(args[:project])
|
19
|
+
unless project
|
20
|
+
puts "Error: project #{args[:project]} not found."
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
params['projectid'] = project['id']
|
24
|
+
end
|
25
|
+
|
26
|
+
if args[:account]
|
27
|
+
account = list_accounts({name: args[:account]}).first
|
28
|
+
unless account
|
29
|
+
puts "Error: Account #{args[:account]} not found."
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
params['domainid'] = account["domainid"]
|
33
|
+
params['account'] = args[:account]
|
34
|
+
end
|
35
|
+
|
36
|
+
json = send_request(params)
|
37
|
+
json['sshkeypair'] || []
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Create ssh key pairs.
|
42
|
+
#
|
43
|
+
|
44
|
+
def create_ssh_key_pair(name, args = {})
|
45
|
+
params = {
|
46
|
+
'command' => 'createSSHKeyPair',
|
47
|
+
'name' => name
|
48
|
+
}
|
49
|
+
if args[:project]
|
50
|
+
project = get_project(args[:project])
|
51
|
+
unless project
|
52
|
+
puts "Error: project #{args[:project]} not found."
|
53
|
+
exit 1
|
54
|
+
end
|
55
|
+
params['projectid'] = project['id']
|
56
|
+
end
|
57
|
+
|
58
|
+
if args[:account]
|
59
|
+
account = list_accounts({name: args[:account]}).first
|
60
|
+
unless account
|
61
|
+
puts "Error: Account #{args[:account]} not found."
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
params['domainid'] = account["domainid"]
|
65
|
+
params['account'] = args[:account]
|
66
|
+
end
|
67
|
+
params['publickey'] = args[:public_key] if args[:public_key]
|
68
|
+
|
69
|
+
json = send_request(params)['keypair']
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Delete ssh key pairs.
|
74
|
+
#
|
75
|
+
|
76
|
+
def delete_ssh_key_pair(name, args = {})
|
77
|
+
params = {
|
78
|
+
'command' => 'deleteSSHKeyPair',
|
79
|
+
'name' => name
|
80
|
+
}
|
81
|
+
|
82
|
+
if args[:project]
|
83
|
+
project = get_project(args[:project])
|
84
|
+
unless project
|
85
|
+
puts "Error: project #{args[:project]} not found."
|
86
|
+
exit 1
|
87
|
+
end
|
88
|
+
params['projectid'] = project['id']
|
89
|
+
end
|
90
|
+
|
91
|
+
if args[:account]
|
92
|
+
account = list_accounts({name: args[:account]}).first
|
93
|
+
unless account
|
94
|
+
puts "Error: Account #{args[:account]} not found."
|
95
|
+
exit 1
|
96
|
+
end
|
97
|
+
params['domainid'] = account["domainid"]
|
98
|
+
params['account'] = args[:account]
|
99
|
+
end
|
100
|
+
|
101
|
+
json = send_request(params)
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module CloudstackClient
|
2
|
+
|
3
|
+
module Template
|
4
|
+
|
5
|
+
##
|
6
|
+
# Finds the template with the specified name.
|
7
|
+
|
8
|
+
def get_template(name)
|
9
|
+
|
10
|
+
# TODO: use name parameter
|
11
|
+
# listTemplates in CloudStack 2.2 doesn't seem to work
|
12
|
+
# when the name parameter is specified. When this is fixed,
|
13
|
+
# the name parameter should be added to the request.
|
14
|
+
params = {
|
15
|
+
'command' => 'listTemplates',
|
16
|
+
'templateFilter' => 'executable'
|
17
|
+
}
|
18
|
+
json = send_request(params)
|
19
|
+
|
20
|
+
templates = json['template']
|
21
|
+
if !templates then
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
|
25
|
+
templates.each { |t|
|
26
|
+
if t['name'] == name then
|
27
|
+
return t
|
28
|
+
end
|
29
|
+
}
|
30
|
+
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Lists all templates that match the specified filter.
|
36
|
+
#
|
37
|
+
# Allowable filter values are:
|
38
|
+
#
|
39
|
+
# * featured - templates that are featured and are public
|
40
|
+
# * self - templates that have been registered/created by the owner
|
41
|
+
# * self-executable - templates that have been registered/created by the owner that can be used to deploy a new VM
|
42
|
+
# * executable - all templates that can be used to deploy a new VM
|
43
|
+
# * community - templates that are public
|
44
|
+
|
45
|
+
def list_templates(args = {})
|
46
|
+
filter = args[:filter] || 'featured'
|
47
|
+
params = {
|
48
|
+
'command' => 'listTemplates',
|
49
|
+
'templateFilter' => filter
|
50
|
+
}
|
51
|
+
params['projectid'] = args[:project_id] if args[:project_id]
|
52
|
+
params['zoneid'] = args[:zone_id] if args[:zone_id]
|
53
|
+
|
54
|
+
json = send_request(params)
|
55
|
+
json['template'] || []
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module CloudstackClient
|
2
|
+
|
3
|
+
module User
|
4
|
+
|
5
|
+
##
|
6
|
+
# Lists users.
|
7
|
+
#
|
8
|
+
|
9
|
+
def list_users(args = {})
|
10
|
+
params = {
|
11
|
+
'command' => 'listUsers',
|
12
|
+
'isrecursive' => true
|
13
|
+
}
|
14
|
+
params['listall'] = true if args[:listall]
|
15
|
+
|
16
|
+
if args[:account]
|
17
|
+
account = list_accounts({name: args[:account]}).first
|
18
|
+
unless account
|
19
|
+
puts "Error: Account #{args[:account]} not found."
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
params['domainid'] = account["domainid"]
|
23
|
+
params['account'] = args[:account]
|
24
|
+
end
|
25
|
+
|
26
|
+
json = send_request(params)
|
27
|
+
json['user'] || []
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CloudstackClient
|
2
|
+
|
3
|
+
module Volume
|
4
|
+
|
5
|
+
##
|
6
|
+
# Lists all volumes.
|
7
|
+
|
8
|
+
def list_volumes(project_id = nil)
|
9
|
+
params = {
|
10
|
+
'command' => 'listVolumes',
|
11
|
+
'listall' => true,
|
12
|
+
}
|
13
|
+
params['projectid'] = project_id if project_id
|
14
|
+
json = send_request(params)
|
15
|
+
json['volume'] || []
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module CloudstackClient
|
2
|
+
|
3
|
+
module Zone
|
4
|
+
|
5
|
+
##
|
6
|
+
# Finds the zone with the specified name.
|
7
|
+
|
8
|
+
def get_zone(name)
|
9
|
+
params = {
|
10
|
+
'command' => 'listZones',
|
11
|
+
'available' => 'true'
|
12
|
+
}
|
13
|
+
json = send_request(params)
|
14
|
+
|
15
|
+
networks = json['zone']
|
16
|
+
return nil unless networks
|
17
|
+
|
18
|
+
networks.each { |z|
|
19
|
+
if z['name'] == name then
|
20
|
+
return z
|
21
|
+
end
|
22
|
+
}
|
23
|
+
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Finds the default zone for your account.
|
29
|
+
|
30
|
+
def get_default_zone
|
31
|
+
params = {
|
32
|
+
'command' => 'listZones',
|
33
|
+
'available' => 'true'
|
34
|
+
}
|
35
|
+
json = send_request(params)
|
36
|
+
|
37
|
+
zones = json['zone']
|
38
|
+
return nil unless zones
|
39
|
+
|
40
|
+
zones.first
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Lists all available zones.
|
45
|
+
|
46
|
+
def list_zones
|
47
|
+
params = {
|
48
|
+
'command' => 'listZones',
|
49
|
+
'available' => 'true'
|
50
|
+
}
|
51
|
+
json = send_request(params)
|
52
|
+
json['zone'] || []
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
module CloudstackNagios
|
5
|
+
class Base < Thor
|
6
|
+
include Thor::Actions
|
7
|
+
include CloudstackNagios::Helper
|
8
|
+
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
# catch control-c and exit
|
12
|
+
trap("SIGINT") {
|
13
|
+
puts " bye"
|
14
|
+
exit!
|
15
|
+
}
|
16
|
+
|
17
|
+
# exit with return code 1 in case of a error
|
18
|
+
def self.exit_on_failure?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
no_commands do
|
23
|
+
def client(opts = {})
|
24
|
+
@config ||= load_configuration
|
25
|
+
@client ||= CloudstackClient::Connection.new(
|
26
|
+
@config[:url],
|
27
|
+
@config[:api_key],
|
28
|
+
@config[:secret_key],
|
29
|
+
opts.merge({debug: options[:debug]})
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_configuration(config_file = options[:config], env = options[:environment])
|
34
|
+
unless File.exists?(config_file)
|
35
|
+
say "Configuration file #{config_file} not found.", :red
|
36
|
+
say "Please run \'cs-nagios setup\' to create one."
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
begin
|
40
|
+
config = YAML::load(IO.read(config_file))
|
41
|
+
rescue
|
42
|
+
error "Can't load configuration from file #{config_file}."
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
if env
|
46
|
+
config = config[env]
|
47
|
+
unless config
|
48
|
+
error "Can't find environment #{env} in configuration file."
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
config
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_project(project_name = options[:project])
|
56
|
+
return nil unless project_name
|
57
|
+
unless project = client.get_project(project_name)
|
58
|
+
say "Project '#{options[:project]}' not found", :red
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
project
|
62
|
+
end
|
63
|
+
|
64
|
+
def filter_by(objects, tag_name, tag)
|
65
|
+
objects.select {|r| r[tag_name].downcase == tag.downcase}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
|
3
|
+
module CloudstackNagios
|
4
|
+
class Cli < CloudstackNagios::Base
|
5
|
+
include Thor::Actions
|
6
|
+
|
7
|
+
package_name "cloudstack-nagios"
|
8
|
+
map %w(-v --version) => :version
|
9
|
+
|
10
|
+
class_option :config,
|
11
|
+
default: File.join(Dir.home, '.cloudstack-nagios.yml'),
|
12
|
+
aliases: '-c',
|
13
|
+
desc: 'location of your cloudstack-nagios configuration file'
|
14
|
+
|
15
|
+
class_option :environment,
|
16
|
+
aliases: '-e',
|
17
|
+
desc: 'environment to load from the configuration file'
|
18
|
+
|
19
|
+
class_option :debug,
|
20
|
+
desc: 'enable debug output',
|
21
|
+
type: :boolean
|
22
|
+
|
23
|
+
desc "version", "outputs the cloudstack-nagios version"
|
24
|
+
def version
|
25
|
+
say "cloudstack-nagios v#{CloudstackNagios::VERSION}"
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
desc "setup", "initial setup of the Cloudstack connection"
|
31
|
+
option :url
|
32
|
+
option :api_key
|
33
|
+
option :secret_key
|
34
|
+
def setup(file = options[:config])
|
35
|
+
config = {}
|
36
|
+
unless options[:url]
|
37
|
+
say "Configuring #{options[:environment] || 'default'} environment."
|
38
|
+
say "What's the URL of your Cloudstack API?", :yellow
|
39
|
+
say "Example: https://my-cloudstack-service/client/api/"
|
40
|
+
config[:url] = ask("URL:", :magenta)
|
41
|
+
end
|
42
|
+
unless options[:api_key]
|
43
|
+
config[:api_key] = ask("API Key:", :magenta)
|
44
|
+
end
|
45
|
+
unless options[:secret_key]
|
46
|
+
config[:secret_key] = ask("Secret Key:", :magenta)
|
47
|
+
end
|
48
|
+
if options[:environment]
|
49
|
+
config = {options[:environment] => config}
|
50
|
+
end
|
51
|
+
if File.exists? file
|
52
|
+
begin
|
53
|
+
old_config = YAML::load(IO.read(file))
|
54
|
+
rescue
|
55
|
+
error "Can't load configuration from file #{config_file}."
|
56
|
+
exit 1
|
57
|
+
end
|
58
|
+
say "Warning: #{file} already exists.", :red
|
59
|
+
exit unless yes?("Do you want to merge your settings? [y/N]", :red)
|
60
|
+
config = old_config.merge(config)
|
61
|
+
end
|
62
|
+
File.open(file, 'w+') {|f| f.write(config.to_yaml) }
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "environments", "list cloudstack-nagios environments"
|
66
|
+
def environments(file = options[:config])
|
67
|
+
config = {}
|
68
|
+
if File.exists? file
|
69
|
+
begin
|
70
|
+
config = YAML::load(IO.read(file))
|
71
|
+
rescue
|
72
|
+
error "Can't load configuration from file #{config_file}."
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
table = [%w(Name URL)]
|
76
|
+
table << ["default", config[:url]]
|
77
|
+
config.each_key do |key|
|
78
|
+
table << [key, config[key][:url]] unless key.class == Symbol
|
79
|
+
end
|
80
|
+
print_table table
|
81
|
+
end
|
82
|
+
end
|
83
|
+
map :envs => :environments
|
84
|
+
|
85
|
+
desc "command COMMAND [arg1=val1 arg2=val2...]", "run a custom api command"
|
86
|
+
def command(command, *args)
|
87
|
+
params = {'command' => command}
|
88
|
+
args.each do |arg|
|
89
|
+
arg = arg.split('=')
|
90
|
+
params[arg[0]] = arg[1]
|
91
|
+
end
|
92
|
+
puts JSON.pretty_generate(client.send_request params)
|
93
|
+
end
|
94
|
+
|
95
|
+
require File.dirname(__FILE__) + '/commands/nagios_config.rb'
|
96
|
+
desc "config SUBCOMMAND ...ARGS", "Nagios configuration commands"
|
97
|
+
subcommand :nagios_config, NagiosConfig
|
98
|
+
|
99
|
+
end # class
|
100
|
+
end # module
|