From 482eddb10cb15ebe9253840da96f1f57b3e483a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lesimple?= Date: Wed, 31 May 2023 13:03:24 +0000 Subject: [PATCH] feat: plugins: add loadConfig parameter & config validator support --- .../restricted/accountAddPersonalAccess | 7 +++--- bin/plugin/restricted/selfAddPersonalAccess | 7 +++--- lib/perl/OVH/Bastion/Plugin.pm | 25 ++++++++++++++----- lib/perl/OVH/Bastion/configuration.inc | 25 ++++++++++++++++--- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/bin/plugin/restricted/accountAddPersonalAccess b/bin/plugin/restricted/accountAddPersonalAccess index 3739bc0..526d880 100755 --- a/bin/plugin/restricted/accountAddPersonalAccess +++ b/bin/plugin/restricted/accountAddPersonalAccess @@ -10,9 +10,10 @@ use OVH::Bastion::Plugin qw( :DEFAULT help ); use OVH::Bastion::Plugin::ACL; my $remainingOptions = OVH::Bastion::Plugin::begin( - argv => \@ARGV, - header => "adding personal access to a server on an account", - options => { + loadConfig => 1, + argv => \@ARGV, + header => "adding personal access to a server on an account", + options => { "account=s" => \my $account, "user-any" => \my $userAny, "port-any" => \my $portAny, diff --git a/bin/plugin/restricted/selfAddPersonalAccess b/bin/plugin/restricted/selfAddPersonalAccess index 139bbe2..4e25073 100755 --- a/bin/plugin/restricted/selfAddPersonalAccess +++ b/bin/plugin/restricted/selfAddPersonalAccess @@ -10,9 +10,10 @@ use OVH::Bastion::Plugin qw( :DEFAULT help ); use OVH::Bastion::Plugin::ACL; my $remainingOptions = OVH::Bastion::Plugin::begin( - argv => \@ARGV, - header => "adding personal access to a server on your account", - options => { + loadConfig => 1, + argv => \@ARGV, + header => "adding personal access to a server on your account", + options => { "user-any" => \my $userAny, "port-any" => \my $portAny, "scpup" => \my $scpUp, diff --git a/lib/perl/OVH/Bastion/Plugin.pm b/lib/perl/OVH/Bastion/Plugin.pm index 0a50a5c..741276f 100644 --- a/lib/perl/OVH/Bastion/Plugin.pm +++ b/lib/perl/OVH/Bastion/Plugin.pm @@ -15,8 +15,10 @@ $SIG{'PIPE'} = 'IGNORE'; # continue even if osh_info gets a SIGPIPE because t $| = 1; use Exporter 'import'; -our ($user, $ip, $host, $port, $scriptName, $self, $sysself, $realm, $remoteself, $HOME, $savedArgs); ## no critic (ProhibitPackageVars) -our @EXPORT = qw( $user $ip $host $port $scriptName $self $sysself $realm $remoteself $HOME $savedArgs ); ## no critic (ProhibitAutomaticExportation) +## no critic (ProhibitPackageVars) +our ($user, $ip, $host, $port, $scriptName, $self, $sysself, $realm, $remoteself, $HOME, $savedArgs, $pluginConfig); +## no critic (ProhibitAutomaticExportation) +our @EXPORT = qw( $user $ip $host $port $scriptName $self $sysself $realm $remoteself $HOME $savedArgs $pluginConfig ); our @EXPORT_OK = qw( help ); my $_helptext; @@ -25,10 +27,11 @@ sub help { osh_info $_helptext; return 1; } sub begin { my %params = @_; - my $options = $params{'options'}; - my $header = $params{'header'}; - my $argv = $params{'argv'}; - my $helpfunc = $params{'help'}; + my $options = $params{'options'}; + my $header = $params{'header'}; + my $argv = $params{'argv'}; + my $loadConfig = $params{'loadConfig'}; + my $helpfunc = $params{'help'}; $_helptext = $params{'helptext'}; my $fnret; @@ -147,6 +150,16 @@ sub begin { "Error with your USER (\"$sysself\" vs \"$ENV{'USER'}\"), please report to your sysadmin."; } + if ($loadConfig) { + # try to load config, and abort if we get an error + $fnret = OVH::Bastion::plugin_config(plugin => $scriptName); + if (!$fnret) { + warn_syslog("Invalid configuration for plugin $scriptName: $fnret"); + osh_exit 'ERR_INVALID_CONFIGURATION', "Error in plugin configuration, aborting"; + } + $pluginConfig = $fnret->value; + } + # only unparsed options are remaining there return \@pluginOptions; } diff --git a/lib/perl/OVH/Bastion/configuration.inc b/lib/perl/OVH/Bastion/configuration.inc index eef9fe4..947f270 100644 --- a/lib/perl/OVH/Bastion/configuration.inc +++ b/lib/perl/OVH/Bastion/configuration.inc @@ -788,7 +788,6 @@ sub plugin_config { secure => 1 ); if ($fnret->err eq 'KO_CANNOT_OPEN_FILE') { - # chmod error, don't fail silently warn_syslog("Can't read configuration file '" . OVH::Bastion::main_configuration_directory() @@ -796,13 +795,33 @@ sub plugin_config { return R('ERR_CONFIGURATION_ERROR', msg => "Configuration file has improper rights, ask your sysadmin!"); } - if ($fnret && ref $fnret->value eq 'HASH') { - + elsif ($fnret->err eq 'KO_NO_SUCH_FILE') { + # no configuration, just continue + } + elsif (!($fnret && ref $fnret->value eq 'HASH')) { + # other error, report it and fail + warn_syslog("Error loading plugin $plugin configuration ($fnret)"); + return R('ERR_CONFIGURATION_ERROR', msg => "Plugin configuration is invalid, aborting"); + } + else { # avoid overriding keys foreach my $key (keys %{$fnret->value}) { $config{$key} = $fnret->value->{$key} if not exists $config{$key}; } } + + # do we have a config validator for this plugin? + ## no critic(Modules::RequireBarewordIncludes) + eval { require "OVH::Bastion::Plugin::$plugin"; }; + if (!$@) { + my $validator = "OVH::Bastion::Plugin::${plugin}::validate_config"; + $fnret = $validator->(config => \%config); + if (!$fnret || !$fnret->value) { + warn_syslog("Invalid configuration for plugin $plugin: $fnret"); + return R('ERR_INVALID_CONFIGURATION', msg => "Plugin configuration is invalid"); + } + %config = %{$fnret->value}; + } } else { %config = %$mock_data;