r4527 yaml_import: update to revision 0.2 by Loïs Taulelle
authorDenis Ovsienko <infrastation@yandex.ru>
Fri, 27 May 2011 15:12:24 +0000 (15:12 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Mon, 26 Mar 2012 10:12:24 +0000 (14:12 +0400)
yaml_import/ask-4rt+yaml.pl [new file with mode: 0755]
yaml_import/dl165lin3.yaml [new file with mode: 0644]
yaml_import/inc/yaml_import.php
yaml_import/skel.yaml [new file with mode: 0644]

diff --git a/yaml_import/ask-4rt+yaml.pl b/yaml_import/ask-4rt+yaml.pl
new file mode 100755 (executable)
index 0000000..95e1ba1
--- /dev/null
@@ -0,0 +1,514 @@
+#!/usr/bin/perl
+#
+# Copyright (C) 2011 PSMN / ENS de Lyon - LT
+# Ce script est régi par la licence CeCILL, voir le fichier
+# COPYING ou http://www.cecill.info/
+#
+# $Id: ask-4rt+yaml.pl 105 2011-05-20 10:09:22Z gruiick $
+#
+# Authors
+#  . Loïs Taulelle <lois dot taulelle at ens-lyon dot fr>
+#
+# Parameters understood:
+#  [hostbase] : the base of hostname (ex: dl165lin)
+#  [start] : numerotation start (ex: 10)
+#  [end] : the end... this is the end (ex: 82)
+#  => generate a list from dl165lin10 to dl165lin82
+#
+# Environment:
+#  Unix only, need following CPAN modules: 
+#  YAML::Tiny Log::Logger File::Tools (for File::Basename File::Copy File::Path) 
+#  File::List Parse::DMIDecode
+#
+# Configuration:
+#  yes, see $debug and $log variables
+#
+use strict;
+use warnings;
+use YAML::Tiny;
+use Log::Logger;
+#use File::Tools;
+use File::Basename;
+use File::Copy;
+use File::Path;
+use File::List;
+use Parse::DMIDecode ();
+
+## Create objects and set environment
+# Configuration
+my $log = "no"; # yes|no
+my $debug = "yes"; # yes|no
+my $fqdn = "ens-lyon.fr";
+
+# global scalars & objects
+my $scriptname = basename($0, ".pl");
+my $hostbase = "";
+my $start = "";
+my $end = "";
+my @hostArray =();
+my $dmi_decoder = Parse::DMIDecode->new();
+my $yaml = YAML::Tiny->new;
+
+# init logs
+my $logline = new Log::Logger;
+my $logfile = "";
+if ( $log eq "yes" ) 
+{
+  $logfile = "$scriptname.log";
+  print ("There will be logs: $logfile \n\n");
+}
+else 
+{
+# TODO verbose and shutup mode ?
+  $logfile = "/dev/null";
+  print ("no logs! \n");
+}
+$logline->open_append("$logfile");
+my $date = &getDate();
+$logline->log_print("\t Job start at $date \n");
+
+# init debug
+if ($debug eq "yes")
+{
+  use Data::Dumper;
+  $logline->log_print("\t DEBUG MODE ON \n");
+}
+
+
+## main program
+# proceeding arguments
+if ( $#ARGV == -1 or $#ARGV != 2 )
+# TODO special mode for one host only, with no number in its name
+{
+  $logline->log_print("\n\t TOO FEW OR MANY ARGUMENTS! \n");
+  $logline->fail("Usage: $scriptname.pl [hostbase] [start] [end] \n");
+}
+else # assuming $#ARGV == 2
+{
+
+  if ($debug eq "yes")
+  {
+    print ("Arguments: \n");
+    print Dumper(@ARGV);
+  }
+  if ( $log eq "yes" )
+  {
+    $logline->log_print("$scriptname called with: @ARGV \n");
+  }
+
+  $hostbase = $ARGV[0];
+  $start = $ARGV[1];
+  $end = $ARGV[2];
+  &setHostList();
+  foreach my $i ($start .. $end)
+  {
+    my $host_os = &getOS($hostArray[$i]);
+    &getSMBios($hostArray[$i],$host_os);
+    &getIfConfig($hostArray[$i],$host_os);
+    &writeYaml($hostArray[$i]);
+  }
+}
+
+## subs
+
+sub writeYaml
+# generate the yaml structures, and write it to yaml file
+# take $hostArray[$i] as filename
+# see skel.yaml
+{
+  my $filename = (my $host = $_[0]);
+  $yaml->[0]->{name} = $_[0];
+  $yaml->[0]->{parameters}->{fqdn} = "$host.$fqdn";
+  $yaml->write( "$filename.yaml" ) || $logline->fail("\t cannot write $filename!");
+
+  if ($debug eq "yes")
+  {
+    print ("$filename.yaml writed successfully \n");
+  }
+  if ( $log eq "yes" )
+  {
+    $logline->log_print("$filename.yaml writed successfully \n");
+  }
+}
+
+sub setHostList
+# generate the hostnames list from call arguments
+# sub take no argument
+{
+  for my $i ($start .. $end)
+  {
+    $hostArray[$i] = "$hostbase$i";
+
+    if ($debug eq "yes")
+    {
+      print ("\t $hostArray[$i] \n");
+    }
+  }
+}
+
+sub getOS
+# ask host for OS release, return OS type
+# my $os = &getOS($host);
+{
+  my $host = $_[0];
+  my $os_internal = "sun"; # pick one, cannot be NULL.
+  my $release = "";
+  my @release_internal = qx(ssh $host cat /etc/release); # have to start with something
+
+  if ($release_internal[0] eq "")
+  {
+    @release_internal = qx(ssh $host cat /etc/redhat-release);
+# TODO debian ? others ? BSD's ? LSB ?
+# Xen/kvm/vmware/vbox has something to deal with:
+# $yaml->[0]->{parameters}->{hypervisor} = "No|Yes";
+
+    if ($release_internal[0] =~ /CentOS/i)
+    {
+      $os_internal = "centos";
+      $release = $release_internal[0];
+    }
+    elsif ($release_internal[0] =~ /Red Hat/i)
+    {
+      $os_internal = "redhat";
+      $release = $release_internal[0];
+    }
+  }
+  elsif ($release_internal[0] =~ /Solaris/i)
+  {
+    $os_internal = "sun";
+    $release = $release_internal[0];
+  }
+  $release =~ s/^\s+//; $release =~ s/\s+$//; # cleanup result
+
+  # save this to yaml
+  $yaml->[0]->{parameters}->{operatingsystem} = $release;
+  my ($digits) = $release =~ /(\d+(?:\.)?\d+)/;
+  $yaml->[0]->{parameters}->{operatingsystemrelease} = $digits;
+  $yaml->[0]->{parameters}->{hypervisor} = "No"; # fixed, for now
+  
+  if ($debug eq "yes")
+  {
+    print ("$release, $digits\n");
+  }
+  if ( $log eq "yes" )
+  {
+    $logline->log_print("$host.$fqdn: $release, $digits\n");
+  }
+
+  return $os_internal;
+}
+
+sub getSMBios
+# ask host for dmidecode information
+# &getSMBios($host,$os);
+{
+  my $host = $_[0];
+  my $os = $_[1];
+  my $product_name = "";
+  my $serial_number = "";
+  my $uuid = "";
+
+  if ($os eq "sun")
+# Parse::dmidecode doesn't parse Oracle/Sun smbios output, so back to basics.
+  {
+    my @bios_raw = qx(ssh uroot\@$host smbios);
+    my $biosLine = "";
+    my $pn_state = (my $sn_state = (my $uu_state = "0"));
+
+    foreach $biosLine (@bios_raw)
+    {
+      if ($biosLine =~ /Product:/)
+      {
+        if ($pn_state == "0")
+        {
+          $product_name = $biosLine;
+          $product_name =~ s/\s+Product:\s+//; chomp $product_name; # cleanup
+          
+          if ($debug eq "yes")
+          {
+            print ("$product_name \n");
+          }
+          $pn_state = "1";
+        }
+        else {next;} # don't waste time with other lines
+      }
+      elsif ($biosLine =~ /Serial Number:/)
+      {
+        if ($sn_state == "0")
+        {
+          $serial_number = $biosLine;
+          $serial_number =~ s/\s+Serial Number:\s+//; chomp $serial_number;
+          
+          if ($debug eq "yes")
+          {
+            print ("$serial_number \n");
+          }
+          $sn_state = "1";
+        }
+        else {next;} # don't waste time with other lines
+      }
+      elsif ($biosLine =~ /UUID:/)
+      {
+        if ($uu_state == "0")
+        {
+          $uuid = $biosLine;
+          $uuid =~ s/\s+UUID:\s+//; chomp $uuid;
+
+          if ($debug eq "yes")
+          {
+            print ("$uuid \n");
+          }
+          $uu_state = "1";
+        }
+        else {next;} # don't waste time with other lines
+      }
+    }
+  }
+  else
+  # Welcome to Parse::dmidecode world
+  {
+    $dmi_decoder->parse( qx(ssh $host dmidecode) );
+    $product_name = $dmi_decoder->keyword("system-product-name");
+    $serial_number = $dmi_decoder->keyword("system-serial-number");
+    $uuid = $dmi_decoder->keyword("system-uuid");
+  }
+  # save this to yaml
+  $yaml->[0]->{parameters}->{productname} = $product_name;
+  $yaml->[0]->{parameters}->{serialnumber} = $serial_number;
+  $yaml->[0]->{parameters}->{uuid} = $uuid;
+  
+  if ($debug eq "yes")
+  {
+    print ("$host: $product_name ; $serial_number ; $uuid ; $os \n");
+  }
+  if ( $log eq "yes" )
+  {
+    $logline->log_print("$host: $product_name ; $serial_number ; $uuid ; $os \n");
+  }
+}
+
+sub getIfConfig
+# ask host for IPv4 IF informations
+# &getIfConfig($host,$os);
+{
+  my $host = $_[0];
+  my $os = $_[1];
+  my @ifname = ();
+  my @ifip = ();
+  my @iftype = (); # for future uses (maybe...)
+  my @ifmac = ();
+  my $ifNstate = (my $ifIstate = (my $ifTstate = (my $ifMstate = "0")));
+  my @ifconfigRaw = ();
+  my $ifconfigLine = "";
+  my $ifylist = "";
+
+  if ($os eq "sun")
+# specific sort/regexp for SunOS, ifconfig output's not "standard"
+  {
+    @ifconfigRaw = qx(ssh uroot\@$host ifconfig -a);
+
+    foreach $ifconfigLine (@ifconfigRaw)
+    {
+      if ($ifconfigLine =~ /^(\S+)\:/)
+      { 
+        if ($ifconfigLine =~ /^lo/) 
+        # interface is local, don't keep
+        {
+          next;
+        }
+        elsif ($ifconfigLine =~ /^(\S+\:[0-9]{1})\:(\s+)/)
+        # interface is an alias, doesn't have MAC
+        {
+          $ifname[$ifNstate] = $1;
+          $ifname[$ifNstate] =~ s/\:/\./; # ":" is yaml reserved, so we use "."
+          $iftype[$ifTstate] = "Ethernet";
+          $ifmac[$ifMstate] = $ifmac[$ifMstate-1];
+
+          if ($debug eq "yes")
+          {
+            print ("$host: $ifname[$ifNstate] \n");
+            print ("$host: $iftype[$ifTstate] = $ifmac[$ifMstate] \n");
+          }
+          if ( $log eq "yes" )
+          {
+            $logline->log_print("$host: $ifname[$ifNstate] ; $iftype[$ifTstate] ; $ifmac[$ifMstate] \n");
+          }
+
+          $ifNstate++;
+          $ifTstate++;
+          $ifMstate++;
+        }
+        else
+        # assume real interface
+        {
+          $ifname[$ifNstate] = $1;
+
+          if ($debug eq "yes")
+          {
+            print ("$host: $ifname[$ifNstate] \n");
+          }
+          if ( $log eq "yes" )
+          {
+            $logline->log_print("$host: $ifname[$ifNstate] \n");
+          }
+          $ifNstate++;
+        }
+      }
+      elsif ($ifconfigLine =~ /inet (?:addr\:)?(\d+(?:\.\d+){3})/ )
+      {
+        if ($1 =~ /127\.0\.0\.1/)
+        # IP is local, don't keep
+        {
+          next;
+        }
+        else
+        {
+          $ifip[$ifIstate] = $1;
+
+          if ($debug eq "yes")
+          {
+            print ("$host: $ifip[$ifIstate] \n");
+          }
+          if ( $log eq "yes" )
+          {
+            $logline->log_print("$host: $ifip[$ifIstate] \n");
+          }
+          $ifIstate++;
+        }
+      }
+      elsif ($ifconfigLine =~ /(\s+)ether(\s+)/)
+      # real interface have MAC
+      {
+        $iftype[$ifTstate] = "Ethernet";
+        $ifconfigLine =~ s/\s+ether\s+//; chomp $ifconfigLine;
+        $ifmac[$ifMstate] = $ifconfigLine;
+        $ifmac[$ifMstate] =~ s/\s+$//; # remove trailing spaces, chomp does not make it.
+
+        if ($debug eq "yes")
+        {
+          print ("$host: $iftype[$ifTstate] = $ifmac[$ifMstate] \n");
+        }
+        if ( $log eq "yes" )
+        {
+          $logline->log_print("$host: $iftype[$ifTstate] ; $ifmac[$ifMstate] \n");
+        }
+        $ifTstate++;
+        $ifMstate++;
+      }
+      else {next;} # don't waste time with other lines
+    }
+  }
+  else
+  # welcome to "linux compliant" ifconfig output
+  # cpan really lacks a Parse::ifconfig :o)
+  {
+    @ifconfigRaw = qx(ssh $host ifconfig);
+
+    foreach $ifconfigLine (@ifconfigRaw)
+    {
+      if ($ifconfigLine =~ /^(\S+)/)
+      {
+        if ($ifconfigLine =~ /^lo/)
+        # interface is local, don't keep
+        {
+          next;
+        }
+        elsif ($ifconfigLine =~ /^(\S+(?:\:)?[0-9]{1}) (\s+)/ )
+        # interface is real or alias
+        {
+          $ifname[$ifNstate] = $1;
+          $ifname[$ifNstate] =~ s/\:/\./; # ":" is yaml reserved, so we use "."
+
+          if ($ifconfigLine =~ /Link encap:(.+)\s+HWaddr\s+(\S+)/ )
+          # hardware address
+          {
+            $iftype[$ifTstate] = $1; chomp $iftype[$ifTstate];
+# TODO filter infiniband... if infiniband: next; else: keep;
+            $ifmac[$ifMstate] = $2;
+          }
+
+          if ($debug eq "yes")
+          {
+            print ("$host: $ifname[$ifNstate] \n");
+            print ("$host: $iftype[$ifTstate] = $ifmac[$ifMstate] \n");
+          }
+          if ( $log eq "yes" )
+          {
+            $logline->log_print("$host: $ifname[$ifNstate] ; $iftype[$ifTstate] ; $ifmac[$ifMstate] \n");
+          }
+
+          $ifNstate++;
+          $ifTstate++;
+          $ifMstate++;
+        }
+      }
+      elsif ($ifconfigLine =~ /inet (?:addr\:)?(\d+(?:\.\d+){3})/ )
+      {
+        if ($1 =~ /127\.0\.0\.1/)
+        # do not want local IP
+        {
+          next;
+        }
+        else
+        {
+          $ifip[$ifIstate] = $1;
+          
+          if ($debug eq "yes")
+          {
+            print ("$host: $ifip[$ifIstate] \n");
+          }
+          if ( $log eq "yes" )
+          {
+            $logline->log_print(" ");
+          }
+
+          $ifIstate++;
+        }
+      }
+      else {next;} # don't waste time with other lines
+    }
+  }
+
+  if ($debug eq "yes")
+  {
+    print Dumper(@ifname);
+    print Dumper(@ifip);
+    print Dumper(@iftype);
+    print Dumper(@ifmac);
+  }
+
+# save this to yaml
+# $yaml->[0]->{parameters}->{interfaces} is a list
+# other network parameters are {interfaces} dependant
+  foreach my $i (0 .. $#ifname)
+  {
+    $ifylist = "$ifylist"."${ifname[$i]},";
+    print ("$ifylist \n");
+    my $foo = "ipaddress_"."${ifname[$i]}";
+    $yaml->[0]->{parameters}->{$foo} = $ifip[$i];
+    my $bar = "macaddress_"."${ifname[$i]}";
+    $yaml->[0]->{parameters}->{$bar} = $ifmac[$i];
+  }
+  $ifylist =~ s/,$//; # remove trailing comma
+  $yaml->[0]->{parameters}->{interfaces} = $ifylist ;
+
+  if ($debug eq "yes")
+  {
+    print Dumper($yaml);
+  }
+  if ( $log eq "yes" )
+  {
+  # TODO rewrite this, no need to dump in logs
+  my $yodump = Dumper($yaml);
+  $logline->log_print("$host: $yodump");
+  }
+}
+
+sub getDate
+# return date in human-readable format for logs
+{
+  my $result = `date +%Y%m%d-%H:%M`;
+  chomp($result);
+  return $result;
+}
+
diff --git a/yaml_import/dl165lin3.yaml b/yaml_import/dl165lin3.yaml
new file mode 100644 (file)
index 0000000..44ceacf
--- /dev/null
@@ -0,0 +1,17 @@
+--- this line must be here and will be ignored
+  name: dl165lin3 
+  parameters:
+    fqdn: dl165lin3.ens-lyon.fr
+    productname: ProLiant DL165 G5
+    serialnumber: GB8905H5X7
+    uuid: 00591336-D21D-B211-8000-001F29E77084
+    operatingsystem: CentOS release 5.4 (Final) 
+    operatingsystemrelease: 5.4
+    interfaces: "eth0,eth1,ib0"
+    macaddress_eth0: 00:1F:29:E7:70:84
+    macaddress_eth1: 00:1F:29:E7:70:85
+    macaddress_ib0: 
+    ipaddress_eth0: 172.16.165.3
+    ipaddress_eth1: 10.20.165.3
+    ipaddress_ib0: 10.50.165.3
+
index 1b715c2..3ea2541 100644 (file)
@@ -1,17 +1,20 @@
 <?php
 //
 // Puppets YAML import
-// Version 0.1
+// Version 0.2
 //
 // Written by Tommy Botten Jensen
+//   Modified by Loïs Taulelle
 //
 // The purpose of this plugin is to automatically import objects from puppets YAML files.
 // History
 // Version 0.1:  Initial release
+// Version 0.2:  Adaptation to 0.19.x, with additionnal specs from PSMN (see skel.yaml)
+// $Id: yaml_import.php 106 2011-05-24 09:51:36Z gruiick $
 //
 // Installation:
 // 1)  Copy script to inc folder as yaml_import.php
-// 2)  Add include to inc/local.php: include("yaml_iplog.php");
+// 2)  Add include to inc/local.php: include("yaml_import.php");
 // 3)  Include the 'spyc.php' into inc/ . Get it from http://code.google.com/p/spyc/
 
 # YAML Parser library.
@@ -22,10 +25,10 @@ require_once 'inc/spyc.php';
 $tab['depot']['yaml_import'] = 'Import objects';
 $tabhandler['depot']['yaml_import'] = 'ImportTab';
 $ophandler['depot']['yaml_import']['RunImport'] = 'RunImport';
-
+//$ophandler['depot']['addmore']['addLotOfObjects'] = 'addLotOfObjects'; # ref
 
 // Set variables
-$Version = "0.1";
+$Version = "0.2";
 $username = $_SERVER['PHP_AUTH_USER'];
 $nextorder['odd'] = 'even';
 $nextorder['even'] = 'odd';
@@ -34,212 +37,292 @@ $nextorder['even'] = 'odd';
 function RunImport()
 {
   $objectnames = $_POST['objectname'];
+
   global $dbxlink;
   global $username;
+//  global $taglist;
+  $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
   $log = emptyLog();
 
-  foreach($objectnames as $objectname) {
-   // FIXME: This reads the entire directory for each object. Not very efficient.
-   if ($handle = opendir('./yamls/')) {
-      while (false !== ($file = readdir($handle))) {
-        # puppet names the files $FQDN.yaml
-        if($file == $objectname . ".yaml") {
-            # SPYC is not happy with the puppet header. Hence read it as string, strip the header and feed it to SPYC
-            $file_contents = file_get_contents("./yamls/$file");
-            $file_contents = substr($file_contents, (strpos($file_contents, "\n")+1));
-            
-            # I Also remove all entries with ID00X seems to annoy SPYC.
-            $file_contents = preg_replace('/\*id00/','',$file_contents);
-    
-            $yaml_file_array = Spyc::YAMLLoadString($file_contents);
-           // FIXME: Is this the correct way to narrow in on an array?
-           // At this point, $yaml_file_array contains all the data from the YAML files in a indexed array.
-           $yaml_file_array = $yaml_file_array['parameters'];
-           
-          $object = getSearchResultByField
-               (
-                       'RackObject',
-                       array ('id'),
-                       'name',
-                       $objectname,
-                       '',
-                       2
-               );
-  
-          if($object) {
-               # Object exists. Modify.
-               $id = $object[0]['id']; 
-                       $log = mergeLogs ($log, oneLiner (202, array ("$objectname exists.Modification not yet implemented ")));
-          }
-  
-          else {
-               // Object does not exist. Create new.
-               //Syntax: commitAddObject ($new_name, $new_label, $new_barcode, $new_type_id,$new_asset_no, $taglist = array())
-               // Type is 4, server.
-            $new_yamlobject = commitAddObject ($yaml_file_array['fqdn'],'','',4,$yaml_file_array['serialnumber']);
-
-               // Hardware type. i.e. ProLiant DL380 G6a
-       $hw_dict_key = getdict($hw=$yaml_file_array['productname'], $chapter=11 );
-               commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '2', $value = $hw_dict_key);
-       // Operating system string. I.e. 
-               $osrelease = $yaml_file_array['operatingsystem'] . $yaml_file_array['operatingsystemrelease'];
-               $os_dict_key = getdict($hw=$osrelease, $chapter=13);
-               commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '4', $value = $os_dict_key);
-
-       // FIXME: The IDs should be looked up, and not preset.
-      // Architecture. Attribute ID is '10000'.
-       commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '10000', $value = $yaml_file_array['hardwareisa']);
-      // Memory. Attribute ID is 17.
-       commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '17', $value = (int)$yaml_file_array['memorysize']);
-      // CPU. Attribute ID is 100001
-       $cpu = $yaml_file_array['processorcount'] . " x " . $yaml_file_array['processor0'];
-       commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '10001', $value = $cpu);
-      // FQDN. Attribute ID is '3'.
-       commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '3', $value = $yaml_file_array['fqdn']);
-
-       // NICS
-       $nics = explode(',',$yaml_file_array['interfaces'],9);
-       $count = count($nics);
-       
-       for ($i = 0; $i < $count; $i++) {
-        // We generally don't monitor sit interfaces.
-         if ($nics[$i] == "sit0")
-               break;
-       
-         if (isset($yaml_file_array['ipaddress_' . $nics[$i]]))
-                 $ip = $yaml_file_array['ipaddress_' . $nics[$i]];
-         if (isset($yaml_file_array['macaddress_' . $nics[$i]]))
-               $mac = $yaml_file_array['macaddress_' . $nics[$i]];
-               // Add a port to an object. Type 24 is 1000Base-T       
-         commitAddPort($object_id = $new_yamlobject, $nics[$i], 24,'Ethernet port',"$mac");
-               // Add an IP to an object.
-          if($ip) {
-           bindIpToObject($ip , $new_yamlobject, $nics[$i],'regular');
+  foreach($objectnames as $objectname) 
+  {
+  // FIXME: This reads the entire directory for each object. Not very efficient.
+    if ($handle = opendir('./yamls/'))
+    {
+      while (false !== ($file = readdir($handle)))
+      {
+        # puppet names the files $FQDN.yaml, not PSMN
+        if($file == $objectname . ".yaml") 
+        {
+          # SPYC is not happy with the puppet header. Hence read it as string, strip the header and feed it to SPYC
+          $file_contents = file_get_contents("./yamls/$file");
+          $file_contents = substr($file_contents, (strpos($file_contents, "\n")+1));
+
+          $yaml_file_array = Spyc::YAMLLoadString($file_contents);
+               // FIXME: Is this the correct way to narrow in on an array?
+               // At this point, $yaml_file_array contains all the data from the YAML files in a indexed array.
+          $yaml_name = $yaml_file_array['name'];
+               // switch to the 2nd part of the array
+          $yaml_file_array = $yaml_file_array['parameters'];
+
+               // getSearchResultByField ($tname, $rcolumns, $scolumn, $terms, $ocolumn = '', $exactness = 0|1|2)
+          $object = getSearchResultByField
+          (
+            'RackObject',
+            array ('id'),
+            'name',
+            $yaml_name,
+            '',
+            2
+          );
+
+          if($object) 
+          {
+            # Object exists. Do NOT modify.
+            $id = $object[0]['id'];    
+            $log = mergeLogs ($log, oneLiner (202, array ("$objectname exists. No modifications!")));
           }
-         unset($ip);
-         unset($mac);
-         }
-
-               // Create a URL for the log message.
-           $url=makeHref (array (
-                    'page' => 'object',
-                    'tab' => 'default',
-                    'object_id' => $new_yamlobject
+
+          else 
+          {
+            // Object does not exist. Create new.
+            // Syntax: commitAddObject ($new_name, $new_label, $new_type_id, $new_asset_no, $taglist = array())
+            // Type is 4, server, by default.
+            $new_yamlobject = commitAddObject ($yaml_name,'',4,$yaml_file_array['serialnumber'],$taglist = array());
+
+            // Hardware type (i.e. ProLiant DL380 G6a), Dict Chapter ID is '11';
+            $hw_dict_key = getdict($hw=$yaml_file_array['productname'], $chapter=11 );
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '2', $value = $hw_dict_key);
+            // Operating system string, Dict Chapter ID is '13'.
+            $osrelease = $yaml_file_array['operatingsystem'] . " " . $yaml_file_array['operatingsystemrelease'];
+            $os_dict_key = getdict($hw=$osrelease, $chapter=13);
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '4', $value = $os_dict_key);
+/*
+            // FIXME: The IDs should be looked up, and not preset.
+            // Architecture. Attribute ID is '10000'.
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '10000', $value = $yaml_file_array['hardwareisa']);
+            // Memory. Attribute ID is 17.
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '17', $value = (int)$yaml_file_array['memorysize']);
+            // CPU. Attribute ID is 100001
+            $cpu = $yaml_file_array['processorcount'] . " x " . $yaml_file_array['processor0'];
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '10001', $value = $cpu);
+*/
+            // OEM S/N 1. Attribute ID is '1'.
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '1', $value = $yaml_file_array['serialnumber']);
+            // FQDN. Attribute ID is '3'.
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '3', $value = $yaml_file_array['fqdn']);
+            // UUID. Attribute ID is '25'.
+            commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '25', $value = $yaml_file_array['uuid']);
+            // Hypervisor. Attribute ID is '26', Dict Chapter ID is '29'.
+            // Hypervisor key does not exist in standard Puppet yaml file, added by PSMN
+            if(isset($yaml_file_array['hypervisor'])) 
+            {
+              $hv_dict_key = getdict($hw=$yaml_file_array['hypervisor'], $chapter=29);
+              commitUpdateAttrValue ($object_id = $new_yamlobject, $attr_id = '26', $value = $hv_dict_key);
+            }
+
+            // NICS
+// Warning! This part only work if default Configuration is modified
+// Go to "MainPage -> Configuration -> User Interface"
+// Modify "AutoPorts configuration": Change "4 = 1*33*kvm + 2*24*eth%u;15 = 1*446*kvm" to "15 = 1*446*kvm"
+// Ref: http://www.freelists.org/post/racktables-users/Automatic-insertions-of-servers-in-the-db,7
+
+            $nics = explode(',',$yaml_file_array['interfaces'],9);
+            $count = count($nics);
+
+            for ($i = 0; $i < $count; $i++) 
+            {
+              switch ($nics[$i])
+              {
+              case "sit0":
+                break 1;
+
+              case "ib0": // infiniband
+                if (isset($yaml_file_array['ipaddress_' . $nics[$i]]))
+                {
+                  $ip = $yaml_file_array['ipaddress_' . $nics[$i]];
+                }
+// do NOT import infiniband MAC for now
+//                if (isset($yaml_file_array['macaddress_' . $nics[$i]]))
+//                {
+//                  $mac = $yaml_file_array['macaddress_' . $nics[$i]];
+//                }
+                // Add port to object. Type 40 is 10GBase-CX4, MAC can be NULL
+                commitAddPort($object_id = $new_yamlobject, $nics[$i], 40,'infiniband',$mac);    
+                // Add IP to object.
+                if(isset($ip)) 
+                {
+                  bindIpToObject($ip , $new_yamlobject, $nics[$i],'regular');
+                }
+                break 1;
+
+              default:
+                if (preg_match("eth", $nics[$i]) === 0) break 1; 
+                # this one might be bad for non-linux OSes ?
+                if (isset($yaml_file_array['ipaddress_' . $nics[$i]]))
+                {
+                  $ip = $yaml_file_array['ipaddress_' . $nics[$i]];
+                }
+                if (isset($yaml_file_array['macaddress_' . $nics[$i]]))
+                {
+                  $mac = $yaml_file_array['macaddress_' . $nics[$i]];
+                }
+                // Add port to object. Type 24 is 1000Base-T   
+                commitAddPort($object_id = $new_yamlobject, $nics[$i], 24,'Ethernet port',"$mac");
+                // Add IP to object.
+                if(isset($ip)) 
+                {
+                  bindIpToObject($ip , $new_yamlobject, $nics[$i],'regular');
+                }
+                break 1;
+
+              }
+              unset($ip);
+              unset($mac);
+            }
+
+            // Create a URL for the log message.
+            $url=makeHref (array (
+              'page' => 'object',
+              'tab' => 'default',
+              'object_id' => $new_yamlobject
             ));
-               $loginstance = "<a href=\"$url\">" . $objectname .  "</a>";
-               $log = mergeLogs ($log, oneLiner (80, array ("$loginstance")));
-          }
-  
+            $loginstance = "<a href=\"$url\">" . $objectname .  "</a>";
+            $log = mergeLogs ($log, oneLiner (80, array ("$loginstance")));
+          }
         }
       }
     }
   }
