ispman/scripts ldifupdate,1.1,1.2

[email protected]
Newsgroups gmane.comp.isp.ispman.cvs
Message-ID <[email protected]>
Update of /cvsroot/ispman/ispman/scripts
In directory sc8-pr-cvs1:/tmp/cvs-serv11293/scripts

Modified Files:
	ldifupdate 
Log Message:
some major recoding of update script
(some more logic, much cleaner code)

this script should become the generic update tool for the ispman ldap data

if it doesn't update your ldap correctly, file a bug!


Index: ldifupdate
===================================================================
RCS file: /cvsroot/ispman/ispman/scripts/ldifupdate,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ldifupdate	28 Aug 2003 09:43:14 -0000	1.1
+++ ldifupdate	18 Jan 2004 20:03:19 -0000	1.2
@@ -1,167 +1,220 @@
-#!/usr/bin/perl
+#!/usr/bin/perl -w
 
 # Script to update LDIF data
-# Reads from one ldif file and writes to out.ldif
+# Reads from one ldif file and writes to another ldif
 # Messages are dumped on STDERR
 
-# Logic
-# If there is only one objectclass and it is top, replace with ispmanBranch
-# if a dn starts with ou= replace objectclass with ispmanBranch
-# If Entry  is ispmanDomain, set appropriate objectclasses
-# If Entry is  ispmanVhost set appropriate objectclasses
-# If Entry is ispmanVhost set uid to vhostname.domain.name
-# If Entry is ispmanVhost and uidNumber is missing set it to 9999
-# If Entry is ispmanVhost and gidNumber is missing set it to 9999
-# If Entry is ispmanVhost and homeDirectory is missing set it to /ispman/domain/$domain/vhosts/$vhostname
-# If Entry is ispmanVhost and userPassword  is missing set it to 12345
-
-# For all entries make sure that the first attr=value pair is defined as attribute in the entry
+# please adjust defines below to suit your environment
 
