1#!/usr/local/bin/perl
2##################################################################################
3# CSV/XML Bridge Tool for Pandora FMS
4# (c) Sancho Lerena 2012, slerena@gmail.com
5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License
8# as published by the Free Software Foundation; version 2
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# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16##################################################################################
17
18use strict;
19use Getopt::Long;
20
21my $version = "v1.0";
22
23sub print_usage () {
24	print "Usage: $0 $version\n\n";
25	print "\t-A <field position for Agent> \n";
26	print "\t-Y <field position for module data value> \n";
27	print "\t-T <module type, by default is 'generic_data'> \n";
28	print "\t-O <field position for module description> \n";
29	print "\t-N <field position for agent description> \n";
30	print "\t-M <module name> \n";
31	print "\t-X <field position for data timestamp> \n";
32	print "\t-I <agent interval (in secs)> \n";
33	print "\t-G <field position for agent group> \n";
34
35	print "\t-s <Skip # firt lines (2 by default)> \n";
36	print "\t-c <character delimitator>\n";
37	print "\t-f <CSV file to process>\n";
38	print "\t-d <destination directory>\n";
39	print "\t-R Is used to dump header fields / order, to select \n";
40	print "\t   what fields you need to parse\n";
41
42	print "\t-hV Help (this help)\n";
43	print "\nSample Usage:\n\n";
44	print "\tperl pandora_csv_bridge.pl -f datos4.csv -c @ -A 2 -Y 26 -M Consumo_Electrico -d /tmp/dump -G 3 -X 12\n\n";
45    	exit;
46}
47
48sub transform_date ($){
49	#'2012/03/26 19:37:22	# Output format needed
50	my $orig_data = $_[0];
51	my $date;
52
53	my @t1;
54	if ($orig_data =~ /\//){
55		@t1 = split ("/", $orig_data);
56	} else {
57		@t1 = split ("-", $orig_data);
58	}
59
60	# We asume 3rd digit is YEAR in "two digits" format
61	# 2nd field is DAY and 1st field is month
62	if ($t1[0] < 12){
63		$date = "20".$t1[2]."/".$t1[0]."/".$t1[1]. " 00:00:00";
64	} else {
65		$date = "20".$t1[2]."/".$t1[1]."/".$t1[0]. " 00:00:00";
66	}
67	return $date;
68}
69
70my ($opt_v, $opt_h, $opt_d, $opt_c, $opt_f, $opt_s, $opt_R, $opt_A, $opt_O, $opt_Y, $opt_T, $opt_X, $opt_I,  $opt_M, $opt_G, $opt_N);
71
72# Default values
73$opt_N = "";
74$opt_G = "Servers";
75$opt_I = "300";
76$opt_I = "300";
77$opt_s = 2;
78$opt_T = "generic_data";
79
80my $utimestamp;
81my $utimestamp_extra;
82
83if ( $ARGV[0] eq "" ) {
84	print_usage();
85}
86
87GetOptions
88        ("h"   => \$opt_h,
89		 "R"   => \$opt_R,
90		 "help" => \$opt_h,
91	     "c=s" => \$opt_c,
92         "f=s" => \$opt_f,
93		 "d=s" => \$opt_d,
94		 "s=s" => \$opt_s,
95		 "M=s" => \$opt_M,
96		 "N=s" => \$opt_N,
97		 "A=s" => \$opt_A,
98		 "O=s" => \$opt_O,
99		 "Y=s" => \$opt_Y,
100		 "T=s" => \$opt_T,
101		 "X=s" => \$opt_X,
102		 "G=s" => \$opt_G,
103		 "I=s" => \$opt_I,
104         "v" => \$opt_v,
105		 "verbose" => \$opt_v);
106
107if ($opt_v) {
108    print "\n";
109    print "$0 Pandora FMS CSV / XML Bridge Tool $version\n";
110    print "\n";
111    print_usage();
112}
113
114if ($opt_h) {
115    print_usage();
116}
117
118if (!defined($opt_R)){
119	if ( !defined($opt_f)){
120		print_usage();
121	}
122
123	if ( !defined($opt_X)){
124		print_usage();
125	}
126}
127
128# DEBUG
129#print "Opening file $opt_f with CSV character $opt_c Agent name $opt_A Timestamp Field $opt_X \n";
130
131open (FIDATA, "< $opt_f");
132my @data;
133my $header;
134
135# Skip first $opt_s lines of File
136my $ax; my $temp_skip;
137for ($ax = 0; $ax < $opt_s; $ax++){
138	if ($ax == 0) {
139		$header = <FIDATA>;
140	}
141	else {
142		$temp_skip = <FIDATA>;
143		$header = $temp_skip;
144	}
145}
146
147# Dump header
148if ( defined($opt_R)){
149
150	if (!defined($opt_c)){
151		print_usage();
152	}
153
154	my %header_data = split ("$opt_c", $header );
155	my $key;
156
157	print "\nDumping CSV Structure (Field Label -> Field Order)\n\n";
158
159	foreach $key (keys %header_data){
160		print $header_data{$key} ." -> ". $key ." \n";
161	}
162
163	exit;
164}
165
166# Begin process file
167my $buffer_line;
168my $filename;
169my $counter = 1;
170
171print "Generating data from CSV file $opt_f, with CSV character $opt_c Agent name $opt_A Timestamp Field $opt_X \n";
172
173while (<FIDATA>){
174	$counter++;
175    $buffer_line = $_;
176	@data = split ("$opt_c", $buffer_line);
177
178	# Let's create the damm XML for each line
179	$utimestamp = time ();
180	$utimestamp_extra = int(rand(10000));
181	$utimestamp = $utimestamp . $utimestamp_extra;
182	$utimestamp = $utimestamp + $counter;
183
184	$filename = $opt_d."/". $data[$opt_A].".".$utimestamp.".data";
185
186	open (OUTDATA, "> $filename");
187	print OUTDATA "<?xml version='1.0' encoding='ISO-8859-1'?>";
188	print OUTDATA "<agent_data description='$data[$opt_N]' group='$data[$opt_G]' os_name='other' os_version='1.0' interval='$opt_I' version='4.0.1' timestamp='".transform_date($data[$opt_X])."' agent_name='$data[$opt_A]' timezone_offset='0'>";
189
190	print OUTDATA "<module>
191	<name>$opt_M</name>
192	<type>$opt_T</type>
193	<description>$data[$opt_O]</description>
194	<data>$data[$opt_Y]</data>
195	</module>";
196	print OUTDATA "</agent_data>";
197	close (OUTDATA);
198
199}
200