[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