From: Fabian Grünbichler Date: Tue, 5 Apr 2016 07:20:50 +0000 (+0200) Subject: Handle string parameter to file content replacement X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=commitdiff_plain;h=408976c6f711f82895b105733b914660384160df Handle string parameter to file content replacement This is modelled after the way read_password() is used to wrap -password parameters on the command line. If a mapping for a certain API method and parameter is defined in the sub class of CLIHandler.pm, the parameter is interpreted as a file path on the command line and the parameter is filled with the string contents of the referenced file. This allows us to use the same API schema once in API2, but overwrite the behaviour for individual parameters in the CLI tools when desired. --- diff --git a/src/PVE/CLIHandler.pm b/src/PVE/CLIHandler.pm index c2d3438..9a2f841 100644 --- a/src/PVE/CLIHandler.pm +++ b/src/PVE/CLIHandler.pm @@ -452,7 +452,7 @@ sub generate_asciidoc_synopsys { } my $handle_cmd = sub { - my ($def, $cmdname, $cmd, $args, $pwcallback, $podfn, $preparefunc) = @_; + my ($def, $cmdname, $cmd, $args, $pwcallback, $podfn, $preparefunc, $stringfilemap) = @_; $cmddef = $def; $exename = $cmdname; @@ -486,13 +486,13 @@ my $handle_cmd = sub { } my $prefix = "$exename $cmd"; - my $res = $class->cli_handler($prefix, $name, \@ARGV, $arg_param, $uri_param, $pwcallback); + my $res = $class->cli_handler($prefix, $name, \@ARGV, $arg_param, $uri_param, $pwcallback, $stringfilemap); &$outsub($res) if $outsub; }; my $handle_simple_cmd = sub { - my ($def, $args, $pwcallback, $podfn, $preparefunc) = @_; + my ($def, $args, $pwcallback, $podfn, $preparefunc, $stringfilemap) = @_; my ($class, $name, $arg_param, $uri_param, $outsub) = @{$def}; die "no class specified" if !$class; @@ -519,7 +519,7 @@ my $handle_simple_cmd = sub { &$preparefunc() if $preparefunc; - my $res = $class->cli_handler($name, $name, \@ARGV, $arg_param, $uri_param, $pwcallback); + my $res = $class->cli_handler($name, $name, \@ARGV, $arg_param, $uri_param, $pwcallback, $stringfilemap); &$outsub($res) if $outsub; }; @@ -553,6 +553,7 @@ sub run_cli_handler { my $no_init = $params{no_init}; my $pwcallback = $class->can('read_password'); + my $stringfilemap = $class->can('string_param_file_mapping'); $exename = &$get_exe_name($class); @@ -573,11 +574,11 @@ sub run_cli_handler { my $def = ${"${class}::cmddef"}; if (ref($def) eq 'ARRAY') { - &$handle_simple_cmd($def, \@ARGV, $pwcallback, $podfn, $preparefunc); + &$handle_simple_cmd($def, \@ARGV, $pwcallback, $podfn, $preparefunc, $stringfilemap); } else { $cmddef = $def; my $cmd = shift @ARGV; - &$handle_cmd($cmddef, $exename, $cmd, \@ARGV, $pwcallback, $podfn, $preparefunc); + &$handle_cmd($cmddef, $exename, $cmd, \@ARGV, $pwcallback, $podfn, $preparefunc, $stringfilemap); } exit 0; diff --git a/src/PVE/RESTHandler.pm b/src/PVE/RESTHandler.pm index edf23d1..9e0980e 100644 --- a/src/PVE/RESTHandler.pm +++ b/src/PVE/RESTHandler.pm @@ -631,14 +631,29 @@ sub dump_properties { return $raw; } +my $replace_file_names_with_contents = sub { + my ($param, $mapping) = @_; + + if ($mapping) { + foreach my $elem ( @$mapping ) { + $param->{$elem} = PVE::Tools::file_get_contents($param->{$elem}) + if defined($param->{$elem}); + } + } + + return $param; +}; + sub cli_handler { - my ($self, $prefix, $name, $args, $arg_param, $fixed_param, $pwcallback) = @_; + my ($self, $prefix, $name, $args, $arg_param, $fixed_param, $pwcallback, $stringfilemap) = @_; my $info = $self->map_method_by_name($name); my $res; eval { my $param = PVE::JSONSchema::get_options($info->{parameters}, $args, $arg_param, $fixed_param, $pwcallback); + &$replace_file_names_with_contents($param, &$stringfilemap($name)) + if defined($stringfilemap); $res = $self->handle($info, $param); }; if (my $err = $@) {