[pve-devel] r4845 - in pve-manager/pve2: . bin/test lib/PVE

svn-commits at proxmox.com svn-commits at proxmox.com
Fri Jun 25 16:28:36 CEST 2010


Author: dietmar
Date: 2010-06-25 14:28:36 +0000 (Fri, 25 Jun 2010)
New Revision: 4845

Modified:
   pve-manager/pve2/ChangeLog
   pve-manager/pve2/bin/test/example1.pl
   pve-manager/pve2/lib/PVE/API2.pm
   pve-manager/pve2/lib/PVE/API2Client.pm
   pve-manager/pve2/lib/PVE/APIDaemon.pm
   pve-manager/pve2/lib/PVE/JSONSchema.pm
   pve-manager/pve2/lib/PVE/REST.pm
   pve-manager/pve2/lib/PVE/RESTHandler.pm
Log:
	* lib/PVE/APIDaemon.pm (worker_finished): 

	* lib/PVE/JSONSchema.pm: add 'protected' property to method_shema

	* lib/PVE/REST.pm (proxy_handler): automatically proxy protected
	method to 'pvedaemon'



Modified: pve-manager/pve2/ChangeLog
===================================================================
--- pve-manager/pve2/ChangeLog	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/ChangeLog	2010-06-25 14:28:36 UTC (rev 4845)
@@ -1,3 +1,10 @@
+2010-06-25  Proxmox Support Team  <support at proxmox.com>
+
+	* lib/PVE/JSONSchema.pm: add 'protected' property to method_shema
+
+	* lib/PVE/REST.pm (proxy_handler): automatically proxy protected
+	method to 'pvedaemon'
+
 2010-06-24  Proxmox Support Team  <support at proxmox.com>
 
 	* lib/PVE/REST.pm (proxy_handler): implement ability to proxy call to

Modified: pve-manager/pve2/bin/test/example1.pl
===================================================================
--- pve-manager/pve2/bin/test/example1.pl	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/bin/test/example1.pl	2010-06-25 14:28:36 UTC (rev 4845)
@@ -16,6 +16,6 @@
 #   host => 'localhost',
     );
 
-my $res = $conn->post("api2/", {});
+my $res = $conn->get("api2/", {});
 
 print "TEST: " . Dumper($res);

Modified: pve-manager/pve2/lib/PVE/API2.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2.pm	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/lib/PVE/API2.pm	2010-06-25 14:28:36 UTC (rev 4845)
@@ -26,6 +26,7 @@
 
 __PACKAGE__->register_method ({
     name => 'index', 
+    # protected => 1, # fixme: remove
     match_re => [], 
     method => 'GET',
     description => "Directory index.",
@@ -54,7 +55,6 @@
 	    ],
     },
 }); 
-
 sub index {
     my ($conn, $resp) = @_;
     

Modified: pve-manager/pve2/lib/PVE/API2Client.pm
===================================================================
--- pve-manager/pve2/lib/PVE/API2Client.pm	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/lib/PVE/API2Client.pm	2010-06-25 14:28:36 UTC (rev 4845)
@@ -80,12 +80,8 @@
 
 	die "got unexpected content type" if $ct ne 'application/json';
 
-	my $data = decode_json($response->decoded_content);
+	return from_json($response->decoded_content, {utf8 => 1, allow_nonref => 1});
 
-	die $data->{error} if $data->{error};
-
-	return $data;
-
     } else {
 
 	die $response->status_line . "\n";

Modified: pve-manager/pve2/lib/PVE/APIDaemon.pm
===================================================================
--- pve-manager/pve2/lib/PVE/APIDaemon.pm	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/lib/PVE/APIDaemon.pm	2010-06-25 14:28:36 UTC (rev 4845)
@@ -260,15 +260,7 @@
 			    $response->header("Set-Cookie" => $cookie);
 			}
 
-			if ($res->{data}) {
-			    my $raw = to_json($res->{data}, {utf8 => 1});
-			    $response->content($raw);
-			    $response->header("Content-Length" => length($raw));
-
-			} else {
-			    $response->header("Content-Length" => 0);
-			}
-			
+			$response->content(to_json($res->{data}, {utf8 => 1,allow_nonref => 1}));
 			$c->send_response($response);
 		    }
 