-  return buildWideRedirectURL ($log);
+  return showSuccess ($log);
 }
 
 // Display the import page.
 function ImportTab()
 {
-    global $nextorder;
-    global $username;
-    global $Version;
+  global $nextorder;
+  global $username;
+  global $Version;
+  global $taglist;
 ?>
 
-<style type='text/css'>
-tr.has_problems {
-background-color: #ffa0a0;
-}
-</style>
+  <style type='text/css'>
+  tr.has_problems 
+  {
+    background-color: #ffa0a0;
+  }
+  </style>
 
-<table align=right>
-  <tr class=trerror><td>Non-existing object: </td></tr>
-</table>
+  <table align=right>
+  <tr class=trerror><td>Unknown object</td></tr>
+  <tr class=row_odd><td>Existing object</td></tr>
+  </table>
 
-<center><h1>Import puppet objects</h1><h2>yaml objects from ./yaml/</h2></center>
+  <center><h1>Import yaml objects </h1><h2>from /yamls/</h2></center>
 <?php
-    startPortlet();
-    echo "<table with=90% align=center border=0 cellpadding=5 cellspacing=0 align=center class=cooltable><tr valign=top>";
-    echo "<form method=post name=ImportObject action='process.php?page=depot&tab=yaml_import&op=RunImport'>";
-    echo "<tr><th align=center>Name</th><th align=center>Import?</th></tr>";
-    $order = 'odd';
-    # Find and read loop through all .yaml files in the yaml directory.
-    if ($handle = opendir('./yamls/')) {
-       while (false !== ($file = readdir($handle))) {
-        # Since puppet names the files $FQDN.yaml, we don't have to inspect the file during the first run.
-         if(preg_match('/\.yaml/',$file)) {
-          $name = preg_replace('/\.yaml/','',$file);
-          # Do a search on the row 'name' passing the one name, and retrieving the ID.
-          $object = getSearchResultByField
-               (
-                       'RackObject',
-                       array ('id'),
-                       'name',
-                       $name,
-                       '',
-                       2
-               );
-
-          if($object) {
-       $url=makeHref (array (
-                'page' => 'object',
-                'tab' => 'default',
-                'object_id' => $object[0]['id']
-        ));
-
-          echo "<tr class=row_${order}><td align=left><a href=\"$url\">" . $name .  "</a></td>\n";
-          }
-
-          else {
-          echo "<tr class=trerror><td align=left>" . $name . "</td>\n";
-          }
-          echo "<td align=center> <input type=checkbox name=objectname[] value=$name></td></tr>\n";
-           $order = $nextorder[$order];
-
-        }
-       }
+  startPortlet();
+  echo "<table with=90% align=center border=0 cellpadding=5 cellspacing=0 align=center class=cooltable><tr valign=top>";
+
+// add taglist on display - left handed
+//  echo "<tr><th align=center>Assign tags</th></tr><tr><td rowspan=\"0\">";
+//  renderNewEntityTags('object');
+//  echo "</td></tr>";
+
+  echo "<form method=post name=ImportObject action='?module=redirect&page=depot&tab=yaml_import&op=RunImport'>";
+  echo "<tr valign=top><th align=center>Name</th><th align=center>Import ?</th></tr>";
+
+  $order = 'odd';
+  # Find and read loop through all .yaml files in the yaml directory.
+//  if ($handle = opendir('./yamls/'))
+  if ($files = scandir('./yamls/'))  
+  {
+//    while (false !== ($file = readdir($handle))) 
+    foreach($files as $file)
+    {
+      # Since puppet names the files $FQDN.yaml, we don't have to inspect the file during the first run.
+      if(preg_match('/\.yaml/',$file)) 
+      {
+        $name = preg_replace('/\.yaml/','',$file);
+        # Do a search on the row 'name' passing the one name, and retrieving the ID.
+        $object = getSearchResultByField
+        (
+          'RackObject',
+          array ('id'),
+          'name',
+          $name,
+          '',
+          2
+        );
+
+        if($object) 
+        {
+          $url=makeHref 
+          (array 
+            (
+              'page' => 'object',
+              'tab' => 'default',
+              'object_id' => $object[0]['id']
+            )
+          );
+
+          echo "<tr class=row_${order}><td align=left><a href=\"$url\">" . $name .  "</a></td>\n";
+        }
+        else 
+        {
+          echo "<tr class=trerror><td align=left>" . $name . "</td>\n";
+        }
+        echo "<td align=center> <input type=checkbox name=objectname[] value=$name></td></tr>\n";
+        $order = $nextorder[$order];
+      }
     }
+  }
 
-    echo "</select>";
-    echo "</th>";
-    echo "<tr><td align=left><font size=1em color=gray>version ${Version}</font></td><td align=right><input type=submit name=got_very_fast_data value='Import selected items'></td></tr></table></td></tr>";
-    echo "</form>";
-    echo "</table>";
-    finishPortlet();
+  echo "<tr><td align=left><font size=1em color=gray>version ${Version}</font></td><td align=right><input type=submit name=got_very_fast_data value='Import selected items'></td><td></td></tr></table></td></tr>";
+  echo "</form>";
+  echo "</table>";
+  finishPortlet();
 }
 
 // Gets the dict_key for a specified chapter_id . If it does not exist, we create a dictionary entry.
-function getdict ($hw,$chapter) {
-try {
-  global $dbxlink;
-  $query = "select dict_key from Dictionary where chapter_id='$chapter' AND dict_value ='$hw' LIMIT 1";
-  $result = usePreparedSelectBlade ($query);
-  $array = $result->fetchAll (PDO::FETCH_ASSOC);
+// a bit redundant with existing dict entries, won't hurt.
+// Table Dictionary: (chapter_id,dict_key,'dict_value')
+function getdict ($hw,$chapter) 
+{
+  try 
+  {
+    global $dbxlink;
+    $query = "select dict_key from Dictionary where chapter_id='$chapter' AND dict_value LIKE '%$hw%' LIMIT 1";
+    $result = usePreparedSelectBlade ($query);
+    $array = $result->fetchAll (PDO::FETCH_ASSOC);
 
-  if($array) {
-    return $array[0]['dict_key'];
-  }
-  else {
-       // Chapter ID for hardware is 11.
-    $dbxlink->exec("INSERT INTO Dictionary (chapter_id,dict_value) VALUES ('$chapter','$hw')");
-    
-    $squery = "select dict_key from Dictionary where dict_value ='$hw' AND chapter_ID ='$chapter' LIMIT 1";
-    $sresult = usePreparedSelectBlade ($squery);
-    $sarray = $sresult->fetchAll (PDO::FETCH_ASSOC);
-  
-    if($sarray) {
-      return $sarray[0]['dict_key'];
+    if($array) 
+    {
+      return $array[0]['dict_key'];
     }
-  
-    else {
+    else 
+    {
+      $dbxlink->exec("INSERT INTO Dictionary (chapter_id,dict_value) VALUES ('$chapter','$hw')");
+    
+      $squery = "select dict_key from Dictionary where dict_value ='$hw' AND chapter_ID ='$chapter' LIMIT 1";
+      $sresult = usePreparedSelectBlade ($squery);
+      $sarray = $sresult->fetchAll (PDO::FETCH_ASSOC);
+
+      if($sarray) 
+      {
+        return $sarray[0]['dict_key'];
+      }
+      else 
+      {
        // If it still has not returned, we are up shit creek. 
-      return 0;
+        return 0;
+      }
     }
+    $dbxlink = null;
   }
-  $dbxlink = null;
-}
-catch(PDOException $e)
-    {
+  catch(PDOException $e)
+  {
     echo $e->getMessage();
-    }
+  }
 }
 ?>
+
diff --git a/yaml_import/skel.yaml b/yaml_import/skel.yaml
new file mode 100644 (file)
index 0000000..4a09e11
--- /dev/null
@@ -0,0 +1,16 @@
+--- this line must be here and will be ignored ; filename must be hostname ; fqdn: must contain full fqdn ; $Id: skel.yaml 105 2011-05-20 10:09:22Z gruiick $
+name: 
+parameters:
+  fqdn: 
+  productname: 
+  serialnumber: 
+  uuid: 
+  operatingsystem: 
+  operatingsystemrelease: 
+  hypervisor: Yes|No 
+  interfaces: i1,i2,i3
+  macaddress_i1:
+  macaddress_i3:
+  ipaddress_i1:
+  ipaddress_i2:
+  ipaddress_i3: