Benutzer:Kirmse/delixs-pooladd

Aus Delixs
Zur Navigation springen Zur Suche springen

delixs-pooladd

  • Dieses Script dient dazu, im LDAP Pools einzutragen
  • Parameter: --pool oder -p, --tnetz oder -t, --nummer oder -n, --range oder -r
  • Aufruf: delixs-pooladd -p mathe -t 10.101.0.0 -n 4 -r 50:150

das Teilnetz muss normalerweise nicht angegeben werden. Voreinstellung ist '10.100.0.0'. Dieser Parameter ist nur dazu da, damit dieses Script (später) auch dann genutzt werden kann, wenn weitere echte Netzwerkkarten eingebaut wurden.

Der Parameter --nummer gibt die "Poolnummer" an. Auch dieser sollte nicht angegeben werden, weil das Script die vorhandenen Pools ermittelt und die größte Poolnummer herauszieht. Diese wird normalerweise um 1 erhöht und als Poolnummer genommen.

Auch der Poolbereich sollte normalerweise nicht angegeben werden. Es wird als Voreinstellung 100:200 genommen.

Für dieses Beispiel würde als dhcpRange 10.101.4.50 10.101.4.150 eingetragen.


das Script

<source lang="perl">

  1. !/usr/bin/perl

use warnings; use strict;

use Net::LDAP; use Getopt::Long;

my ($ldap, $ldap_base, $pass, $entry, $mesg, $poolname, $range, $poolnumber,

   $teilnetz, $tn, $vorgabe_teilnetz, $vorgabe_range, $vorgabe_nummer,
   $min, $max, @numbers, $temp, @temp, $anzahl, $rangemin, $rangemax);


  1. --------- Konfigurationsbereich --------------------------------------------

$vorgabe_teilnetz = '10.100.0.0'; # Vorgabe fuer das Teilnetz $vorgabe_range = '100:200'; # Vorgabe fuer den Poolbereich $vorgabe_nummer = 1; # Vorgabe fuer den ersten Pool

  1. ----------------------------------------------------------------------------


  1. Initialisieren der Variablen fuer die Parameter

$poolname = ; $teilnetz = ; $poolnumber = ; $range = ;

  1. wir holen uns zuerst die Parameter,
  2. falls --help, dann Ausgabe der Hilfe (siehe &help) und beenden

GetOptions('pool=s' => \$poolname,

          'tnetz=s'  => \$teilnetz,
          'nummer=i' => \$poolnumber,
          'range=s'  => \$range,       # z.B. 100:200  
          'help'     => \&help);


  1. --------- formale Ueberpruefung der uebergebenen Parameter -----------------
  1. Wenn kein Parameter -p oder --poolname uebergeben wurde, dann Abbruch

if ($poolname eq ) {

 die "Abbruch: es wurde kein Name fuer die Rechnergruppe uebergeben!\n";

}

  1. Wenn der Poolname nicht den (meinen) Konventionen entspricht, dann Abbruch

unless ($poolname =~ /^[a-zA-Z]\w{1,10}$/) {

 die "Abbruch: Der Name fuer die Rechnergruppe ist nicht korrekt!\n";

}

  1. Wenn Parameter Teilnetz uebergeben, dann kontrollieren

unless ($teilnetz eq ) {

 # ob richtiges Format 
 unless ($teilnetz =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.0$/) {
   die "Abbruch: Das Teilnetz $teilnetz ist keine gueltige Angabe!\n"
 }

}

  1. Wenn der Parameter nicht uebergeben

else {

 # dann setzen wir das Teilnetz
 $teilnetz = $vorgabe_teilnetz;  

}

  1. wenn Parameter Poolnummer uebergeben, dann kontrollieren

unless ($poolnumber eq ) {

 # ob richtiges Format (eine max. 3stellige Zahl)
 unless ($poolnumber =~ /^\d{1,3}$/) {
   die "Abbruch: Die Poolnummer $poolnumber ist keine gueltige Angabe!\n"
 }
 # Test, ob Wert groesser 0
 unless ($poolnumber > 0) {
   die "Abbruch: Poolnumber muss groesser 0 sein!\n"
 }
 # Test, ob Wert kleiner 255 
 unless ($poolnumber < 255) {
   die "Abbruch: Poolnumber muss kleiner 255 sein!\n"
 }

}

  1. Wenn Parameter $range uebergeben, dann kontrollieren,

unless ($range eq ) {

 # ob richtiges Format (zwei max. dreistellige Zahlen)
 unless ($range =~ /^\d{1,3}:\d{1,3}$/) {
   die "Abbruch: Der DHCP-Range ist nicht im richtigen Format angegeben!\n"
 }
 
 # wir zerlegen die Eingabe
 ($min,$max) = split /:/, $range;
 # Test, ob beide Werte groesser 0 
 unless ($min > 0 and $max > 0) {
   die "Abbruch: Beide Werte muessen groesser 0 sein!\n"
 }
 # Test, ob beide Werte kleiner 255 
 unless ($min < 255 and $max < 255) {
   die "Abbruch: Beide Werte muessen kleiner 255 sein!\n"
 }
 # Test, ob der kleinere Wert zuerst steht 
 unless ($min < $max) {
   die "Abbruch: der erste Wert muss kleiner als der zweite sein!\n"
 }

}

  1. Wenn kein Parameter uebergeben

else {

 # dann setzen wir den Bereich
 $range = '100:200';  

}


  1. ----------- Arbeiten mit Dateien (ldap.conf, ldap.secret) -----------------
  1. Wenn wir keine root-Rechte haben, dann Abbruch

