Merge branch 'variables-placeholder-2491' into 'v2.0'

Variables placeholder in configuration

See merge request lemonldap-ng/lemonldap-ng!273
This commit is contained in:
Yadd 2022-07-01 14:12:22 +00:00
commit 0fffe97e99
4 changed files with 137 additions and 1 deletions

View File

@ -128,6 +128,21 @@ configuration.
instanceName = LLNG_Demo
.. tip::
It is possible to use environment variable placeholders anywhere in
configuration. Those placeholders will be replaced by each LLNG component
using environment variables set locally.
The format is: ``%SERVERENV:VariableName%``.
To enable this feature, you must edit ``lemonldap-ng.ini`` to set
``useServerEnv`` value in [configuration] section:
.. code:: ini
[configuration]
useServerEnv = 1
Manager API
-----------

View File

@ -84,6 +84,7 @@ scripts/lmMigrateConfFiles2ini
scripts/rotateOidcKeys
t/01-Common-Conf.t
t/02-Common-Conf-File.t
t/02-Common-Conf-ServerEnv.t
t/03-Common-Conf-CDBI.t
t/03-Common-Conf-RDBI.t
t/05-Common-Conf-LDAP.t

View File

@ -31,6 +31,8 @@ our $VERSION = '2.0.14';
our $msg = '';
our $iniObj;
our $PlaceHolderRe = '%SERVERENV:(.*?)%';
BEGIN {
eval {
require threads::shared;
@ -228,9 +230,10 @@ sub getConf {
$res = $r;
}
# Create cipher object
# Create cipher object and replace variable placeholder
unless ( $args->{raw} ) {
$self->replacePlaceholders($res) if $self->{useServerEnv};
eval {
$res->{cipher} = Lemonldap::NG::Common::Crypto->new( $res->{key} );
};
@ -504,6 +507,46 @@ sub logError {
return shift->_launch( 'logError', @_ );
}
sub _substPlaceHolders {
return $_[0] unless $_[0];
$_[0] =~ s/$PlaceHolderRe/$ENV{$1}/geo;
return $_[0];
}
## @method void replacePlaceholders(res: LLNG_Conf)
#
# Recursively replace %SERVERENV:VariableName% by $ENV{VariableName} value
sub replacePlaceholders {
my ( $self, $conf ) = @_;
if ( ref $conf eq 'HASH' ) {
foreach my $key ( keys %$conf ) {
if ( $key =~ /$PlaceHolderRe/o ) {
my $val = $conf->{$key};
delete $conf->{$key};
my $nk = _substPlaceHolders($key);
$conf->{$nk} = $val;
}
next unless ( $conf->{$key} );
if ( ref $conf->{$key} ) {
$self->replacePlaceholders( $conf->{$key} );
}
elsif ( $conf->{$key} =~ /$PlaceHolderRe/o ) {
$conf->{$key} = _substPlaceHolders( $conf->{$key} );
}
}
}
elsif ( ref $conf eq 'ARRAY' ) {
for ( my $i = 0 ; $i < @$conf ; $i++ ) {
if ( ref $conf->[$i] ) {
$self->replacePlaceholders( $conf->[$i] );
}
elsif ( $conf->[$i] =~ /$PlaceHolderRe/o ) {
$conf->[$i] = _substPlaceHolders( $conf->[$i] );
}
}
}
}
1;
__END__

View File

@ -0,0 +1,77 @@
use strict;
use Test::More tests => 14;
use Data::Dumper;
BEGIN { use_ok('Lemonldap::NG::Common::Conf') }
my $h;
ok(
$h = new Lemonldap::NG::Common::Conf( {
type => 'File',
dirName => "t/",
}
),
'type => file',
);
my $conf = {
cfgNum => 1,
test => '%SERVERENV:A%',
test2 => '%SERVERENV:B% %SERVERENV:C%',
'%SERVERENV:MYKEY%' => {
test => 'Test: %SERVERENV:A%',
array => [ 'a', '%SERVERENV:B% %SERVERENV:C%', ],
},
};
$ENV{A} = 'Aa';
$ENV{B} = 'Bb';
$ENV{C} = 'Cc';
$ENV{MYKEY} = 'MyKey';
ok( $h->store($conf) == 1, "Conf is stored" )
or print STDERR "$Lemonldap::NG::Common::Conf::msg $!";
my $cfg;
ok( $cfg = $h->getConf( { cfgNum => 1 } ), "Conf can be read" )
or print STDERR $Lemonldap::NG::Common::Conf::msg;
ok( $cfg->{test} eq '%SERVERENV:A%',
'%SERVERENV:A% is not substitued into Aa without useServerEnv' )
or print STDERR "Expect $cfg->{test} eq %SERVERENV:A%\n";
unlink 't/lmConf-1.json';
ok(
$h = new Lemonldap::NG::Common::Conf( {
type => 'File',
dirName => "t/",
useServerEnv => 1,
}
),
'type => file',
);
ok( $h->store($conf) == 1, "Conf is stored" )
or print STDERR "$Lemonldap::NG::Common::Conf::msg $!";
ok( $cfg = $h->getConf( { cfgNum => 1 } ), "Conf can be read" )
or print STDERR $Lemonldap::NG::Common::Conf::msg;
ok( $cfg->{test} eq 'Aa', '%SERVERENV:A% is substitued into Aa' )
or print STDERR "Expect $cfg->{test} eq Aa\n";
ok( $cfg->{test2} eq 'Bb Cc',
'%SERVERENV:B% %SERVERENV:C% is substitued into Bb Cc' )
or print STDERR "Expect $cfg->{test} eq Aa\n";
ok( ( !$cfg->{'%SERVERENV:MYKEY%'} and $cfg->{MyKey} ),
'Keyname is transformed' );
ok( (
$cfg->{MyKey}->{array}->[0] eq 'a'
and $cfg->{MyKey}->{array}->[1] eq 'Bb Cc'
),
'Values are substitued into arrays'
);
ok( $cfg = $h->getConf( { cfgNum => 1, raw => 1 } ), 'Get raw conf' );
ok( $cfg->{test} eq '%SERVERENV:A%',
'%SERVERENV:A% is not substitued into Aa in raw mode' )
or print STDERR "Expect $cfg->{test} eq %SERVERENV:A%\n";
unlink 't/lmConf-1.json';