Statistics
| Branch: | Tag: | Revision:

root / policies / system / inventory / 1.0 / fusionAgent.st @ fd4f20ee

History | View | Annotate | Download (18 kB)

1
#####################################################################################
2
# Copyright 2011 Normation SAS
3
#####################################################################################
4
#
5
# This program is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, Version 3.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
#
17
#####################################################################################
18

    
19
#
20
# This file launch a fusion-inventory agent
21
# inventory in local.
22
# If fusion agent is not installed, 
23
# the installation is done
24
# 
25
# Then the inventory file is improved with external informations (UUID, cf-key, VMs)
26

    
27

    
28
bundle agent doInventory {
29
        commands:
30
          linux::
31
                "/usr/bin/curl"
32
                        args => "-s -f -o \"$(g.rudder_var_tmp)/uuid.txt\" http://${server_info.cfserved}/uuid",
33
                        comment => "Getting the uuid from the server",
34
                        classes => if_else("uuid_succesfully_downloaded","could_not_download_uuid");
35

    
36
	  windows::
37
                "\"${g.rudder_base_sbin}\curl\curl.exe\""
38
                        args => "-s -f -o \"$(g.rudder_var_tmp)\uuid.txt\" http://${server_info.cfserved}/uuid",
39
                        comment => "Getting the uuid from the server",
40
                        classes => if_else("uuid_succesfully_downloaded","could_not_download_uuid");
41

    
42
	vars:
43
	  linux.uuid_succesfully_downloaded::
44
		"policy_server_uuid" string => readfile("$(g.rudder_var_tmp)/uuid.txt", 50);
45

    
46
	  windows.uuid_succesfully_downloaded::
47
		"policy_server_uuid" string => readfile("$(g.rudder_var_tmp)/uuid.txt", 50);
48

    
49
        classes:
50
                "splaying" expression => splayclass("$(sys.host)$(sys.ipv4)","hourly");
51

    
52
	  uuid_succesfully_downloaded::
53
		"uuid_valid" expression => regcmp("[a-z0-9-]+","$(policy_server_uuid)");
54
		"uuid_validity_checked"
55
			expression => "any",
56
			comment    => "This dummy class is just used for ordering the report using !uuid_valid below";
57

    
58
        methods:
59

    
60
                uuid_valid.force_inventory::
61
			"any" usebundle => fusionAgent;
62
			"any" usebundle => listInstalledVM;
63
			"any" usebundle => generateExtraInformations;
64
			"any" usebundle => turnUsersToUnicode;
65
			"any" usebundle => addInformationsToInventory;
66
			"any" usebundle => moveInventoryToFinalDestination;
67
			"any" usebundle => sendInventory;
68

    
69
		# Workaround the wrong class expansion
70
		uuid_valid.Night.splaying.!inventory_sent::
71
			"any" usebundle => fusionAgent;
72
			"any" usebundle => listInstalledVM;
73
			"any" usebundle => generateExtraInformations;
74
			"any" usebundle => turnUsersToUnicode;
75
			"any" usebundle => addInformationsToInventory;
76
			"any" usebundle => moveInventoryToFinalDestination;
77
			"any" usebundle => sendInventory;
78

    
79
        reports:
80
                could_not_download_uuid::
81
                        "@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not retrieve the UUID of the policy server";
82

    
83
		uuid_succesfully_downloaded.uuid_validity_checked.!uuid_valid::
84
			"@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not retrieve a valid UUID from the policy server";
85

    
86
			# Send reports to confirm this PT's success even if we don't need to send an inventory
87
			inventory_sent::
88
				"@@Inventory@@log_info@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#An inventory was already sent less than 8 hours ago";
89

    
90
			!(Night.splaying).!force_inventory::
91
				"@@Inventory@@result_success@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Next inventory scheduled between 00:00 and 06:00";
92
			
93
}
94

    
95
bundle common inventory {
96
	vars:
97
	  windows::
98
		# Files names
99
		"UserListFile_cp" string => "${g.rudder_var_tmp}\UserList.tmp";
100
		"UserListFile" string => "${g.rudder_var_tmp}\UserList.list";
101
		
102
	  any::
103
	  	"CPUIDFile" string => "${g.rudder_var_tmp}/cpuid.arc";
104
}
105

    
106
bundle agent fusionAgent {
107
     
108

    
109
	files:
110
	linux|cygwin::
111
	    "${g.rudder_var_tmp}/inventory/."
112
		create => "true",
113
		comment => "Creating inventory directory",
114
		classes => if_ok("inventoryfoldercreated");
115

    
116
	    "${g.rudder_var_reports}/."
117
		create => "true";
118

    
119
	windows.!cygwin::
120
	    "${g.rudder_var_tmp}\inventory\."
121
		create => "true",
122
		comment => "Creating inventory directory",
123
		classes => if_ok("inventoryfoldercreated");
124

    
125
	    "${g.rudder_var_reports}\."
126
		create => "true";
127

    
128
	commands:
129
	    linux.inventoryfoldercreated::
130
			"${g.rudder_base}/bin/run-inventory --local=${g.rudder_var_tmp}/inventory",
131
			classes => cf2_if_else("run_inventory", "inventory_failed"),
132
			comment => "Generating inventory, in the temporary folder";
133

    
134
	    windows::	    
135
			"\"${g.rudder_base_sbin}\perl\bin\perl.exe\""
136
				        args => "\"${g.rudder_base_sbin}\perl\bin\fusioninventory-agent\" --local=\"${g.rudder_var_tmp}\inventory\" 2>nul",
137
				        contain => in_shell,
138
				        classes => cf2_if_else("run_inventory", "inventory_failed"),
139
			 			comment => "Generating inventory";
140
			 			
141
	reports:
142
		run_inventory::
143
			"@@Inventory@@log_debug@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Running inventory";
144
			
145
		inventory_failed::
146
			"@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not execute the inventory";
147
			
148
		cant_install_curl::
149
			"@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not install curl";
150
			
151
		cant_install_ocs::
152
			"@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not install ocs";
153
			
154
		curl_installed::
155
			"@@Inventory@@log_info@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Curl installed";
156
			
157
}
158

    
159
# List all installed VM on the machine (based on VirtualBox)
160
# CAUTION : Issue with path containing a whitespace, it's not working with windows
161
bundle agent listInstalledVM {
162
	commands:
163
		linux.VirtualBoxInstalled::
164
			"/usr/bin/VBoxManage"
165
				args => "-q list vms > ${virtualMachines.VBoxListFile}",
166
				contain => outputable,
167
				classes => cf2_if_else("vb_listed", "cant_list_vb"),
168
				comment => "Generating file with list of VM";
169

    
170

    
171
		windows.VirtualBoxInstalled::
172
			"\"${virtualMachines.virtual_box_install_path}VBoxManage.exe\""
173
				args => "-q list vms > ${virtualMachines.VBoxListFile}",
174
				contain => outputable,
175
				classes => cf2_if_else("vb_listed", "cant_list_vb"),
176
				comment => "Generating file with list of VM";
177

    
178
		linux.VMWareInstalled::
179
			"${virtualMachines.VMWareScript}"
180
				contain => outputable,
181
				args => " > ${virtualMachines.VMWareListFile}",
182
				classes => cf2_if_else("vm_listed", "cant_list_vm"),
183
				comment => "Generating file with list of VM";
184

    
185

    
186
		windows.VMWareInstalled::
187
			"${virtualMachines.VMWareScript}"
188
				contain => outputable,
189
				args => " > ${virtualMachines.VMWareListFile}",
190
				classes => cf2_if_else("vm_listed", "cant_list_vm"),
191
				comment => "Generating file with list of VM";
192

    
193
	files:
194
		VirtualBoxInstalled::
195
			"${virtualMachines.VBoxListFile}"
196
				create => "true",
197
				edit_line => xmlify($(virtualMachines.VBoxAttr)),
198
				comment => "Converting file into pseudo XML";
199

    
200
		VMWareInstalled::
201
			"${virtualMachines.VMWareListFile}"
202
				create => "true",
203
				edit_line => xmlify($(virtualMachines.VMWareAttr)),
204
				comment => "Converting file into pseudo XML";
205

    
206

    
207
	reports:
208
		cant_list_vm::
209
			"@@Inventory@@log_warn@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not list installed VMWare machines";
210
			
211
		cant_list_vb::
212
			"@@Inventory@@log_warn@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not list installed VirtualBox machines";
213
}
214

    
215
bundle agent generateExtraInformations {
216
  commands:
217
    windows::
218
		"\"${g.rudder_dependencies}\userlist.bat\""
219
			args => " > \"${inventory.UserListFile_cp}\" ",
220
			contain => outputable,
221
			classes => cf2_if_else("userlist", "userlist_fail"),
222
			comment => "Generating file with list of users";
223
	
224
		"${sys.winsysdir}\cscript.exe"
225
			args => "/Nologo \"${g.rudder_dependencies}/cpuid-windows-V1.0.vbs\" > \"${inventory.CPUIDFile}\"",
226
			contain => outputable,
227
			classes => cf2_if_else("cpuid", "cpuid_fail"),
228
			comment => "Generating file with CPUID information";
229
			
230
	linux::
231
		"${g.rudder_dependencies}/cpuid-linux-V1.0.sh"
232
			args => " > ${inventory.CPUIDFile}",
233
			contain => outputable,
234
			classes => cf2_if_else("cpuid", "cpuid_fail"),
235
			comment => "Generating file with CPUID information";
236
		
237
 reports:
238
		userlist::
239
			"@@Inventory@@log_debug@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Generated the userlist";
240
		cpuid::
241
			"@@Inventory@@log_debug@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Generated the CPUID";
242
		
243
			
244
		userlist_fail::
245
			"@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not generate the user list";
246
	
247
		cpuid_fail::
248
			"@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not generate the cpuid";
249
}
250

    
251
bundle agent turnUsersToUnicode {
252

    
253
  commands:
254
    windows::
255
		"\"${g.rudder_dependencies}\iconv.exe\""
256
			args => " -f CP850 -t UTF-8 \"${inventory.UserListFile_cp}\" > \"${inventory.UserListFile}\" ",
257
			contain => outputable_dir("${g.rudder_dependencies}"),
258
			classes => cf2_if_else("userlist", "userlist_fail"),
259
			comment => "Generating file with list of users in UTF";
260
		
261
 reports:
262
	
263
		windows::
264
			"@@Inventory@@log_debug@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#This is a windows machine. User list has been converted to Unicode";
265
}
266

    
267

    
268
# adding data to the inventory :
269
# UUID and CFKey in <DEVICEID>, 
270
# list of VM in <CONTENT>
271
bundle agent addInformationsToInventory {
272
  vars:
273
	windows.!cygwin::
274
		"CFKEY" string => execresult("${sys.winsysdir}\cmd.exe /c \"type \"${sys.workdir}\ppkeys\localhost.pub\"\"", "noshell");
275
		"USER" string => getenv("USERNAME", 40);
276
		"RUDDERUUID" string => execresult("${sys.winsysdir}\cscript.exe /Nologo \"${g.rudder_dependencies}/uuid.vbs\"","noshell");
277
		"polserv_uuid" string => readfile( "$(g.rudder_var_tmp)\uuid.txt" , "33" );
278
		"users" slist => { readstringlist("${inventory.UserListFile}","#.*","[\n| |\r]",50,4000) };
279
		
280
	cygwin::
281
		"mywinpath" string => execresult("/usr/bin/echo $WINDIR ", "useshell");
282
		"CFKEY" string => execresult("/usr/bin/cat ${sys.workdir}/ppkeys/localhost.pub", "noshell");
283
		"USER" string => execresult("/usr/bin/whoami", "noshell");
284
		"RUDDERUUID" string => execresult("${sys.winsysdir}\cscript.exe /Nologo ${g.rudder_dependencies}/uuid.vbs","noshell");
285
		"polserv_uuid" string => readfile( "$(g.rudder_var_tmp)/uuid.txt" , "33" );
286
		"users" slist => { readstringlist("${inventory.UserListFile}","#.*","[\n| |\r]",10,4000) };
287

    
288
	linux::
289
		"RUDDERUUID" string => execresult("/usr/sbin/dmidecode -s system-uuid","noshell");
290
		"CFKEY" string => execresult("/bin/cat ${sys.workdir}/ppkeys/localhost.pub", "noshell");
291
		"USER" string => execresult("/usr/bin/whoami", "noshell");		
292
		"polserv_uuid" string => readfile( "$(g.rudder_var_tmp)/uuid.txt" , "33" );
293
		"usersnumber" int =>  readstringarray("userslist","/etc/passwd","#[^\n]*",":",50,4000);
294
		"users" slist => getindices("userslist");
295

    
296
  files:
297
	windows::
298
		"C:/Program Files/Rudder/var/tmp/inventory/.*.ocs"
299
		#"${g.esc_rudder_var_tmp}\\inventory\\.*.ocs"
300
			edit_line => add_information_to_inventory($(RUDDERUUID), $(CFKEY), $(USER), $(polserv_uuid)),
301
			edit_defaults => def,
302
			pathtype => "regex";
303
			
304
		"C:/Program Files/Rudder/var/tmp/inventory/.*.ocs"
305
		#"${g.esc_rudder_var_tmp}\\inventory\\.*.ocs"
306
			edit_line => add_users_information_to_inventory($(users)),
307
			edit_defaults => def,
308
			pathtype => "regex";
309
	
310
	linux::
311
		"${g.rudder_var_tmp}/inventory/.*.ocs"
312
			edit_line => add_information_to_inventory($(RUDDERUUID), $(CFKEY), $(USER), $(polserv_uuid)),
313
			edit_defaults => def;
314
			
315
		"${g.rudder_var_tmp}/inventory/.*.ocs"
316
			edit_line => add_users_information_to_inventory($(users)),
317
			edit_defaults => def;
318

    
319
}
320

    
321

    
322
# Move the inventory file in the shared directory
323
bundle agent moveInventoryToFinalDestination {
324
  files:
325
    "${g.rudder_inventories}" 
326
		copy_from => copy("$(g.rudder_var_tmp)/inventory"),
327
		depth_search => recurse_visible(1),
328
		file_select => inventory_files,
329
		comment => "Moving inventory files to the final location",
330
		action => bg(30, 10);
331

    
332
}
333

    
334

    
335
# Send the file to the promises server
336
bundle agent sendInventory {
337
  files:
338
    linux::
339
    "${g.rudder_inventories}" 
340
		transformer => "/usr/bin/curl -f -s --user $(g.davuser):$(g.davpw) -T $(this.promiser)  http://${server_info.cfserved}/inventories/",
341
		depth_search => recurse_visible(1),
342
		file_select => inventory_files,
343
		classes => persistant_class("inventory_sent", "cant_send_inventory", 480),
344
		comment => "Sending the inventory to the server";
345

    
346
	# Once we've successfully sent all inventories, remove them
347
	linux.inventory_sent.!cant_send_inventory::
348
	"${g.rudder_inventories}" 
349
		transformer  => "/bin/rm -f $(this.promiser)",
350
		depth_search => recurse_visible(1),
351
		file_select  => inventory_files,
352
		classes      => if_else("inventory_file_deleted", "cant_delete_inventory_file"),
353
		comment      => "Cleaning up inventory files already sent to the server";
354

    
355
	"${g.rudder_var_tmp}/inventory"
356
		transformer  => "/bin/rm -f $(this.promiser)",
357
		depth_search => recurse_visible(1),
358
		file_select  => inventory_files,
359
		classes      => if_else("inventory_file_deleted", "cant_delete_inventory_file"),
360
		comment      => "Cleaning up inventory files already sent to the server";
361

    
362
	# TODO: we should find some way to have an equivalent behaviour to send-clean.sh above on Windows
363
	windows::
364
	 "${g.rudder_inventories}" 
365
		transformer => "\"${g.rudder_base_sbin}\curl\curl.exe\" -f -s --user $(g.davuser):$(g.davpw) -T \"$(this.promiser)\"  http://${server_info.cfserved}/inventories/",
366
		depth_search => recurse_visible(1),
367
		file_select => inventory_files,
368
		classes => persistant_class("inventory_sent", "cant_send_inventory", 480),
369
		comment => "Sending the inventory to the server";
370
		
371
	reports:
372
		inventory_sent::
373
			"@@Inventory@@result_success@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#The inventory has been successfully sent";
374
		
375
		cant_send_inventory::
376
			"@@Inventory@@result_error@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not send the inventory";
377

    
378
		cant_delete_inventory_file::
379
			"@@Inventory@@log_warn@@&TRACKINGKEY&@@inventory@@None@@$(g.execRun)##$(g.uuid)@#Could not delete inventory file after sending to server";
380
			
381
}
382

    
383
#####################################################
384
#Adding the list of Virtual Machines into the report
385
#Adding the ids in the report
386
#####################################################
387
bundle edit_line add_information_to_inventory(RUDDERUUID, CFKEY, USER, POLSRVUUID)
388
{
389
	insert_lines:
390
		"<UUID>${g.uuid}</UUID>$(const.n)<USER>$(USER)</USER>$(const.n)<AGENTSNAME>$(const.n)</AGENTSNAME>$(const.n)<MACHINEID>$(RUDDERUUID)</MACHINEID>$(const.n)<CFKEY>$(CFKEY)</CFKEY>$(const.n)<POLICIES>InitPolicies</POLICIES>$(const.n)<HOSTNAME>$(sys.fqhost)</HOSTNAME>$(const.n)<POLICY_SERVER>$(POLSRVUUID)</POLICY_SERVER>$(const.n)" location => after_deviceid,
391
		comment => "Add the UUID and CFKEY tags in the inventory file";
392

    
393
	any::
394
		"<VMS>$(const.n)</VMS>$(const.n)<USERSLIST>$(const.n)</USERSLIST>" location => after_content;
395

    
396

    
397
		"${inventory.CPUIDFile}"
398
		    insert_type => "file",
399
			location => after_location("<HOSTNAME>"),
400
			comment => "Adding the CPUID data in the inventory file";
401

    
402
	nova_edition::
403
		"<AGENTNAME>Nova</AGENTNAME>"
404
			location => after_location("<AGENTSNAME>"),
405
			comment => "Adding the agent data in the inventory file";
406

    
407
	community_edition::
408
		"<AGENTNAME>Community</AGENTNAME>"
409
			location => after_location("<AGENTSNAME>"),
410
			comment => "Adding the agent data in the inventory file";
411
			
412
	VirtualBoxInstalled::
413
		"${virtualMachines.VBoxListFile}"
414
		        insert_type => "file",
415
			location => after_location("<VMS>"),
416
			comment => "Adding the list of VM in the inventory file";
417

    
418
	VMWareInstalled::
419
		"${virtualMachines.VMWareListFile}"
420
		        insert_type => "file",
421
			location => after_vm,
422
			comment => "Adding the list of VM in the inventory file";
423
}
424

    
425
bundle edit_line add_users_information_to_inventory(userlist)
426
{
427
	insert_lines:
428
		"<USER>${userlist}</USER>$(const.n)" location => after_users,
429
		comment => "Add the UUID and CFKEY tags in the inventory file";	
430
}
431

    
432
#Locators
433
body location after_location(pos) {
434
	select_line_matching => ".*$(pos).*";
435
	before_after => "after";
436
}
437

    
438
body location after_deviceid {
439
	select_line_matching => ".*<DEVICEID>.*";
440
	before_after => "after";
441
}
442

    
443
body location after_content {
444
        select_line_matching => ".*<CONTENT>.*";
445
        before_after => "after";
446
}
447
body location after_vm {
448
        select_line_matching => ".*<VMS>.*";
449
        before_after => "after";
450
}
451
body location after_users {
452
        select_line_matching => ".*<USERSLIST>.*";
453
        before_after => "after";
454
}
455

    
456
###############
457
# Editors
458
##############
459
# Convert a simple list in <VM TYPe="vmtype"><NAME>machine_name</NAME><UUID>value<UUID></VM>
460
bundle edit_line xmlify(ATTR) {
461
	replace_patterns:
462
		"\"(.*)\" \{(.*)\}"
463
			replace_with=> xmled($(ATTR));
464

    
465
}
466

    
467
body replace_with xmled(attribute) {
468
	replace_value => "<VM TYPE=\"$(attribute)\"><NAME>$(match.1)</NAME><UUID>$(match.2)</UUID></VM>";
469
}
470

    
471

    
472
# select the inventory files that has the right extension
473
#I'd like to select also those older than 4 hours (ctime => irange(ago(0,0,0,4,0,0),now);) not working...
474
# (for some reason, ocs duplicated files over time)
475
body file_select inventory_files {
476

    
477
	(windows|linux)::
478
		leaf_name => { ".*.ocs" };
479
		file_result => "leaf_name";
480

    
481
	#windows::
482
	#	leaf_name => { ".*.xml" };
483
	#	file_result => "leaf_name";
484

    
485
}
486

    
487
body perms inventory_perms 
488
{
489
	mode => "0700";
490
}
491

    
492

    
493
body file_select one_day_age
494
#
495
# we can build old "include", "exclude", and "ignore" 
496
# from these as standard patterns - these bodies can
497
# form a library of standard patterns
498
#
499

    
500
{
501
mtime     => irange(ago(1,0,0,0,0,0),ago(0,0,1,0,0,0));  
502
file_result => "mtime"; 
503
}