if ($> != 0) { # siehe $EFFECTIVE_USER_ID,$EUID

 die "Abbruch: das Script muss mit root-Rechten ausgefuehrt werden!\n";

}

  1. wir holen uns die Such-Basis ($ldap_base) aus der ldap.conf

open DATEI, '<', '/etc/ldap/ldap.conf'

 or die "Abbruch: konnte ldap.conf nicht oeffnen, $!\n";

while (my $zeile = <DATEI>) {

 if ($zeile =~ m/^\s*base\s+(\w.*\w)\s*$/i) {
   $ldap_base = $1;
   last;
 }

} close DATEI;

  1. da wir (spaeter) in den LDAP schreiben wollen, brauchen wir noch das Passwort

open DATEI, '<', '/etc/ldap.secret'

 or die "Abbruch: konnte ldap.secret nicht oeffnen, $!\n";

$pass = <DATEI>; chomp($pass); close DATEI;


  1. ------------- Ueberpruefungen im LDAP --------------------------------------
  1. wir verbinden uns mit dem LDAP

$ldap = Net::LDAP->new('127.0.0.1', version => 3) or die "Abbruch: $@"; $ldap->bind( dn => "cn=admin, $ldap_base", password => $pass)

 or die "Abbruch: konnte mich nicht mit dem LDAP verbinden";
  1. wir ueberpruefen, ob das Teilnetz im LDAP existiert

$mesg = $ldap->search(base => "cn=$teilnetz,cn=DHCP Config,$ldap_base",

                     filter => "cn=$teilnetz",
                     attrs  => 'dhcpNetMask' );

$mesg->code and die $mesg->error;

  1. wenn wir keinen Eintrag erhalten haben, dann Abbruch

if (scalar ($mesg->entries) == 0) {

 die "Abbruch: Das Teilnetz $teilnetz existiert nicht im LDAP!\n";

}

  1. Wir ueberpruefen, ob der Poolname schon verwendet wird
  2. es wird ganz bewusst diese Suchbasis verwendet, um alle Teilnetze zu erfassen

$mesg = $ldap->search(

         base   => "cn=DHCP Config,$ldap_base", 
         filter => "cn=$poolname" );
  1. wenn Fehlercode, dann das Script mit Fehlermeldung sterben lassen

$mesg->code and die $mesg->error;

  1. Wenn der DN gefunden wird dann Abbruch

if (scalar ($mesg->entries) > 0) {

 die "Abbruch: Der Poolname $poolname wird schon verwendet!\n";

}

  1. wir holen uns von dem Teilnetz von allen Pools die dhcpRanges

$mesg = $ldap->search(

         base   => "cn=$teilnetz,cn=DHCP Config,$ldap_base", 
         filter => 'objectClass=dhcpPool',
         attrs  => 'dhcpRange' );
  1. wenn Fehlercode, dann das Script mit Fehlermeldung sterben lassen

$mesg->code and die $mesg->error;

  1. dann holen wir uns von allen dhcpRange-Eintraegen den Min-Wert

@numbers = (); if (scalar $mesg->entries > 0) {

 foreach my $entry ($mesg->entries) {
   $temp = $entry->get_value('dhcpRange');
   @temp = split /\s+/, $temp;              # am Leerzeichen trennen
   if ($temp[0] =~ /^\d{1,3}\.\d{1,3}\.(\d{1,3})\.\d{1,3}$/) {
     push @numbers, $1; 
   } 
 }               

}

  1. wenn keine Poolnummer angegeben wurde, dann

if ($poolnumber eq ) {

 # dann sortieren wir die Liste, groesste Zahl ist vorn  
 @numbers = sort { $b <=> $a } @numbers;
 if (scalar @numbers == 0) {
   $poolnumber = 1;
 }
 else {
   $poolnumber = $numbers[0] + 1;
 }

} else {

 # dann sollte diese Poolnummer nicht in der Liste sein
 $anzahl = grep /^$poolnumber$/, @numbers;
 if ( $anzahl > 0) {
   die "Abbruch: Poolnummer $poolnumber wird schon verwendet!\n"; 
 }

}


  1. ------------- Der Eintrag in den LDAP --------------------------------------
  1. wir zerlegen $range und holen die ersten beiden Oktetts vom Teilnetz

($min,$max) = split /:/, $range; ($tn) = $teilnetz =~ /^(\d{1,3}\.\d{1,3})\.\d{1,3}\.\d{1,3}$/;

  1. wir basten uns die beiden Werte fuer dhcpRange

$rangemin = join('.', $tn, $poolnumber, $min); $rangemax = join('.', $tn, $poolnumber, $max);

  1. jetzt tragen wir (endlich) den Pool ein

$mesg = $ldap->add(

         dn   => "cn=$poolname,cn=$teilnetz,cn=DHCP Config,$ldap_base",
         attr => [ objectClass => ['top', 'dhcpPool'],
                   cn          => $poolname,
                   dhcpRange   => "$rangemin $rangemax" ] ); 
  1. wenn Fehlercode, dann das Script mit Fehlermeldung sterben lassen

$mesg->code and die $mesg->error;

  1. wir trennen uns vom LDAP

$ldap->unbind;

  1. Ausgabe auf der Konsole (Rueckmeldung)

print "Die Rechnergruppe \"$poolname\" wurde in den LDAP eingetragen.\n";


                                      1. Programm-Ende #####################################
  1. Wenn Parameter -h uebergeben wurde, dann Hilfe ausgegeben und beenden

sub help {

  print "Hilfe muss noch erstellt werden.\n";
  exit (0);

}


__END__

</source>