jupiter 0.0.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Gemfile +1 -0
- data/README.md +323 -3
- data/bin/jupiter +7 -0
- data/config.yaml.example +37 -0
- data/jupiter.gemspec +10 -0
- data/lib/jupiter.rb +45 -1
- data/lib/jupiter/cli.rb +100 -0
- data/lib/jupiter/cli/colorizer.rb +44 -0
- data/lib/jupiter/cli/output.rb +355 -0
- data/lib/jupiter/configuration.rb +18 -0
- data/lib/jupiter/host.rb +257 -0
- data/lib/jupiter/nagios.rb +188 -0
- data/lib/jupiter/template.rb +39 -0
- data/lib/jupiter/uuid.rb +20 -0
- data/lib/jupiter/version.rb +1 -1
- data/lib/jupiter/virtualmachine.rb +123 -0
- data/spec/jupiter/cli_spec.rb +14 -0
- data/spec/jupiter/host_spec.rb +29 -0
- data/spec/jupiter/nagios_spec.rb +9 -0
- data/spec/jupiter/uuid_spec.rb +13 -0
- data/spec/jupiter/virtualmachine_spec.rb +12 -0
- data/spec/jupiter_spec.rb +7 -0
- data/spec/spec_helper.rb +14 -0
- metadata +129 -6
@@ -0,0 +1,18 @@
|
|
1
|
+
module Jupiter
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :nagios, :hosts, :vmusers, :templates
|
4
|
+
|
5
|
+
def self.load_from_yaml!
|
6
|
+
config = YAML.load_file('config.yaml')
|
7
|
+
new(config)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@hosts = options.fetch(:hosts) {[]}
|
12
|
+
@vmusers = options.fetch(:vmusers) { {} }
|
13
|
+
@templates = options.fetch(:templates) { {} }
|
14
|
+
@nagios = options.fetch(:nagios) { {} }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/jupiter/host.rb
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
module Jupiter
|
2
|
+
class Host
|
3
|
+
|
4
|
+
attr_accessor :name, :vmpath, :host, :sshport, :sshuser, :sshpass, :dcname, :timestamp
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
self.name = options.fetch(:name)
|
8
|
+
self.vmpath = options.fetch(:vmpath)
|
9
|
+
self.host = options.fetch(:host)
|
10
|
+
self.sshport = options.fetch(:sshport)
|
11
|
+
self.sshuser = options.fetch(:sshuser)
|
12
|
+
self.sshpass = options.fetch(:sshpass)
|
13
|
+
self.dcname = options.fetch(:dcname)
|
14
|
+
self.timestamp = Time.new.strftime('%Y-%m-%d-%H%M').freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def server_uptime
|
18
|
+
puts ssh.exec!("uptime")
|
19
|
+
close_ssh
|
20
|
+
end
|
21
|
+
|
22
|
+
def server_vm_list
|
23
|
+
vm_list = ssh.exec!("ls #{vmpath}").to_s
|
24
|
+
close_ssh
|
25
|
+
vm_list.split("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def ssh
|
29
|
+
@ssh ||= Net::SSH.start(host, sshuser, password: sshpass, port: sshport)
|
30
|
+
end
|
31
|
+
|
32
|
+
def close_ssh
|
33
|
+
ssh.close
|
34
|
+
@ssh = nil
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def vmhost
|
39
|
+
if /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.match(host)
|
40
|
+
vim = RbVmomi::VIM.connect host: host, user: sshuser, password: sshpass, insecure: true
|
41
|
+
dc = vim.serviceInstance.find_datacenter(dcname) or fail "datacenter not found"
|
42
|
+
else
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def guestvm(vmname)
|
48
|
+
vm = vmhost.find_vm(vmname) or fail "\n\nVirtual Machine was not found. Although its files might exist, it may not be registered on the server. You can register the VM with the following command:\n\njupiter register --guest=#{vmname} --host=#{name}\n\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
def guest_ip(vm)
|
52
|
+
result = guestvm(vm).guest_ip
|
53
|
+
end
|
54
|
+
|
55
|
+
def vm_state(vm)
|
56
|
+
result = guestvm(vm).guest.guestState
|
57
|
+
end
|
58
|
+
|
59
|
+
def snapshot_create(vm)
|
60
|
+
result = guestvm(vm).CreateSnapshot_Task(name: "snapshot_#{timestamp}", memory: false, quiesce: true)
|
61
|
+
end
|
62
|
+
|
63
|
+
def snapshots_remove(vm)
|
64
|
+
result = guestvm(vm).RemoveAllSnapshots_Task
|
65
|
+
end
|
66
|
+
|
67
|
+
def consolidate_snapshots(vm)
|
68
|
+
result = guestvm(vm).ConsolidateVMDisks_Task
|
69
|
+
end
|
70
|
+
|
71
|
+
def register_vm(vm)
|
72
|
+
ssh.exec!("vim-cmd solo/registervm #{vmpath}/#{vm}/#{vm}.vmx")
|
73
|
+
snapshots_remove(vm)
|
74
|
+
end
|
75
|
+
|
76
|
+
def unregister_vm(vm)
|
77
|
+
ssh.exec!("vim-cmd vmsvc/unregister #{vmpath}/#{vm}/#{vm}.vmx")
|
78
|
+
end
|
79
|
+
|
80
|
+
def power_on_vm(vm)
|
81
|
+
result = guestvm(vm).PowerOnVM_Task
|
82
|
+
end
|
83
|
+
|
84
|
+
def power_off_vm(vm)
|
85
|
+
result = guestvm(vm).PowerOffVM_Task
|
86
|
+
end
|
87
|
+
|
88
|
+
def power_cycle_vm(vm)
|
89
|
+
guestvm(vm).PowerOffVM_Task
|
90
|
+
sleep 5
|
91
|
+
guestvm(vm).PowerOnVM_Task
|
92
|
+
end
|
93
|
+
|
94
|
+
def reboot_vm(vm)
|
95
|
+
result = guestvm(vm).RebootGuest
|
96
|
+
end
|
97
|
+
|
98
|
+
def shutdown_vm(vm)
|
99
|
+
result = guestvm(vm).ShutdownGuest
|
100
|
+
end
|
101
|
+
|
102
|
+
def clone_vm(vm, newvm)
|
103
|
+
snapshot_create(vm)
|
104
|
+
sleep 5
|
105
|
+
ssh.exec!("mkdir #{vmpath}/#{newvm}")
|
106
|
+
ssh.exec!("cp -Rfv #{vmpath}/#{vm}/* #{vmpath}/#{newvm}")
|
107
|
+
rename_cp_files(vm, newvm)
|
108
|
+
update_vmx(vm, newvm)
|
109
|
+
update_vmxf(vm, newvm)
|
110
|
+
update_vmdk(vm, newvm)
|
111
|
+
register_vm(newvm)
|
112
|
+
close_ssh
|
113
|
+
snapshots_remove(vm)
|
114
|
+
consolidate_snapshots(vm)
|
115
|
+
sleep 5
|
116
|
+
power_on_vm(newvm)
|
117
|
+
sleep 5
|
118
|
+
answer_vm_question(newvm) # Needed to answer the "Was the VM moved" question that pops up.
|
119
|
+
sleep 5
|
120
|
+
power_on_vm(newvm)
|
121
|
+
end
|
122
|
+
|
123
|
+
def rename_cp_files(vm, newvm)
|
124
|
+
old_files_path = "#{vmpath}/#{newvm}/#{vm}"
|
125
|
+
new_files_path = "#{vmpath}/#{newvm}/#{newvm}"
|
126
|
+
ssh.exec!("rm -f #{vmpath}/#{newvm}/vmware-*.log")
|
127
|
+
ssh.exec!("rm -f #{old_files_path}.vmx~")
|
128
|
+
ssh.exec!("rm -f #{old_files_path}.vmsd")
|
129
|
+
ssh.exec!("rm -f #{old_files_path}-*.vmsn")
|
130
|
+
ssh.exec!("rm -f #{old_files_path}-0000*.vmdk")
|
131
|
+
ssh.exec!("mv #{old_files_path}-aux.xml #{new_files_path}-aux.xml")
|
132
|
+
ssh.exec!("mv #{old_files_path}-flat.vmdk #{new_files_path}-flat.vmdk")
|
133
|
+
ssh.exec!("mv #{old_files_path}.nvram #{new_files_path}.nvram")
|
134
|
+
ssh.exec!("mv #{old_files_path}.vmdk #{new_files_path}.vmdk")
|
135
|
+
ssh.exec!("mv #{old_files_path}.vmx #{new_files_path}.vmx")
|
136
|
+
ssh.exec!("mv #{old_files_path}.vmxf #{new_files_path}.vmxf")
|
137
|
+
end
|
138
|
+
|
139
|
+
def change_config_value(key, value)
|
140
|
+
self[key] = value
|
141
|
+
return self
|
142
|
+
end
|
143
|
+
|
144
|
+
def read_config_to_hash(file)
|
145
|
+
file_contents = ssh.exec!(%Q[cat #{file}])
|
146
|
+
Hash[file_contents.split("\n").map { |line| line.split('=').map(&:strip).map { |value| value.gsub(/\A"|"\z/, '') } }]
|
147
|
+
end
|
148
|
+
|
149
|
+
def uuid(newvm)
|
150
|
+
@uuid ||= Jupiter::UUID.new.generate(newvm)
|
151
|
+
end
|
152
|
+
|
153
|
+
def flatten_hash(hash_to_flatten)
|
154
|
+
hash_to_flatten.map{|k,v| "#{k} = \"#{v}\""}.join("\n")
|
155
|
+
end
|
156
|
+
|
157
|
+
def write_to_file(file_content, full_path_to_file)
|
158
|
+
ssh.exec!(%Q[echo '#{file_content}' > #{full_path_to_file}])
|
159
|
+
end
|
160
|
+
|
161
|
+
def generate_mac_address
|
162
|
+
(1..6).map{"%0.2X"%rand(256)}.join(":")
|
163
|
+
end
|
164
|
+
|
165
|
+
def update_vmx(vm, newvm)
|
166
|
+
vmx_hash = read_config_to_hash("#{vmpath}/#{newvm}/#{newvm}.vmx")
|
167
|
+
vmx_hash['ethernet0.generatedAddress'] = generate_mac_address
|
168
|
+
vmx_hash['uuid.bios'] = uuid(newvm)
|
169
|
+
vmx_hash['uuid.location'] = uuid(newvm)
|
170
|
+
vmx_hash['displayName'] = newvm
|
171
|
+
vmx_hash['nvram'] = "#{newvm}.nvram"
|
172
|
+
vmx_hash['extendedConfigFile'] = "#{newvm}.vmxf"
|
173
|
+
vmx_hash['scsi0:0.fileName'] = "#{newvm}.vmdk"
|
174
|
+
swap_derived_name = vmx_hash['sched.swap.derivedName']
|
175
|
+
swap_derived_name["#{vm}/#{vm}"]= "#{newvm}/#{newvm}"
|
176
|
+
vmx_hash['sched.swap.derivedName'] = swap_derived_name
|
177
|
+
write_to_file(flatten_hash(vmx_hash), "#{vmpath}/#{newvm}/#{newvm}.vmx")
|
178
|
+
return true
|
179
|
+
end
|
180
|
+
|
181
|
+
def update_vmxf(vm, newvm)
|
182
|
+
file_with_path = "#{vmpath}/#{newvm}/#{newvm}.vmxf"
|
183
|
+
newuuid = uuid(newvm)
|
184
|
+
file_contents = "<?xml version=\"1.0\"?>\n<Foundry>\n<VM>\n<VMId type=\"string\">#{newuuid}</VMId>\n<ClientMetaData>\n<clientMetaDataAttributes/>\n<HistoryEventList/></ClientMetaData>\n<vmxPathName type=\"string\">#{newvm}.vmx</vmxPathName></VM></Foundry>"
|
185
|
+
write_to_file(file_contents, file_with_path)
|
186
|
+
return true
|
187
|
+
end
|
188
|
+
|
189
|
+
def update_vmdk(vm, newvm)
|
190
|
+
file_with_path = "#{vmpath}/#{newvm}/#{newvm}.vmdk"
|
191
|
+
file_contents = ssh.exec!(%Q[cat #{file_with_path}])
|
192
|
+
file_contents[vm]= newvm
|
193
|
+
write_to_file(file_contents, file_with_path)
|
194
|
+
return true
|
195
|
+
end
|
196
|
+
|
197
|
+
def vmdk_size(vm)
|
198
|
+
file_with_path = "#{vmpath}/#{vm}/#{vm}.vmdk"
|
199
|
+
vmdk_contents = ssh.exec!(%Q[cat #{file_with_path}])
|
200
|
+
close_ssh
|
201
|
+
vmfs_sectors = vmdk_contents[/\RW(.*?)VMFS/,1]
|
202
|
+
gb_size = ((vmfs_sectors.to_f * 512) / (1024 * 1024 * 1024))
|
203
|
+
end
|
204
|
+
|
205
|
+
def resize_vmdk(vm, size_in_GB)
|
206
|
+
size_in_GB.tr!('^.0-9', '')
|
207
|
+
raise InvalidGBSizeError.new("You can only increase the size of the drive, not reduce it.") if vmdk_size(vm).to_f > size_in_GB.to_f
|
208
|
+
raise InvalidVMStateError.new("#{vm} must be shutdown before the drive can be resized.") if vm_state(vm) == 'running'
|
209
|
+
result = ssh.exec!(%Q[vmkfstools -X #{size_in_GB}G #{vmpath}/#{vm}/#{vm}.vmdk])
|
210
|
+
close_ssh
|
211
|
+
return result
|
212
|
+
end
|
213
|
+
|
214
|
+
def answer_vm_question(vm)
|
215
|
+
result = guestvm(vm).AnswerVM(questionId: '_vmx1', answerChoice: '2')
|
216
|
+
end
|
217
|
+
|
218
|
+
def setup_template(original_name, new_name)
|
219
|
+
extract_template(original_name, new_name)
|
220
|
+
rename_copied_template(original_name, new_name)
|
221
|
+
update_vmx(original_name, new_name)
|
222
|
+
update_vmxf(original_name, new_name)
|
223
|
+
update_vmdk(original_name, new_name)
|
224
|
+
register_vm(new_name)
|
225
|
+
close_ssh
|
226
|
+
sleep 5
|
227
|
+
power_on_vm(new_name)
|
228
|
+
sleep 5
|
229
|
+
answer_vm_question(new_name) # Needed to answer the "Was the VM moved" question that pops up.
|
230
|
+
sleep 5
|
231
|
+
power_on_vm(new_name)
|
232
|
+
end
|
233
|
+
|
234
|
+
def extract_template(original_name, new_name)
|
235
|
+
file_exists = ssh.exec!("find #{vmpath}/#{original_name}.tar.gz").chomp
|
236
|
+
if file_exists == "#{vmpath}/#{original_name}.tar.gz"
|
237
|
+
ssh.exec!("cd #{vmpath} && tar -zxvf #{original_name}.tar.gz && rm #{original_name}.tar.gz")
|
238
|
+
else
|
239
|
+
close_ssh
|
240
|
+
return false
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def rename_copied_template(original_name, new_name)
|
245
|
+
if !new_name.nil? && !original_name.nil?
|
246
|
+
ssh.exec!("mv #{vmpath}/#{original_name} #{vmpath}/#{new_name}")
|
247
|
+
rename_cp_files(original_name, new_name)
|
248
|
+
else
|
249
|
+
return false
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
class InvalidVMStateError < StandardError; end
|
254
|
+
class InvalidGBSizeError < StandardError; end
|
255
|
+
|
256
|
+
end
|
257
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module Jupiter
|
2
|
+
class TextTemplate
|
3
|
+
|
4
|
+
def initialize( template )
|
5
|
+
@template = template.clone()
|
6
|
+
@values = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def set( name, value )
|
10
|
+
@values[ name ] = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def run()
|
14
|
+
@template.gsub( /:::(.*?):::/ ) {
|
15
|
+
raise "Key '#{$1}' found in template but the value has not been set" unless ( @values.has_key?( $1 ) )
|
16
|
+
@values[ $1 ].to_s
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s()
|
21
|
+
run()
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class Nagios
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@url = Jupiter.nagios.fetch(:url)
|
30
|
+
@location = Jupiter.nagios.fetch(:location)
|
31
|
+
@sshuser = Jupiter.nagios.fetch(:sshuser)
|
32
|
+
@sshpass = Jupiter.nagios.fetch(:sshpass)
|
33
|
+
@sshport = Jupiter.nagios.fetch(:sshport)
|
34
|
+
@host = Jupiter.nagios.fetch(:host)
|
35
|
+
end
|
36
|
+
|
37
|
+
def ask(question)
|
38
|
+
print question + " "
|
39
|
+
answer = STDIN.gets.chomp
|
40
|
+
if answer == "" or answer.nil?
|
41
|
+
return nil
|
42
|
+
else
|
43
|
+
return answer
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def host_template(machines_name, machines_alias, machines_ip)
|
48
|
+
template_host = Jupiter::TextTemplate.new(
|
49
|
+
"\ndefine host {"\
|
50
|
+
"\n use linux-server"\
|
51
|
+
"\n host_name :::HOSTNAME:::"\
|
52
|
+
"\n alias :::HOSTALIAS:::"\
|
53
|
+
"\n address :::IPADDRESS:::"\
|
54
|
+
"\n statusmap_image linux40.gd2"\
|
55
|
+
"\n parents GATEWAY1"\
|
56
|
+
"\n}\n"
|
57
|
+
)
|
58
|
+
template_host.set( 'HOSTNAME', machines_name)
|
59
|
+
template_host.set( 'HOSTALIAS', machines_alias)
|
60
|
+
template_host.set( 'IPADDRESS', machines_ip)
|
61
|
+
|
62
|
+
return template_host
|
63
|
+
end
|
64
|
+
|
65
|
+
def services_template(machines_name)
|
66
|
+
template_services = Jupiter::TextTemplate.new(
|
67
|
+
"\ndefine service {"\
|
68
|
+
"\n use local-service"\
|
69
|
+
"\n host_name :::HOSTNAME:::"\
|
70
|
+
"\n service_description Root Partition"\
|
71
|
+
"\n check_command check_local_disk!20%!10%!/"\
|
72
|
+
"\n notifications_enabled 1"\
|
73
|
+
"\n}\n"\
|
74
|
+
"\ndefine service{"\
|
75
|
+
"\n use local-service"\
|
76
|
+
"\n host_name :::HOSTNAME:::"\
|
77
|
+
"\n service_description Current Users"\
|
78
|
+
"\n check_command check_local_users!20!50"\
|
79
|
+
"\n notifications_enabled 1"\
|
80
|
+
"\n}\n"\
|
81
|
+
"\ndefine service{"\
|
82
|
+
"\n use local-service"\
|
83
|
+
"\n host_name :::HOSTNAME:::"\
|
84
|
+
"\n service_description Total Processes"\
|
85
|
+
"\n check_command check_local_procs!250!400!RSZDT"\
|
86
|
+
"\n notifications_enabled 1"\
|
87
|
+
"\n}\n"\
|
88
|
+
"\ndefine service{"\
|
89
|
+
"\n use local-service"\
|
90
|
+
"\n host_name :::HOSTNAME:::"\
|
91
|
+
"\n service_description Current Load"\
|
92
|
+
"\n check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0"\
|
93
|
+
"\n notifications_enabled 1"\
|
94
|
+
"\n}\n"\
|
95
|
+
"\ndefine service{"\
|
96
|
+
"\n use local-service"\
|
97
|
+
"\n host_name :::HOSTNAME:::"\
|
98
|
+
"\n service_description Swap Usage"\
|
99
|
+
"\n check_command check_local_swap!20!10"\
|
100
|
+
"\n notifications_enabled 1"\
|
101
|
+
"\n}\n"\
|
102
|
+
"\ndefine service{"\
|
103
|
+
"\n use local-service"\
|
104
|
+
"\n host_name :::HOSTNAME:::"\
|
105
|
+
"\n service_description SSH"\
|
106
|
+
"\n check_command check_ssh!-p 2500"\
|
107
|
+
"\n notifications_enabled 0"\
|
108
|
+
"\n}\n"\
|
109
|
+
"\ndefine service{"\
|
110
|
+
"\n use local-service"\
|
111
|
+
"\n host_name :::HOSTNAME:::"\
|
112
|
+
"\n service_description HTTP"\
|
113
|
+
"\n check_command check_http"\
|
114
|
+
"\n notifications_enabled 0"\
|
115
|
+
"\n}"\
|
116
|
+
)
|
117
|
+
template_services.set( 'HOSTNAME', machines_name)
|
118
|
+
|
119
|
+
return template_services
|
120
|
+
end
|
121
|
+
|
122
|
+
def action(choice, machines_name, machines_alias, machines_ip)
|
123
|
+
if (choice == 1)
|
124
|
+
include_services = ask("\nWould you like to include default services? (yes / no): ")
|
125
|
+
if (include_services == 'yes')
|
126
|
+
puts "\n\n\n"
|
127
|
+
puts generate_template(machines_name, machines_alias, machines_ip, 1)
|
128
|
+
puts "\n\n\n"
|
129
|
+
end
|
130
|
+
if (include_services == 'no')
|
131
|
+
puts "\n\n\n"
|
132
|
+
puts generate_template(machines_name, machines_alias, machines_ip, 0)
|
133
|
+
puts "\n\n\n"
|
134
|
+
end
|
135
|
+
elsif (choice == 2)
|
136
|
+
include_services = ask("\nWould you like to include default services? (yes / no): ")
|
137
|
+
if (include_services == 'yes')
|
138
|
+
puts "\n\n\n"
|
139
|
+
upload_nagios_config(machines_name, machines_alias, machines_ip, 1)
|
140
|
+
puts "Completed adding nagios config for #{machines_name}. Please restart Nagios to see changes."
|
141
|
+
puts "\n\n\n"
|
142
|
+
end
|
143
|
+
if (include_services == 'no')
|
144
|
+
puts "\n\n\n"
|
145
|
+
upload_nagios_config(machines_name, machines_alias, machines_ip, 0)
|
146
|
+
puts "Added Nagios configuration for #{machines_name}. Please restart Nagios to see changes."
|
147
|
+
puts "\n\n\n"
|
148
|
+
end
|
149
|
+
else
|
150
|
+
raise InvalidSelectionError.new("Not a valid selection.")
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def generate_template(machines_name, machines_alias, machines_ip, services)
|
155
|
+
host = host_template(machines_name, machines_alias, machines_ip)
|
156
|
+
serv = services_template(machines_name)
|
157
|
+
if (services == 1)
|
158
|
+
template = "########## GENERATED BY JUPITER ##########\n#{host}#{serv}\n\n########## GENERATED BY JUPITER ##########"
|
159
|
+
else
|
160
|
+
template = "########## GENERATED BY JUPITER ##########\n#{host}\n\n########## GENERATED BY JUPITER ##########"
|
161
|
+
end
|
162
|
+
return template
|
163
|
+
end
|
164
|
+
|
165
|
+
def upload_nagios_config(machines_name, machines_alias, machines_ip, services)
|
166
|
+
template = generate_template(machines_name, machines_alias, machines_ip, services)
|
167
|
+
puts template
|
168
|
+
puts ssh.exec!(%Q[echo "#{template}" > #{@location}/#{machines_name}.cfg])
|
169
|
+
close_ssh
|
170
|
+
end
|
171
|
+
|
172
|
+
def ssh
|
173
|
+
@ssh ||= Net::SSH.start(@host, @sshuser, password: @sshpass, port: @sshport)
|
174
|
+
end
|
175
|
+
|
176
|
+
def close_ssh
|
177
|
+
ssh.close
|
178
|
+
@ssh = nil
|
179
|
+
true
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
class InvalidSelectionError < StandardError; end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
|