+# All entries are parsed (unless filtered with option "-b") and changed
+# according to current schema
+# For details see comments below
 
 
-package ISPMan;
-BEGIN{
-   use FindBin; unshift @INC, ($FindBin::Bin , "$FindBin::Bin/../lib", "$FindBin::Bin/../conf");
-   use Getopt::Std;
-   getopt('f',  \%opts);
-   unless ($opts{'f'}){
-      print "$FindBin::Script. A utility to update data from ldif according to new ISPMan schema\n";
-      print "This script has been tested from a LDAP dump from openldap 2.0.x running with ISPMan 0.9.6\n";
-      print "The data was updated and loaded to openldap 2.1.12 running with ISPMan 1.0\n";
-      print "Please provide your ldif file with -f switch\n";
-      print "\n\n";
-      exit;
-   }
+sub usage {
+    print "ISPMan ldifupdate\n";
+    print "A utility to update your ispman LDAP data according to current ISPMan schema.\n";
+    print "It will convert the given input LDIF and output it to an output LDIF\n";
+    print "either in add or modify format.\n\n";
+    print "Syntax: ldifupdate <options>\n";
+    print "Options:\n";
+    print "  -i        input LDIF filename\n"; 
+    print "  -o        output LDIF filename\n"; 
+    print "  -b        base DN (optional), which limits changes to this subtree\n"; 
 }
 
+use strict;
+use Getopt::Std;
 use Net::LDAP::LDIF;
 use Net::LDAP::Entry;
-  
-use vars qw($ldif $entry);
 
-$ldif = Net::LDAP::LDIF->new( $opts{'f'});
-$out = Net::LDAP::LDIF->new("out.ldif", "w");
+# defines
+my @oc_normalDomain = qw(ispmanDomain PureFTPdUser posixAccount);
+my @oc_replicaDomain = qw(ispmanDomain ispmanBranch top);
+my @oc_virtualHost = qw(ispmanVirtualHost posixAccount PureFTPdUser);
+my $default_domainHomedir = "/ispman/domains";
+my @default_fileserver = qw( );
+my @default_webhost = qw( );
+my $dummyUid = "999999";
+my $dummyGid = "999999";
+my $dummyPassword = "123456";
 
+# local variables
+my ($ldif, $ldif2, $entry, $basedn);
+my (%opts, $dn, $msg);
 
+# get parameters
+getopt('iob',  \%opts);
+unless ($opts{'i'} or $opts{'o'}){
+    usage();
+    exit 1;
+}
 
+$ldif = Net::LDAP::LDIF->new( $opts{'i'});
+$ldif2 = Net::LDAP::LDIF->new( $opts{'o'}, "w");
 
[email protected]=();
+$basedn = $opts{'b'};
 
+# read and parse ldap data
+while( not $ldif->eof() ) {
+    undef ($entry);
+    $entry = $ldif->read_entry();
+    
+    # skip entry if we find an error
+    if ( $ldif->error() ) {
+        print STDERR "Error msg: ",$ldif->error(),"\n";
+        print STDERR "Error lines:\n",$ldif->error_lines(),"\n";
+    }
 
+    $entry->changetype("add");
+    $dn=$entry->dn();
 
+    next unless ! defined($basedn) or $dn =~ m/$basedn$/;
 
-while( not $ldif->eof() ) {
-     $entry = $ldif->read_entry();
-     if ( $ldif->error() ) {
-        print "Error msg: ",$ldif->error(),"\n";
-        print "Error lines:\n",$ldif->error_lines(),"\n";
-     }
-     else {
-        $entry->changetype("add");
-        $dn=$entry->dn();
-	my @oc=$entry->get_value("objectclass");
-        print STDERR "\n\n";
-	print STDERR "DN: $dn\n";
+    $msg="";
 
-	if ($#oc==0 && $oc[0] eq "top"){
-		#if there is only one objectclass: top
-               #replace with ispmanBranch
-            print STDERR "Replacing top with ispmanBranch\n";
+    ## update entry
+    my @oc=$entry->get_value("objectclass");
+    if ($#oc==0 && $oc[0] eq "top"){
+	
+	# if there is only one objectclass: top
+	# replace with ispmanBranch
+	$msg.="replacing objectclass \"top\" with \"ispmanBranch\"\n";
+	$entry->replace("objectclass", "ispmanBranch");
 
-                $entry->replace("objectclass", "ispmanBranch");
-	}  elsif ($dn=~m/^ou=/){
-               #if entry starts with ou=
-              # replace objectclasses top, organiationalunit with
-              # ispmanBranch
-           print STDERR "Replacing oc  with ispmanBranch ou=\n";
-           $entry->replace("objectclass", "ispmanBranch");
-	}  elsif ($dn=~m/^ispmanDomain=/){
-           if ($entry->get_value("ispmanDomainType") eq "replica") {
-              print STDERR "Found Replica domain: Replacing OC with [ispmanDomain, ispmanBranch, top ]\n";
-              $entry->replace("objectclass", ["ispmanDomain", "ispmanBranch", "top" ]);
-           } else {
-              print STDERR "Found NonReplica domain: Replacing OC with [ispmanDomain, PureFTPdUser,  posixAccount]\n";
-              $entry->replace("objectclass", ["ispmanDomain", "PureFTPdUser",  "posixAccount"]);
-           }
-	}  elsif ($dn=~m/^ispmanVhostName/){
-            print STDERR "Found Vhost: Replacing OC with [ispmanVirtualHost, posixAccount, PureFTPdUser]\n";
-              $entry->replace("objectclass", ["ispmanVirtualHost", "posixAccount", "PureFTPdUser"]);
-              unless ($entry->get_value("cn")){
-                 print STDERR "No cn entry found. adding cn", $entry->get_value("ispmanVhostName"), "\n";
-                 $entry->add("cn", $entry->get_value("ispmanVhostName"));
-              }
-              
-              print STDERR "Replacing uid with ", join ".", ($entry->get_value("ispmanVhostName"), $entry->get_value("ispmanDomain")), "\n";
-              $entry->replace("uid", join ".", ($entry->get_value("ispmanVhostName"), $entry->get_value("ispmanDomain")));
-              
-              
-              
-              unless ($entry->get_value("uidNumber")){
-                 print STDERR "No uidNumber. adding uidNumber: 9999. This should be replaced later\n";
-                 $entry->add("uidNumber", 9999);
-              }
-              unless ($entry->get_value("gidNumber")){
-                 print STDERR "No gidNumber. adding gidNumber: 9999. This should be replaced later\n";
-                 $entry->add("gidNumber", 9999);
-              }
-              unless ($entry->get_value("homeDirectory")){
-                 print STDERR "No homeDirectory. adding homeDirectory: ",  join '/', ('/ispman/domains', $entry->get_value("ispmanDomain"), 'vhosts', $entry->get_value("ispmanVhostName")), "\n";
-                 $entry->add("homeDirectory", join '/', ('/ispman/domains', $entry->get_value("ispmanDomain"), 'vhosts', $entry->get_value("ispmanVhostName")));
-              }
-              unless ($entry->get_value("userPassword")){
-                 print STDERR "No userPassword: adding userPassword: 123456. This should be replaced later\n";
-                 $entry->add("userPassword", '123456');
-              }
+    } elsif ($dn=~m/^ou=/){
 
+	# if entry starts with "ou=" replace 
+	# objectclasses top, organizationalunit with ispmanBranch
+	$msg.="replacing objectclass with \"ispmanBranch\"\n";
+	$entry->replace("objectclass", "ispmanBranch");
 
-           } else {
+    } elsif ($dn=~m/^ispmanDomain=/){
+	
+	# update ispmanDomain objectclasses
+	if ($entry->get_value("ispmanDomainType") eq "replica") {
+	    $msg.="Found ispmanReplicaDomain:\n";
+	    $msg.="replacing objectclass with [@oc_replicaDomain]\n";
+	    $entry->replace("objectclass", @oc_replicaDomain );
+	} else {
+	    $msg.="Found ispmanDomain:\n";
+	    $msg.="replacing objectclass with [@oc_normalDomain]\n";
+	    $entry->replace("objectclass", @oc_normalDomain);
+	}
 
+	# check ispmanDomainDefaultFileServer attribute
+	if (! defined $entry->get_value("ispmanDomainDefaultFileServer")){
+	    $msg.="WARNING! no \"Default Fileserver\" defined!\n";
+	    foreach (@default_fileserver){
+		$msg.="adding ispmanDomainDefaultFileServer with \"$_\"\n";
+		$entry->add("ispmanDomainDefaultFileServer",$_);
+	    }
+	}
 
-       }
-        # get the first attrib name and val and 
-        # add them in the entry if the dont exists.
-        my ($attrib, $attribval)=$dn=~m/^(\w+)?\=([^,]*)/;
-        #print "Attrib: $attrib\n";
-        #print "Attribval: $attribval\n";
+	# check ispmanDomainDefaultWebServer attribute
+	if (! defined $entry->get_value("ispmanDomainDefaultWebHost")){
+	    $msg.="WARNING! no \"Default Webhost\" defined!\n";
+	    foreach (@default_webhost){
+		$msg.="adding ispmanDomainWebHost with \"$_\"\n";
+		$entry->add("ispmanDomainDefaultWebHost",$_);
+	    }
+	}
 
-        $entry->replace($attrib, as_arrayref(unique(as_array($entry->get_value($attrib) , $attribval))));       
-        push @entries, $entry;
+    } elsif ($dn=~m/^ispmanVhostName/){
 
-	 
-        #print $entry->dn(), "\n";
-        #print $entry->dump(), "\n";
-        #$entry->dump();
-        # do stuff
-     }
-  }
-  $ldif->done();
+	# update ispmanVhost
+	$msg.="Found ispmanVhost:\n";
+	my $ispmanDomain=$entry->get_value("ispmanDomain") || die("ispmanDomain undefined!");
+    	my $ispmanVhostName=$entry->get_value("ispmanVhostName") || die("ispmanVhostName undefined!");
 
-$out->write_entry(@entries);
+	# replacing vhost objectclasses
+	$msg.="replacing objectclass with [@oc_virtualHost]\n";
+	$entry->replace("objectclass", @oc_virtualHost);
+	
+	# checking vhost cn attribute
+	my $cn=join ".", ($ispmanVhostName, $ispmanDomain);
+	if (! defined ($entry->get_value("cn"))){
+	    $msg.="adding cn with \"$cn\"\n";
+	    $entry->add("cn", $cn);
+	} elsif ($entry->get_value("cn") ne $ispmanVhostName) {
+	    $msg.="changing cn to \"$cn\"\n";
+	    $entry->replace("cn", $cn);
+	}
+	
+	# checking vhost uid attribute
+	my $uid=join ".", ($ispmanVhostName, $ispmanDomain);
+	if (! defined ($entry->get_value("uid"))){
+	    $msg.="adding uid with \"$uid\"\n";
+	    $entry->add("uid", $uid);
+	} elsif ($entry->get_value("uid") ne $uid){
+	    $msg.="changing uid to \"$uid\"\n";
+	    $entry->replace("uid", $uid);
+	}
+	
+	# checking vhost uidNumber attribute
+	unless ($entry->get_value("uidNumber")){
+	    $msg.="adding dummy uidNumber: $dummyUid. This should be replaced later!\n";
+	    $entry->add("uidNumber", $dummyUid);
+	}
 
-sub as_array {
-   #take a list of arrays, strings, arrayrefs etc and return as an array
-   return undef unless @_;
-   my @l=();
-   for (@_){
-          if (ref $_ eq "ARRAY"){
-                  push @l, @$_;
-          } else {
-                  push @l, $_;
-          }
-   }
-   return @l;
-}
+	# checking vhost gidNumber attribute
+	unless ($entry->get_value("gidNumber")){
+	    $msg.="adding dummy gidNumber: $dummyGid. This should be replaced later!\n";
+	    $entry->add("gidNumber", $dummyGid);
+	}
 
-sub as_arrayref {
-   my @l=as_array(@_);
-   return \@l;
+	# checking vhost homeDirectory attribute
+	my $homedir=join '/', ($default_domainHomedir, $ispmanDomain, 'vhosts',
+			       $ispmanVhostName);
+	unless ($entry->get_value("homeDirectory")){
+	    $msg.="adding homeDirectory with \"$homedir\"\n";
+	    $entry->add("homeDirectory", $homedir);
+	}
+        
+	# checking vhost userPassword attribute
+	unless ($entry->get_value("userPassword")){
+	    $msg.="adding userPassword with \"$dummyPassword\". This should be replaced later!\n";
+	    $entry->add("userPassword", $dummyPassword);
+	}
+	
+    } else {
+	# check other entries here	
+	
+    }
+    
+    ## check that RDN is also attribute/value pair
 
+    # get the RDN as attr/value
+    my ($attrib, $attribval)=$dn=~m/^(\w+)?\=([^,]*)/;
+    my @values=$entry->get_value($attrib);
+    my $found=0;
+    for (@values) {
+	if ($_ eq $attribval) { $found=1 }
+    }
+    if (! $found) {
+	$msg.="adding RDN to attributes ($attrib: $attribval)\n";
+	$entry->add($attrib,$attribval);
+    }
+
+    # output msg
+    if ($msg){
+	print STDERR "DN: $dn\n";
+	print STDERR $msg,"\n";
+    }
+    
+    #print $entry->dn(), "\n";
+    #print $entry->dump(), "\n";
+    #$entry->dump();
+
+    # write changed ldif
+    $ldif2->write_entry($entry);
 }
-sub unique {
-        my %hr;
-        map {$hr{$_}++}@_;
-        return keys %hr;
-}
+
+$ldif->done();
+$ldif2->done();
+
+
+
 
 __END__
 




-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.