Handle string parameter to file content replacement
authorFabian Gr├╝nbichler <f.gruenbichler@proxmox.com>
Tue, 5 Apr 2016 07:20:50 +0000 (09:20 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 5 Apr 2016 10:22:38 +0000 (12:22 +0200)
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.

src/PVE/CLIHandler.pm
src/PVE/RESTHandler.pm

index c2d34387ac87c4a9331d229f6064cbe1e5625498..9a2f8418e21cd51d748e2fa08451181575af4c2b 100644 (file)
@@ -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;
index edf23d155d8fe273e7a628b3b00bb5ba2bcdc46b..9e0980e9832ded60bae76730a14377f28b1c2b93 100644 (file)
@@ -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 = $@) {