From 8682f63414d5d834bf11b57cdead8ca6da5a4717 Mon Sep 17 00:00:00 2001 From: Xavier Guimard Date: Tue, 28 Mar 2017 17:09:48 +0000 Subject: [PATCH] Add YAML configuration backend (#1208) --- lemonldap-ng-common/MANIFEST | 1 + lemonldap-ng-common/lemonldap-ng.ini | 4 +- .../Lemonldap/NG/Common/Conf/Backends/YAML.pm | 134 ++++++++++++++++++ 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Backends/YAML.pm diff --git a/lemonldap-ng-common/MANIFEST b/lemonldap-ng-common/MANIFEST index 843591e1c..87f73bb02 100644 --- a/lemonldap-ng-common/MANIFEST +++ b/lemonldap-ng-common/MANIFEST @@ -23,6 +23,7 @@ lib/Lemonldap/NG/Common/Conf/Backends/MongoDB.pm lib/Lemonldap/NG/Common/Conf/Backends/RDBI.pm lib/Lemonldap/NG/Common/Conf/Backends/REST.pm lib/Lemonldap/NG/Common/Conf/Backends/SOAP.pm +lib/Lemonldap/NG/Common/Conf/Backends/YAML.pm lib/Lemonldap/NG/Common/Conf/Compact.pm lib/Lemonldap/NG/Common/Conf/Constants.pm lib/Lemonldap/NG/Common/Conf/DefaultValues.pm diff --git a/lemonldap-ng-common/lemonldap-ng.ini b/lemonldap-ng-common/lemonldap-ng.ini index 896988df7..5cf50eb0e 100644 --- a/lemonldap-ng-common/lemonldap-ng.ini +++ b/lemonldap-ng-common/lemonldap-ng.ini @@ -86,11 +86,11 @@ logLevel = warn [configuration] ; GLOBAL CONFIGURATION ACCESS TYPE -; (File, SOAP, RDBI/CDBI, LDAP) +; (File, SOAP, RDBI/CDBI, LDAP, YAMLFile) ; Set here the parameters needed to access to LemonLDAP::NG configuration. ; You have to set "type" to one of the followings : ; -; * File: you have to set 'dirName' parameter. Example: +; * File/YAMLFile: you have to set 'dirName' parameter. Example: ; ; type = File ; dirName = /var/lib/lemonldap-ng/conf diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Backends/YAML.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Backends/YAML.pm new file mode 100644 index 000000000..48f2ba5b3 --- /dev/null +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/Conf/Backends/YAML.pm @@ -0,0 +1,134 @@ +package Lemonldap::NG::Common::Conf::Backends::YAMLFile; + +use strict; +use Lemonldap::NG::Common::Conf::Constants; #inherits +use YAML qw(); +use Encode; + +our $VERSION = '2.0.0'; +our $initDone; + +sub Lemonldap::NG::Common::Conf::_yamlLock { + my ( $self, $cfgNum ) = @_; + return "$self->{dirName}/lmConf.yamlLock"; +} + +sub Lemonldap::NG::Common::Conf::_yamlFile { + my ( $self, $cfgNum ) = @_; + return "$self->{dirName}/lmConf-$cfgNum.yaml"; +} + +sub prereq { + my $self = shift; + unless ( $self->{dirName} ) { + $Lemonldap::NG::Common::Conf::msg .= + "'dirName' is required in 'File' configuration type ! \n"; + return 0; + } + unless ( -d $self->{dirName} ) { + $Lemonldap::NG::Common::Conf::msg .= + "Directory \"$self->{dirName}\" does not exist ! \n"; + return 0; + } + 1; +} + +sub available { + my $self = shift; + opendir D, $self->{dirName}; + my @conf = readdir(D); + closedir D; + @conf = + sort { $a <=> $b } + map { /lmConf-(\d+)\.yaml/ ? ( $1 + 0 ) : () } @conf; + return @conf; +} + +sub lastCfg { + my $self = shift; + my @avail = $self->available; + return $avail[$#avail]; +} + +sub lock { + my $self = shift; + if ( $self->isLocked ) { + sleep 2; + return 0 if ( $self->isLocked ); + } + unless ( open F, ">" . $self->_yamlLock ) { + $Lemonldap::NG::Common::Conf::msg .= + "Unable to lock (" . $self->_yamlLock . ") \n"; + return 0; + } + print F $$; + close F; + return 1; +} + +sub isLocked { + my $self = shift; + -e $self->_yamlLock; +} + +sub unlock { + my $self = shift; + unlink $self->_yamlLock; + 1; +} + +sub store { + my ( $self, $fields ) = @_; + my $mask = umask; + umask( oct('0027') ); + unless ( open FILE, '>', $self->_yamlFile( $fields->{cfgNum} ) ) { + $Lemonldap::NG::Common::Conf::msg = "Open file failed: $! \n"; + $self->unlock; + return UNKNOWN_ERROR; + } + binmode(FILE); + my $f = YAML::Dump($fields); + print FILE $f; + close FILE; + umask($mask); + return $fields->{cfgNum}; +} + +sub load { + my ( $self, $cfgNum, $fields ) = @_; + my ( $f, $filename ); + $filename = $self->_yamlFile($cfgNum); + local $/ = ''; + my $ret; + unless ( open FILE, $filename ) { + $Lemonldap::NG::Common::Conf::msg .= "Read error: $!$@"; + return undef; + } + binmode FILE; + $f = join( '', ); + eval { $ret = YAML::Load($f) }; + if ($@) { + print STDERR "$@\n"; + $Lemonldap::NG::Common::Conf::msg .= "JSON fails to read file: $@ \n"; + return undef; + } + return $ret; +} + +sub delete { + my ( $self, $cfgNum ) = @_; + my $file = $self->_yamlFile($cfgNum); + if ( -e $file ) { + my $res = unlink($file); + $Lemonldap::NG::Common::Conf::msg .= $! unless ($res); + return $res; + } + else { + $Lemonldap::NG::Common::Conf::msg .= + "Unable to delete conf $cfgNum, no such file"; + return 0; + } +} + +1; +__END__