New feature : convertConfig

This commit is contained in:
Xavier Guimard 2009-12-15 16:31:13 +00:00
parent b289a53608
commit 703b3d64b0
12 changed files with 232 additions and 245 deletions

View File

@ -202,8 +202,7 @@ install_bin: install_libs install_conf_dir
@cp --preserve=mode --remove-destination \
${SRCPORTALDIR}/example/scripts/purgeCentralCache \
${SRCPORTALDIR}/example/scripts/buildPortalWSDL \
${SRCCOMMONDIR}/scripts/lmConfig_File2MySQL \
${SRCCOMMONDIR}/scripts/lmConfig_File2LDIF \
${SRCCOMMONDIR}/scripts/convertConfig \
${SRCMANAGERDIR}/example/scripts/lmConfigEditor \
$(RBINDIR)
chmod +x $(RBINDIR)/*

View File

@ -54,13 +54,5 @@ Modify /etc/lemonldap-ng/storage.conf to change configuration storage.
1.1 - Migrating from 'File' to 'DBI'
To use DBI mechanism to store configuration, you have to create database. An
example is given for MySQL in the file
/usr/share/doc/liblemonldap-ng-conf-perl/examples/lmConfig.mysql.
If you have a running configuration, use this to populate SQL database :
perl /usr/share/lemonldap-ng/bin/lmConfig_File2MySQL -c \
/var/lib/lemonldap-ng/conf/lmConf-<last-number>
"-c" options adds "create table" instruction.
Use the script /usr/share/lemonldap-ng/bin/convertConfig

View File

@ -3,5 +3,5 @@ debian/tmp/etc/lemonldap-ng/for_etc_hosts
debian/tmp/usr/share/perl5/Lemonldap/NG/Common*
debian/tmp/usr/share/man/man3/Lemonldap::NG::Common*
debian/tmp/usr/share/lemonldap-ng/ressources
debian/tmp/usr/share/lemonldap-ng/bin/lmConfig_File2MySQL
debian/tmp/usr/share/lemonldap-ng/bin/convertConfig
debian/tmp/var/lib/lemonldap-ng/conf/

View File

@ -12,6 +12,7 @@ lib/Lemonldap/NG/Common/Conf/CDBI.pm
lib/Lemonldap/NG/Common/Conf/DBI.pm
lib/Lemonldap/NG/Common/Conf/File.pm
lib/Lemonldap/NG/Common/Conf/LDAP.pm
lib/Lemonldap/NG/Common/Conf/RDBI.pm
lib/Lemonldap/NG/Common/Conf/SOAP.pm
lib/Lemonldap/NG/Common/Conf/Serializer.pm
lib/Lemonldap/NG/Common/Crypto.pm
@ -20,8 +21,7 @@ Makefile.PL
MANIFEST
META.yml Module meta-data (added by MakeMaker)
README
scripts/lmConfig_File2LDIF
scripts/lmConfig_File2MySQL
scripts/convertConfig
lemonldap-ng.ini
t/01-Common-Conf.t
t/02-Common-Conf-File.t

View File

@ -34,7 +34,7 @@ WriteMakefile(
'HTTP::Headers' => 0,
'Config::IniFiles' => 0,
}, # e.g., Module::Name => 1.1
#EXE_FILES => [ 'scripts/lmConfig_File2MySQL', ],
#EXE_FILES => [ 'scripts/convertConfig', ],
(
$] >= 5.005
? ## Add these new keywords supported since 5.005

View File

@ -10,7 +10,8 @@ package Lemonldap::NG::Common::Conf;
use strict;
no strict 'refs';
use Lemonldap::NG::Common::Conf::Constants; #inherits
use Lemonldap::NG::Common::Crypto; #link protected cipher Object "cypher" in configuration hash
use Lemonldap::NG::Common::Crypto
; #link protected cipher Object "cypher" in configuration hash
use Regexp::Assemble;
use Config::IniFiles;
@ -100,9 +101,10 @@ sub saveConf {
# If configuration was modified, return an error
return CONFIG_WAS_CHANGED
if ( $conf->{cfgNum} != $self->lastCfg or $self->isLocked );
if ( not( $self->{force} )
and ( $conf->{cfgNum} != $self->lastCfg or $self->isLocked ) );
$self->lock or return DATABASE_LOCKED;
$conf->{cfgNum}++;
$conf->{cfgNum}++ unless ( $self->{cfgNumFixed} );
$msg = "Configuration $conf->{cfgNum} stored";
return $self->store($conf);
}
@ -190,9 +192,7 @@ sub getLocalConf {
}
# Parse ini file
my $cfg = Config::IniFiles->new(
-file => $file,
);
my $cfg = Config::IniFiles->new( -file => $file, );
unless ( defined $cfg ) {
$msg = "Local config error: " . @Config::IniFiles::errors;
@ -351,6 +351,10 @@ sub delete {
return &{ $self->{type} . '::delete' }( $self, $a[ $#a + $c ] );
}
sub logError {
return &{ $_[0]->{type} . '::logError' }(@_);
}
1;
__END__

View File

@ -91,11 +91,10 @@ sub store {
$self->logError;
return UNKNOWN_ERROR;
}
eval { $self->dbh->do("COMMIT"); };
unless ( $self->unlock ) {
$self->logError;
return UNKNOWN_ERROR;
}
eval { $self->dbh->do("COMMIT"); };
return $fields->{cfgNum};
}

View File

@ -0,0 +1,144 @@
package Lemonldap::NG::Common::Conf::RDBI;
use strict;
use DBI;
use Lemonldap::NG::Common::Conf::Constants; #inherits
use Lemonldap::NG::Common::Conf::Serializer;
our $VERSION = 0.17;
BEGIN {
*Lemonldap::NG::Common::Conf::dbh = \&dbh;
}
sub prereq {
my $self = shift;
unless ( $self->{dbiChain} ) {
$Lemonldap::NG::Common::Conf::msg =
'"dbiChain" is required in RDBI configuration type';
return 0;
}
print STDERR __PACKAGE__ . 'Warning: "dbiUser" parameter is not set'
unless ( $self->{dbiUser} );
$self->{dbiTable} ||= "lmConfig";
1;
}
sub available {
my $self = shift;
my $sth =
$self->dbh->prepare( "SELECT DISTINCT cfgNum from "
. $self->{dbiTable}
. " order by cfgNum" );
$sth->execute();
my @conf;
while ( my @row = $sth->fetchrow_array ) {
push @conf, $row[0];
}
return @conf;
}
sub lastCfg {
my $self = shift;
my @row = $self->dbh->selectrow_array(
"SELECT max(cfgNum) from " . $self->{dbiTable} );
return $row[0];
}
sub dbh {
my $self = shift;
$self->{dbiTable} ||= "lmConfig";
return $self->{dbh} if ( $self->{dbh} and $self->{dbh}->ping );
return DBI->connect_cached(
$self->{dbiChain}, $self->{dbiUser},
$self->{dbiPassword}, { RaiseError => 1 }
);
}
sub lock {
my $self = shift;
my $sth = $self->dbh->prepare_cached( q{SELECT GET_LOCK(?, 5)}, {}, 1 );
$sth->execute('lmconfrdbi');
my @row = $sth->fetchrow_array;
return $row[0] || 0;
}
sub isLocked {
my $self = shift;
my $sth = $self->dbh->prepare_cached( q{SELECT IS_FREE_LOCK(?)}, {}, 1 );
$sth->execute('lmconfrdbi');
my @row = $sth->fetchrow_array;
return $row[0] ? 0 : 1;
}
sub unlock {
my $self = shift;
my $sth = $self->dbh->prepare_cached( q{SELECT RELEASE_LOCK(?)}, {}, 1 );
$sth->execute('lmconfrdbi');
my @row = $sth->fetchrow_array;
return $row[0] || 0;
}
sub store {
my ( $self, $fields ) = @_;
$self->{noQuotes} = 1;
$fields = $self->serialize($fields);
my $errors = 0;
eval { $self->dbh->do('BEGIN'); };
while ( my ( $k, $v ) = each %$fields ) {
unless (
$self->dbh->do(
"insert into "
. $self->{dbiTable}
. " (cfgNum,field,value) values ("
. join( ',', $fields->{cfgNum}, "'$k'", "'$v'" ) . ')'
)
)
{
$self->logError;
$errors++;
last;
}
}
eval { $errors ? $self->dbh->do("ROLLBACK") : $self->dbh->do("COMMIT"); };
unless ( $self->unlock ) {
$self->logError;
}
return $errors ? UNKNOWN_ERROR : $fields->{cfgNum};
}
sub load {
my ( $self, $cfgNum, $fields ) = @_;
$fields = $fields ? join( ",", @$fields ) : '*';
my $sth =
$self->dbh->prepare( "SELECT cfgNum,field,value from "
. $self->{dbiTable}
. " WHERE cfgNum=$cfgNum" );
$sth->execute();
my ( $res, @row );
while ( @row = $sth->fetchrow_array ) {
$res->{ $row[1] } = $row[2];
}
unless($res) {
$Lemonldap::NG::Common::Conf::msg .= "No configuration $cfgNum found";
return 0;
}
$res->{cfgNum} = $cfgNum;
return $self->unserialize($res);
}
sub delete {
my ( $self, $cfgNum ) = @_;
$self->dbh->do(
"DELETE from " . $self->{dbiTable} . " WHERE cfgNum=$cfgNum" );
}
sub logError {
my $self = shift;
$Lemonldap::NG::Common::Conf::msg .=
"Database error: " . $self->dbh->errstr . "\n";
}
1;
__END__

View File

@ -17,7 +17,7 @@ sub serialize {
if ( ref($v) ) {
$fields->{$k} = Dumper($v);
$fields->{$k} =~ s/'/&#39;/g;
$fields->{$k} = "'$fields->{$k}'";
$fields->{$k} = "'$fields->{$k}'" unless ( $self->{noQuotes} );
}
elsif ( $v =~ /^\d+$/ ) {
$fields->{$k} = "$v";
@ -29,7 +29,9 @@ sub serialize {
# trim
$v =~ s/^\s*(.*?)\s*$/$1/;
$fields->{$k} = "'$v'";
$v =~ s/'/&#39;/g;
$v = "'$v'" unless ( $self->{noQuotes} );
$fields->{$k} = $v;
}
}
return $fields;
@ -68,6 +70,7 @@ sub unserialize {
}
}
else {
$v =~ s/&#?39;/'/g;
$conf->{$k} = $v;
}
}

View File

@ -0,0 +1,66 @@
#!/usr/bin/perl
use strict;
use Getopt::Long;
use Lemonldap::NG::Common::Conf;
my %opts;
my $result = GetOptions ( \%opts, 'help|h', 'current|c=s', 'new|n=s', 'latest|l' );
if( $opts{help} or not ( $opts{current} and $opts{new} ) ) {
print STDERR "Usage: $0 --current=/current/lemonldap-ng.ini --new=/new/lemonldap-ng.ini\n";
print STDERR "# other parameters:
--latest -l
convert only last configuration
";
exit 1;
}
foreach( $opts{current}, $opts{new} ) {
unless( -e $_ ) {
print STDERR "$_ does not exist\n";
exit 2;
}
unless( -r $_ ) {
print STDERR "$_ is not readable\n";
exit 3;
}
}
my $old = Lemonldap::NG::Common::Conf->new({
confFile => $opts{current},
noCache=>1,
});
unless($old) {
print STDERR "Failed to get current conf : $Lemonldap::NG::Common::Conf::msg\n";
exit 4;
}
my $new = Lemonldap::NG::Common::Conf->new({
confFile => $opts{new},
force=>1,
noCache=>1,
cfgNumFixed=>1,
});
unless($new) {
print STDERR "Failed to create new conf object : $Lemonldap::NG::Common::Conf::msg\n";
exit 5;
}
my @available;
if($opts{lastest}){
@available = $old->lastCfg();
}else{
@available = $old->available();
}
foreach(@available) {
my $conf = $old->getConf({cfgNum=>$_});
eval { delete $conf->{reVHosts};
delete $conf->{cipher};
};
unless($conf){
print STDERR "\nFailed to get conf $_ : $Lemonldap::NG::Common::Conf::msg\n";
exit 6;
}
print "Conf $conf->{cfgNum}:";
my $r = $new->saveConf($conf);
print ($r ? "stored" : "failed: $Lemonldap::NG::Common::Conf::msg");
print "\n";
}

View File

@ -1,109 +0,0 @@
#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if 0; # not running under some shell
use Getopt::Std;
use Lemonldap::NG::Common::Conf;
use File::Basename;
use strict;
# Get ARGS
my %opts;
getopts( 'b:c', \%opts );
&usage("configuration file required")
unless ( $ARGV[0] );
&usage(qq#$ARGV[0] is not readable#)
unless ( -r $ARGV[0] );
&usage("configuration branch required")
unless ( $opts{b} );
# Internal varibales
my $branch = $opts{b};
my ( $branchname ) = ( $branch =~ /^ou=(.+?),/ );
my ($filename, $directories, $suffix) = fileparse ( $ARGV[0] );
# LDIF header
print "# LemonLDAP::NG configuration (converted from files)\n";
# Create configuration branch
if($opts{c}) {
print "dn: $branch
objectClass: top
objectClass: organizationalUnit
ou: $branchname\n\n";
}
# Create configuration entry
open FILE, $ARGV[0];
$/ = "";
print "dn: cn=$filename,$branch
objectClass: top
objectClass: applicationProcess
cn: $filename\n";
while (<FILE>) {
my ( $k, $v ) = split /\n\s+/;
chomp $k;
next unless($k);
$v =~ s/\n*$//;
print "description: {$k}$v\n";
}
print "\n";
sub usage {
print STDERR shift;
print STDERR "\nusage: $0 <options> file
Options:
-b branch : name of the configuration branch
-c : add 'create table' instruction\n\n";
exit 1;
}
1;
__END__
=head1 NAME
lmConfig_File2LDIF - Perl utility to convert Lemonldap::NG configuration file
into LDIF file.
=head1 SYNOPSIS
lmConf_File2LDIF <options> /path/to/lmConf-1
=head1 DESCRIPTION
Use this software to convert Lemonldap::NG configuration file into LDIF.
=head2 Options
=over
=item * -b : name of the configuration branch
=item * -c : create the configuration branch (organizationalUnit)
=back
=head1 SEE ALSO
Lemonldap::NG::Manager
=head1 AUTHOR
Clement Oudot, E<lt>clement@oodo.netE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2007 by Xavier Guimard
Copyright (C) 2009 by Clement Oudot
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -1,111 +0,0 @@
#!/usr/bin/perl
use Getopt::Std;
use Lemonldap::NG::Common::Conf;
use strict;
# Get ARGS
my %opts;
getopts( 'ct:', \%opts );
usage("configuration file required")
unless ( $ARGV[0] );
usage(qq#$ARGV[0] is not readable#)
unless ( -r $ARGV[0] );
my $table = $opts{t} || 'lmConfig';
if($opts{c}) {
print "CREATE TABLE $table (
cfgNum int not null primary key,
locationRules text,
exportedHeaders text,
globalStorage text,
globalStorageOptions text,
macros text,
groups text,
portal text,
domain text,
ldapServer text,
ldapPort int,
ldapBase text,
securedCookie int,
cookieName text,
authentication text,
exportedVars text,
managerDn text,
managerPassword text,
timeout int,
whatToTrace text\n);\n";
}
my $fields;
open FILE, $ARGV[0];
$/ = "";
while (<FILE>) {
my ( $k, $v ) = split /\n\s+/;
chomp $k;
next unless($k);
$v =~ s/\n*$//;
$fields->{$k} = $v;
}
print "INSERT INTO "
. $table . " (\n\t"
. join( ",\n\t", keys(%$fields) )
. ")\n VALUES (\n\t"
. join( ",\n\t", values(%$fields) )
. "\n );\n";
close FILE;
sub usage {
print STDERR shift;
print STDERR "\nusage: $0 <options> file
Options:
-t table : name of the table (default: lmConfig)
-c : add 'create table' instruction\n";
exit 1;
}
1;
__END__
=head1 NAME
lmConfig_File2MySQL - Perl utility to convert Lemonldap::NG configuration file
into MySQL SQL file.
=head1 SYNOPSIS
lmConf_File2MySQL <options> /path/to/lmConf-1
=head1 DESCRIPTION
Use this software to convert Lemonldap::NG configuration file into SQL
instructions.
=head2 Options
=over
=item * -c : add "create table" instruction
=item * -t : name of the table (lmConfig by default)
=back
=head1 SEE ALSO
Lemonldap::NG::Manager
=head1 AUTHOR
Xavier Guimard, E<lt>x.guimard@free.frE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2007 by Xavier Guimard
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
=cut