Modified: pve-manager/pve2/lib/PVE/JSONSchema.pm
===================================================================
--- pve-manager/pve2/lib/PVE/JSONSchema.pm	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/lib/PVE/JSONSchema.pm	2010-06-25 14:28:36 UTC (rev 4845)
@@ -130,7 +130,7 @@
 sub check_object {
     my ($path, $schema, $value, $additional_properties, $errors) = @_;
 
-   # print "Check Object " . Dumper($value) . "\nSchema: " . Dumper($schema);
+    # print "Check Object " . Dumper($value) . "\nSchema: " . Dumper($schema);
 
     my $st = ref($schema);
     if (!$st || $st ne 'HASH') {
@@ -461,6 +461,7 @@
 
 my $method_schema = {
     type => "object",
+    additionalProperties => 0,
     properties => {
 	description => {
 	    description => "This a description of the method",
@@ -471,7 +472,7 @@
 	    description => "This indicates the name of the function to call.",
 	    optional => 1,
             requires => {
- 		additionalProperties => 0,
+ 		additionalProperties => 1,
 		properties => {
                     name => {},
                     description => {},
@@ -489,6 +490,11 @@
 	    enum => [ 'GET', 'POST', 'PUT', 'DELETE' ],
 	    optional => 1,
 	},
+        protected => {
+            type => 'boolean',
+	    description => "method needs special privileges - only pvedaemon can execute it",            
+	    optional => 1,
+        },
 	match_re => {
 	    type =>  'array',
 	    description => "regular expressions for URL matching",

Modified: pve-manager/pve2/lib/PVE/REST.pm
===================================================================
--- pve-manager/pve2/lib/PVE/REST.pm	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/lib/PVE/REST.pm	2010-06-25 14:28:36 UTC (rev 4845)
@@ -64,16 +64,11 @@
 sub send_response {
     my($r, $data) = @_;
     
-    # my $accept = $r->headers_in->{Accept};
-
-    #$r->content_type ('text/plain');
-    
     $r->content_type ('application/json');
 
-    return if !defined($data);
-
-    my $raw = to_json($data, {utf8 => 1});
+    my $raw = to_json($data, {utf8 => 1, allow_nonref => 1});
     $r->print($raw);
+    $r->err_headers_out()->add('Content-length' , length($raw));
 }
 
 sub proxy_handler {
@@ -132,14 +127,17 @@
     if ($code && ($code != OK)) {
 	$r->status($code);
     }
-    my $message = $response->message;
-    if ($message) {
+
+    if (my $message = $response->message) {
 	$r->status_line("$code $message");
     }
 
     $r->content_type ('application/json');
-    $r->print($response->decoded_content);
+    my $raw = $response->decoded_content;
+    $r->err_headers_out()->add('Content-length' , length($raw));
 
+    $r->print($raw);
+
     syslog('info', "proxy end $method $host:$abs_uri ($code)");
 
     return $code;
@@ -187,9 +185,19 @@
 	params => $params,
     };
 
+    my ($handler, $info) = PVE::API2->find_handler($method, $stack, $conn);
+    if (!$handler || !$info) {
+	return {
+	    status => HTTP_NOT_IMPLEMENTED,
+	    message => "Method '$abs_uri' not implemented",
+	};
+    }
+
+    return { proxy => 'localhost' } if $info->{protected} && ($euid != 0);
+
     my $resp = {};
  
-    my $ret = { status => PVE::API2->handle($method, $stack, $conn, $resp) };
+    my $ret = { status => $handler->handle($info, $conn, $resp) };
 
     # fixme: update ticket if too old
     # $ret->{ticket} = update_ticket($ticket);

Modified: pve-manager/pve2/lib/PVE/RESTHandler.pm
===================================================================
--- pve-manager/pve2/lib/PVE/RESTHandler.pm	2010-06-25 12:00:46 UTC (rev 4844)
+++ pve-manager/pve2/lib/PVE/RESTHandler.pm	2010-06-25 14:28:36 UTC (rev 4845)
@@ -62,27 +62,26 @@
     }
 }
 
-sub handle {
-    my ($self, $method, $stack, $conn, $resp) = @_;
+sub find_handler {
+    my ($class, $method, $stack, $conn) = @_;
 
     my $info;
     eval {
-	$info = $self->map_method($stack, $method);
+	$info = $class->map_method($stack, $method);
     };
     syslog('err', $@) if $@;
 
     if (!$info) {
-	$resp->{message} = "Method $method not implemented";
-	$resp->{status} = HTTP_NOT_IMPLEMENTED;
-	return $resp->{status};
+	syslog('info', "Method $method not implemented");
+	return undef;
     }
 
     if (my $subh = $info->{subclass}) {
 	eval "require $subh;";
+
 	if ($@) {
-	    $resp->{message} = "Method $method not implemented - missing subclass '$subh'";
-	    $resp->{status} = HTTP_NOT_IMPLEMENTED;
-	    return $resp->{status};
+	    syslog ('err', "Method $method not implemented - missing subclass '$subh'");
+	    return undef;
 	}
 
 	my $matchlen = scalar(@{$info->{match_re}});
@@ -92,9 +91,15 @@
 	    # fixme: store $fragments somewhere ?
 	}
 
-	return $subh->handle($method, $stack, $conn, $resp);
+	return $subh->find_handle($method, $stack, $conn);
     }
 
+    return ($class, $info);
+}
+
+sub handle {
+    my ($self, $info, $conn, $resp) = @_;
+
     my $func = $info->{name} ? $self->can($info->{name}) : undef;
 
     if (!($info->{name} && $func)) {



More information about the pve-devel mailing list