Commit adfd86d7 authored by Maxime Besson's avatar Maxime Besson
Browse files

Add script to convert sessions between backends (#2014)

parent ad55b39f
......@@ -623,6 +623,7 @@ install_bin: install_conf_dir
${SRCPORTALDIR}/site/cron/purgeCentralCache \
${SRCPORTALDIR}/scripts/llngDeleteSession \
${SRCCOMMONDIR}/scripts/convertConfig \
${SRCCOMMONDIR}/scripts/convertSessions \
${SRCCOMMONDIR}/scripts/lmMigrateConfFiles2ini \
${SRCCOMMONDIR}/scripts/rotateOidcKeys \
${SRCMANAGERDIR}/scripts/lmConfigEditor \
......
/etc/lemonldap-ng/lemonldap-ng.ini
/etc/lemonldap-ng/for_etc_hosts
/usr/share/man/man1/convertConfig.1p
/usr/share/man/man1/convertSessions.1p
/usr/share/man/man1/lemonldap-ng-cli.1p
/usr/share/man/man3/Lemonldap::NG::Common*
/usr/share/perl5/auto/Lemonldap/NG/Common
/usr/share/perl5/Lemonldap/NG/Common*
/usr/share/lemonldap-ng/ressources
/usr/share/lemonldap-ng/bin/convertConfig
/usr/share/lemonldap-ng/bin/convertSessions
/usr/share/lemonldap-ng/bin/importMetadata
/usr/share/lemonldap-ng/bin/lmMigrateConfFiles2ini
/usr/share/lemonldap-ng/bin/rotateOidcKeys
......
......@@ -70,6 +70,7 @@ META.json
META.yml
README
scripts/convertConfig
scripts/convertSessions
scripts/importMetadata
scripts/lemonldap-ng-cli
scripts/lmMigrateConfFiles2ini
......
......@@ -90,6 +90,7 @@ WriteMakefile(
},
MAN1PODS => {
'scripts/convertConfig' => 'blib/man1/convertConfig.1p',
'scripts/convertSessions' => 'blib/man1/convertSessions.1p',
'scripts/lemonldap-ng-cli' => 'blib/man1/lemonldap-ng-cli.1p',
},
);
#!/usr/bin/perl
#=============================================================================
# LemonLDAP::NG session conversion tool
#
# This script lets an administrator migrate existing sessions from one backend
# to another. It is mostly useful when run on persistant sessions, but it can be
# useful in some other cases too, such as OIDC Offline sessions
#
# This is part of LemonLDAP::NG product, released under GPL
#=============================================================================
use Lemonldap::NG::Common::Apache::Session;
use Lemonldap::NG::Common::Session;
use Config::IniFiles;
use strict;
use Getopt::Std;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
our $VERSION = "2.0.6";
# Options
# -d: debug mode
# -c: configuration file
# -i: ignore errors
my $opts = {};
getopts( 'dic:', $opts );
my $debug = $opts->{d};
my $config_file = $opts->{c};
my $ignore_errors = $opts->{i};
my $nb_converted = 0;
my $nb_error = 0;
sub HELP_MESSAGE {
my $OUT = shift;
print $OUT <<END_MESSAGE;
$0 [-di] -c config_file.ini
-d Debug mode
-i Ignore errors
This script converts sessions in between the two backends specified in the configuration file
The configuration file must contain the following (adjust to your environment):
[sessions_from]
storageModule = Apache::Session::File
storageModuleOptions = { \\
'Directory' => '/var/lib/lemonldap-ng/sessions', \\
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock', \\
}
# Only convert some session types
# sessionKind = Persistent, SSO
[sessions_to]
storageModule = Apache::Session::Browseable::Postgres
storageModuleOptions = { \\
'DataSource' => 'DBI:Pg:database=lemonldapdb;host=pg.example.com', \\
'UserName' => 'lemonldaplogin', \\
'Password' => 'lemonldappw', \\
'Commit' => 1, \\
'Index' => 'ipAddr _whatToTrace user', \\
'TableName' => 'sessions', \\
}
END_MESSAGE
}
unless ($config_file) {
HELP_MESSAGE( \*STDERR );
die "You must provide the -c option";
}
my $inicfg =
Config::IniFiles->new( -file => $config_file, -allowcontinue => 1 );
my $cfg = {};
die "Could not read configuration file" unless $inicfg;
for my $section (qw/sessions_from sessions_to/) {
die "Could not find section $section in configuration file $config_file"
unless $inicfg->SectionExists($section);
# Load section parameters
my $r;
foreach ( $inicfg->Parameters($section) ) {
$r->{$_} = $inicfg->val( $section, $_ );
# Remove spaces before and after value (#1488)
$r->{$_} =~ s/^\s*(.+?)\s*/$1/;
if ( $r->{$_} =~ /^[{\[].*[}\]]$/ || $r->{$_} =~ /^sub\s*{.*}$/ ) {
eval "\$r->{$_} = $r->{$_}";
if ($@) {
print $@;
return $r;
}
}
}
$cfg->{$section} = $r;
}
my $backendFrom;
my $backendTo;
my @sessionKindOnly;
if ( $cfg->{sessions_from}->{sessionKind} ) {
@sessionKindOnly = split /\W+/, $cfg->{sessions_from}->{sessionKind};
}
if ( $cfg->{sessions_from}->{storageModule} ) {
$backendFrom = $cfg->{sessions_from}->{storageModuleOptions};
$backendFrom->{backend} = $cfg->{sessions_from}->{storageModule};
}
else {
die
"[sessions_from] configuration section does not declare a storageModule";
}
if ( $cfg->{sessions_to}->{storageModule} ) {
$backendTo = $cfg->{sessions_to}->{storageModuleOptions};
$backendTo->{backend} = $cfg->{sessions_to}->{storageModule};
}
else {
die "[sessions_to] configuration section does not declare a storageModule";
}
Lemonldap::NG::Common::Apache::Session->get_key_from_all_sessions(
$backendFrom,
sub {
my $entry = shift;
my $id = shift;
print "Processing session $id\n" if $debug;
my $s = Lemonldap::NG::Common::Session->new( {
storageModule => $backendTo->{backend},
storageModuleOptions => $backendTo,
id => $id,
info => $entry,
force => 1,
}
);
# If filtering sessionKind
if (@sessionKindOnly) {
unless ( grep { $_ eq $entry->{_session_kind} } @sessionKindOnly ) {
return undef;
}
}
if ( $s->error ) {
die "Error encountered on session $id" unless $ignore_errors;
$nb_error += 1;
print "Error converting session $id : " . $s->error . "\n";
}
else {
print "Session $id successfully converted\n" if $debug;
$nb_converted += 1;
}
}
);
print "$nb_converted sessions have been converted\n";
print "$nb_error errors encountered during conversion\n" if $nb_error;
my $exit = $nb_error ? 1 : 0;
exit $exit;
__END__
=head1 NAME
=encoding utf8
convertSessions - A tool to convert Lemonldap::NG sessions between storage backends.
=head1 SYNOPSIS
convertSession [-di] -c parameters.ini
=head1 DESCRIPTION
convertConfig is a command line tool to migrate all sessions stored
in a source backend (sessions_from), into a new backend (sessions_to).
It requires a special configuration file in which you must list the source
and destination backend modules and parameters.
Sessions will not be deleted from the source backend. Existing sessions in the
destination backend will be kept, unless they have the same session ID as a
session in the source backend. In that case, the source will overwrite the
destination.
=head1 CONFIGURATION FILE FORMAT
The configuration file needs two sections to describe the source and destination backends
Here is an example
[sessions_from]
storageModule = Apache::Session::File
storageModuleOptions = { \
'Directory' => '/var/lib/lemonldap-ng/sessions', \
'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock', \
}
# Only migrate some session types
# sessionKind = Persistent, SSO
[sessions_to]
storageModule = Apache::Session::Browseable::Postgres
storageModuleOptions = { \
'DataSource' => 'DBI:Pg:database=lemonldapdb;host=pg.example.com', \
'UserName' => 'lemonldaplogin', \
'Password' => 'lemonldappw', \
'Commit' => 1, \
'Index' => 'ipAddr _whatToTrace user', \
'TableName' => 'sessions', \
}
The C<sessionKind> parameter may be used to filter only some session types.
Thanks to this, you can use this script to migrate from one database holding
all your sessions to separate tables from each session type.
=head1 SEE ALSO
L<http://lemonldap-ng.org/>
=head1 AUTHORS
=over
=item Maxime Besson, E<lt>maxime.besson@worteks.comE<gt>
=back
=head1 BUG REPORT
Use OW2 system to report bug or ask for features:
L<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>
=head1 DOWNLOAD
Lemonldap::NG is available at
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
......@@ -561,10 +561,12 @@ fi
%config(noreplace) %{apache_confdir}/z-lemonldap-ng-manager.conf
%config(noreplace) %{apache_confdir}/z-lemonldap-ng-portal.conf
%{_mandir}/man1/convertConfig*
%{_mandir}/man1/convertSessions*
%dir %{_libexecdir}/%{name}
%dir %{lm_sbindir}
%dir %{lm_bindir}
%{lm_bindir}/convertConfig
%{lm_bindir}/convertSessions
%{lm_bindir}/importMetadata
%{lm_bindir}/lmMigrateConfFiles2ini
%{lm_bindir}/rotateOidcKeys
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment