[pve-devel] r4970 - pve-common/trunk

svn-commits at proxmox.com svn-commits at proxmox.com
Wed Aug 11 14:03:37 CEST 2010


Author: dietmar
Date: 2010-08-11 12:03:37 +0000 (Wed, 11 Aug 2010)
New Revision: 4970

Modified:
   pve-common/trunk/ChangeLog
   pve-common/trunk/JSONSchema.pm
   pve-common/trunk/RESTHandler.pm
Log:
	* RESTHandler.pm (cli_handler): helper function to call method
	directly, parsing command line args using new JSONSchema::get_options()

	* JSONSchema.pm (get_options): a way to parse command line
	parameters, using a schema to configure Getopt::Long



Modified: pve-common/trunk/ChangeLog
===================================================================
--- pve-common/trunk/ChangeLog	2010-08-11 10:08:12 UTC (rev 4969)
+++ pve-common/trunk/ChangeLog	2010-08-11 12:03:37 UTC (rev 4970)
@@ -1,3 +1,11 @@
+2010-08-11  Proxmox Support Team  <support at proxmox.com>
+
+	* RESTHandler.pm (cli_handler): helper function to call method
+	directly, parsing command line args using new JSONSchema::get_options()
+
+	* JSONSchema.pm (get_options): a way to parse command line
+	parameters, using a schema to configure Getopt::Long
+
 2010-08-10  Proxmox Support Team  <support at proxmox.com>
 
 	* INotify.pm (parse_ccache_options): new shadow option

Modified: pve-common/trunk/JSONSchema.pm
===================================================================
--- pve-common/trunk/JSONSchema.pm	2010-08-11 10:08:12 UTC (rev 4969)
+++ pve-common/trunk/JSONSchema.pm	2010-08-11 12:03:37 UTC (rev 4970)
@@ -3,6 +3,7 @@
 use warnings;
 use strict;
 use Storable; # for dclone
+use Getopt::Long;
 use Devel::Cycle -quiet; # fixme: remove?
 use Data::Dumper; # fixme: remove
 
@@ -603,4 +604,54 @@
     return $found;
 }
 
+# a way to parse command line parameters, using a 
+# schema to configure Getopt::Long
+sub get_options {
+    my ($schema, $args, $uri_param, $pwcallback) = @_;
+
+    if (!$schema || !$schema->{properties}) {
+	die "too many arguments\n"
+	    if scalar(@$args) != 0;
+	return {};
+    }
+
+    my @getopt = ();
+    foreach my $prop (keys %{$schema->{properties}}) {
+	my $pd = $schema->{properties}->{$prop};
+	next if defined($uri_param->{$prop});
+
+	if ($prop eq 'password' && $pwcallback) {
+	    # we do not accept plain password on input line, instead
+	    # we turn this into a boolean option and ask for password below
+	    # using $pwcallback() (for security reasons).
+	    push @getopt, "$prop";
+	} elsif ($pd->{type} eq 'boolean') {
+	    push @getopt, "$prop";
+	} else {
+	    push @getopt, "$prop=s";
+	}
+    }
+
+    my $opts = {};
+    die "unable to parse option\n"
+	if !Getopt::Long::GetOptionsFromArray($args, $opts, @getopt);
+    
+    die "too many arguments\n"
+	if scalar(@$args) != 0;
+
+    if (my $pd = $schema->{properties}->{password}) {
+	if ($pd->{type} ne 'boolean' && $pwcallback) {
+	    if ($opts->{password} || !$pd->{optional}) {
+		$opts->{password} = &$pwcallback(); 
+	    }
+	}
+    }
+
+    foreach my $p (keys %$uri_param) {
+	$opts->{$p} = $uri_param->{$p};
+    }
+
+    return $opts;
+}
+
 1;

Modified: pve-common/trunk/RESTHandler.pm
===================================================================
--- pve-common/trunk/RESTHandler.pm	2010-08-11 10:08:12 UTC (rev 4969)
+++ pve-common/trunk/RESTHandler.pm	2010-08-11 12:03:37 UTC (rev 4970)
@@ -50,24 +50,16 @@
     push @{$method_registry->{$self}}, $info;
 }
 
-sub AUTOLOAD {
-    my $self = shift;
+my $call_local_method = sub {
+    my ($self, $info, $param) = @_;
 
-    my $method = $AUTOLOAD;
-
-    $method =~ s/.*:://;
-   
-    my $info = $method_by_name->{$self}->{$method};
-    
-    die "no such method '${self}::$method'\n" if !$info;
-
     # fixme: how do we handle this here?
     # fixme: language ?
     my $conn = {
 #	abs_uri => $abs_uri,
 #	rel_uri => $rel_uri,
 #	user => $username,
-	params => shift || {},
+	params => $param || {},
     };
 
     my $res = {};
@@ -87,6 +79,20 @@
     }
 
     return $res->{data};
+};
+
+sub AUTOLOAD {
+    my $self = shift;
+
+    my $method = $AUTOLOAD;
+
+    $method =~ s/.*:://;
+
+    my $info = $self->map_method_by_name($method);
+
+    my $param = shift;
+
+    return $self->$call_local_method($info, $param);
 }
 
 sub method_attributes {
@@ -95,6 +101,15 @@
     return $method_registry->{$self};
 }
 
+sub map_method_by_name {
+    my ($self, $name) = @_;
+
+    my $info = $method_by_name->{$self}->{$name};
+    die "no such method '${self}::$name'\n" if !$info;
+
+    return $info;
+}
+
 sub map_method {
     my ($self, $stack, $method, $uri_param) = @_;
 
@@ -226,6 +241,16 @@
     return $resp->{status};
 }
 
+sub cli_handler {
+    my ($self, $name, $args, $uri_param, $pwcallback) = @_;
+
+    my $info = $self->map_method_by_name($name);
+
+    my $param = PVE::JSONSchema::get_options($info->{parameters}, $args, $uri_param, $pwcallback);
+
+    return $self->$call_local_method($info, $param);
+}
+
 # utility methods
 # note: this modifies the original hash by adding the id property
 sub hash_to_array {



More information about the pve-devel mailing list