[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