]> git.proxmox.com Git - pmg-api.git/blobdiff - PMG/API2/Nodes.pm
node: journal: minor code cleanup
[pmg-api.git] / PMG / API2 / Nodes.pm
index 61141ffabf0d258df3db9e738b8f47dd0b00e149..96aa146ea59b8d9e6bf79e95b2f0dd9a11379ded 100644 (file)
@@ -15,13 +15,17 @@ use PVE::ProcFSTools;
 
 use PMG::pmgcfg;
 use PMG::Ticket;
+use PMG::Report;
+use PMG::API2::Subscription;
 use PMG::API2::APT;
 use PMG::API2::Tasks;
 use PMG::API2::Services;
 use PMG::API2::Network;
 use PMG::API2::ClamAV;
+use PMG::API2::SpamAssassin;
 use PMG::API2::Postfix;
 use PMG::API2::MailTracker;
+use PMG::API2::Backup;
 
 use base qw(PVE::RESTHandler);
 
@@ -35,6 +39,11 @@ __PACKAGE__->register_method ({
     path => 'clamav',
 });
 
+__PACKAGE__->register_method ({
+    subclass => "PMG::API2::SpamAssassin",
+    path => 'spamassassin',
+});
+
 __PACKAGE__->register_method ({
     subclass => "PMG::API2::Network",
     path => 'network',
@@ -50,6 +59,11 @@ __PACKAGE__->register_method ({
     path => 'services',
 });
 
+__PACKAGE__->register_method ({
+    subclass => "PMG::API2::Subscription",
+    path => 'subscription',
+});
+
 __PACKAGE__->register_method ({
     subclass => "PMG::API2::APT",
     path => 'apt',
@@ -60,6 +74,11 @@ __PACKAGE__->register_method ({
     path => 'tracker',
 });
 
+__PACKAGE__->register_method ({
+    subclass => "PMG::API2::Backup",
+    path => 'backup',
+});
+
 __PACKAGE__->register_method ({
     name => 'index',
     path => '',
@@ -85,27 +104,54 @@ __PACKAGE__->register_method ({
 
        my $result = [
            { name => 'apt' },
+           { name => 'backup' },
            { name => 'clamav' },
+           { name => 'spamassassin' },
            { name => 'postfix' },
            { name => 'services' },
            { name => 'syslog' },
+           { name => 'journal' },
            { name => 'tasks' },
            { name => 'tracker' },
            { name => 'time' },
+           { name => 'report' },
            { name => 'status' },
-           { name => 'vncshell' },
+           { name => 'subscription' },
+           { name => 'termproxy' },
            { name => 'rrddata' },
        ];
 
        return $result;
     }});
 
+__PACKAGE__->register_method({
+    name => 'report',
+    path => 'report',
+    method => 'GET',
+    protected => 1,
+    proxyto => 'node',
+    permissions => { check => [ 'admin', 'audit' ] },
+    description => "Gather various system information about a node",
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           node => get_standard_option('pve-node'),
+       },
+    },
+    returns => {
+       type => 'string',
+    },
+    code => sub {
+       return PMG::Report::generate();
+    }});
+
 __PACKAGE__->register_method({
     name => 'rrddata',
     path => 'rrddata',
     method => 'GET',
     protected => 1, # fixme: can we avoid that?
     proxyto => 'node',
+    permissions => { check => [ 'admin', 'audit' ] },
     description => "Read node RRD statistics",
     parameters => {
        additionalProperties => 0,
@@ -146,6 +192,7 @@ __PACKAGE__->register_method({
     description => "Read system log",
     proxyto => 'node',
     protected => 1,
+    permissions => { check => [ 'admin', 'audit' ] },
     parameters => {
        additionalProperties => 0,
        properties => {
@@ -214,21 +261,89 @@ __PACKAGE__->register_method({
        return $lines;
     }});
 
+__PACKAGE__->register_method({
+    name => 'journal',
+    path => 'journal',
+    method => 'GET',
+    description => "Read Journal",
+    proxyto => 'node',
+    permissions => { check => [ 'admin', 'audit' ] },
+    protected => 1,
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           node => get_standard_option('pve-node'),
+           since => {
+               description => "Display all log since this UNIX epoch. Conflicts with 'startcursor'.",
+               type => 'integer',
+               minimum => 0,
+               optional => 1,
+           },
+           until => {
+               description => "Display all log until this UNIX epoch. Conflicts with 'endcursor'.",
+               type => 'integer',
+               minimum => 0,
+               optional => 1,
+           },
+           lastentries => {
+               description => "Limit to the last X lines. Conflicts with a range.",
+               type => 'integer',
+               minimum => 0,
+               optional => 1,
+           },
+           startcursor => {
+               description => "Start after the given Cursor. Conflicts with 'since'.",
+               type => 'string',
+               optional => 1,
+           },
+           endcursor => {
+               description => "End before the given Cursor. Conflicts with 'until'.",
+               type => 'string',
+               optional => 1,
+           },
+       },
+    },
+    returns => {
+       type => 'array',
+       items => {
+           type => "string",
+       }
+    },
+    code => sub {
+       my ($param) = @_;
+
+       my $cmd = ["/usr/bin/mini-journalreader"];
+       push @$cmd, '-n', $param->{lastentries} if $param->{lastentries};
+       push @$cmd, '-b', $param->{since} if $param->{since};
+       push @$cmd, '-e', $param->{until} if $param->{until};
+       push @$cmd, '-f', $param->{startcursor} if $param->{startcursor};
+       push @$cmd, '-t', $param->{endcursor} if $param->{endcursor};
+
+       my $lines = [];
+       my $parser = sub { push @$lines, shift };
+
+       PVE::Tools::run_command($cmd, outfunc => $parser);
+
+       return $lines;
+    }});
+
+
 __PACKAGE__->register_method ({
-    name => 'vncshell',
-    path => 'vncshell',
+    name => 'termproxy',
+    path => 'termproxy',
     method => 'POST',
+    permissions => { check => [ 'admin' ] },
     protected => 1,
-    description => "Creates a VNC Shell proxy.",
+    description => "Creates a Terminal proxy.",
     parameters => {
        additionalProperties => 0,
        properties => {
            node => get_standard_option('pve-node'),
-           websocket => {
-               optional => 1,
+           upgrade => {
                type => 'boolean',
-               description => "use websocket instead of standard vnc.",
-               default => 1,
+               description => "Run 'apt-get dist-upgrade' instead of normal shell.",
+               optional => 1,
+               default => 0,
            },
        },
     },
@@ -246,15 +361,17 @@ __PACKAGE__->register_method ({
 
        my $node = $param->{node};
 
-       # we only implement the websocket based VNC here
-       my $websocket = $param->{websocket} // 1;
-       die "standard VNC not implemented" if !$websocket;
+       if ($node ne PVE::INotify::nodename()) {
+           die "termproxy to remote node not implemented";
+       }
 
        my $authpath = "/nodes/$node";
 
        my $restenv = PMG::RESTEnvironment->get();
        my $user = $restenv->get_user();
 
+       raise_perm_exc('user != root@pam') if $param->{upgrade} && $user ne 'root@pam';
+
        my $ticket = PMG::Ticket::assemble_vnc_ticket($user, $authpath);
 
        my $family = PVE::Tools::get_host_address_family($node);
@@ -263,42 +380,34 @@ __PACKAGE__->register_method ({
        my $shcmd;
 
        if ($user eq 'root@pam') {
-           $shcmd = [ '/bin/login', '-f', 'root' ];
+           if ($param->{upgrade}) {
+               my $upgradecmd = "pmgupgrade --shell";
+               # $upgradecmd = PVE::Tools::shellquote($upgradecmd) if $remip;
+               $shcmd = [ '/bin/bash', '-c', $upgradecmd ];
+           } else {
+               $shcmd = [ '/bin/login', '-f', 'root' ];
+           }
        } else {
            $shcmd = [ '/bin/login' ];
        }
 
-       my $cmd = ['/usr/bin/vncterm', '-rfbport', $port,
-                  '-timeout', 10, '-notls', '-listen', 'localhost',
-                  '-c', @$shcmd];
+       my $cmd = ['/usr/bin/termproxy', $port, '--path', $authpath,
+                  '--', @$shcmd];
 
        my $realcmd = sub {
            my $upid = shift;
 
-           syslog ('info', "starting vnc proxy $upid\n");
+           syslog ('info', "starting termproxy $upid\n");
 
            my $cmdstr = join (' ', @$cmd);
            syslog ('info', "launch command: $cmdstr");
 
-           eval {
-               foreach my $k (keys %ENV) {
-                   next if $k eq 'PATH' || $k eq 'TERM' || $k eq 'USER' || $k eq 'HOME';
-                   delete $ENV{$k};
-               }
-               $ENV{PWD} = '/';
-
-               $ENV{PVE_VNC_TICKET} = $ticket; # pass ticket to vncterm
-
-               PVE::Tools::run_command($cmd, errmsg => "vncterm failed");
-           };
-           if (my $err = $@) {
-               syslog('err', $err);
-           }
+           PVE::Tools::run_command($cmd);
 
            return;
        };
 
-       my $upid = $restenv->fork_worker('vncshell', "", $user, $realcmd);
+       my $upid = $restenv->fork_worker('termproxy', "", $user, $realcmd);
 
        PVE::Tools::wait_for_vnc_port($port);
 
@@ -314,6 +423,7 @@ __PACKAGE__->register_method({
     name => 'vncwebsocket',
     path => 'vncwebsocket',
     method => 'GET',
+    permissions => { check => [ 'admin' ] },
     description => "Opens a weksocket for VNC traffic.",
     parameters => {
        additionalProperties => 0,
@@ -359,6 +469,7 @@ __PACKAGE__->register_method({
     method => 'GET',
     description => "Read DNS settings.",
     proxyto => 'node',
+    permissions => { check => [ 'admin', 'audit' ] },
     parameters => {
        additionalProperties => 0,
        properties => {
@@ -447,6 +558,7 @@ __PACKAGE__->register_method({
     method => 'GET',
     description => "Read server time and time zone settings.",
     proxyto => 'node',
+    permissions => { check => [ 'admin', 'audit' ] },
     parameters => {
        additionalProperties => 0,
        properties => {
@@ -519,6 +631,7 @@ __PACKAGE__->register_method({
     method => 'GET',
     description => "Read server status. This is used by the cluster manager to test the node health.",
     proxyto => 'node',
+    permissions => { check => [ 'admin', 'qmanager', 'audit' ] },
     protected => 1,
     parameters => {
        additionalProperties => 0,
@@ -602,12 +715,49 @@ __PACKAGE__->register_method({
            total => $dinfo->{blocks},
            avail => $dinfo->{bavail},
            used => $dinfo->{used},
-           free => $dinfo->{bavail} - $dinfo->{used},
+           free => $dinfo->{blocks} - $dinfo->{used},
        };
 
+       if (my $subinfo = PVE::INotify::read_file('subscription')) {
+           if (my $level = $subinfo->{level}) {
+               $res->{level} = $level;
+           }
+       }
+
        return $res;
    }});
 
+__PACKAGE__->register_method({
+    name => 'node_cmd',
+    path => 'status',
+    method => 'POST',
+    permissions => { check => [ 'admin' ] },
+    protected => 1,
+    description => "Reboot or shutdown a node.",
+    proxyto => 'node',
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           node => get_standard_option('pve-node'),
+           command => {
+               description => "Specify the command.",
+               type => 'string',
+               enum => [qw(reboot shutdown)],
+           },
+       },
+    },
+    returns => { type => "null" },
+    code => sub {
+       my ($param) = @_;
+
+       if ($param->{command} eq 'reboot') {
+           system ("(sleep 2;/sbin/reboot)&");
+       } elsif ($param->{command} eq 'shutdown') {
+           system ("(sleep 2;/sbin/poweroff)&");
+       }
+
+       return undef;
+    }});
 
 package PMG::API2::Nodes;