pve-manager/PVE/API2/Certificates.pm

214 lines
4.8 KiB
Perl
Raw Permalink Normal View History

package PVE::API2::Certificates;
use strict;
use warnings;
use PVE::API2::ACME;
use PVE::Certificate;
use PVE::CertHelpers;;
use PVE::Exception qw(raise_param_exc);
use PVE::JSONSchema qw(get_standard_option);
use PVE::Tools qw(extract_param file_get_contents file_set_contents);
use base qw(PVE::RESTHandler);
__PACKAGE__->register_method ({
subclass => "PVE::API2::ACME",
path => 'acme',
});
__PACKAGE__->register_method ({
name => 'index',
path => '',
method => 'GET',
permissions => { user => 'all' },
description => "Node index.",
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
},
},
returns => {
type => 'array',
items => {
type => "object",
properties => {},
},
links => [ { rel => 'child', href => "{name}" } ],
},
code => sub {
my ($param) = @_;
return [
{ name => 'acme' },
{ name => 'custom' },
{ name => 'info' },
];
},
});
__PACKAGE__->register_method ({
name => 'info',
path => 'info',
method => 'GET',
permissions => { user => 'all' },
proxyto => 'node',
description => "Get information about node's certificates.",
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
},
},
returns => {
type => 'array',
items => get_standard_option('pve-certificate-info'),
},
code => sub {
my ($param) = @_;
my $node_path = "/etc/pve/nodes/$param->{node}";
my $res = [];
my $cert_paths = [
'/etc/pve/pve-root-ca.pem',
"$node_path/pve-ssl.pem",
"$node_path/pveproxy-ssl.pem",
];
for my $path (@$cert_paths) {
eval {
my $info = PVE::Certificate::get_certificate_info($path);
push @$res, $info if $info;
};
}
return $res;
},
});
__PACKAGE__->register_method ({
name => 'upload_custom_cert',
path => 'custom',
method => 'POST',
permissions => {
check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
},
description => 'Upload or update custom certificate chain and key.',
protected => 1,
proxyto => 'node',
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
certificates => {
type => 'string',
format => 'pem-certificate-chain',
description => 'PEM encoded certificate (chain).',
},
key => {
type => 'string',
description => 'PEM encoded private key.',
format => 'pem-string',
optional => 1,
},
force => {
type => 'boolean',
description => 'Overwrite existing custom or ACME certificate files.',
optional => 1,
default => 0,
},
restart => {
type => 'boolean',
description => 'Restart pveproxy.',
optional => 1,
default => 0,
},
},
},
returns => get_standard_option('pve-certificate-info'),
code => sub {
my ($param) = @_;
my $node = extract_param($param, 'node');
my $cert_prefix = PVE::CertHelpers::cert_path_prefix($node);
my $certs = extract_param($param, 'certificates');
$certs = PVE::Certificate::strip_leading_text($certs);
my $key = extract_param($param, 'key');
if ($key) {
$key = PVE::Certificate::strip_leading_text($key);
} else {
raise_param_exc({'key' => "Attempted to upload custom certificate without (existing) key."})
if ! -e "${cert_prefix}.key";
}
my $info;
my $code = sub {
print "Setting custom certificate files\n";
$info = PVE::CertHelpers::set_cert_files($certs, $key, $cert_prefix, $param->{force});
if ($param->{restart}) {
print "Restarting pveproxy\n";
PVE::Tools::run_command(['systemctl', 'reload-or-restart', 'pveproxy']);
}
};
PVE::CertHelpers::cert_lock(10, $code);
die "$@\n" if $@;
return $info;
}});
__PACKAGE__->register_method ({
name => 'remove_custom_cert',
path => 'custom',
method => 'DELETE',
permissions => {
check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
},
description => 'DELETE custom certificate chain and key.',
protected => 1,
proxyto => 'node',
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
restart => {
type => 'boolean',
description => 'Restart pveproxy.',
optional => 1,
default => 0,
},
},
},
returns => {
type => 'null',
},
code => sub {
my ($param) = @_;
my $node = extract_param($param, 'node');
my $cert_prefix = PVE::CertHelpers::cert_path_prefix($node);
my $code = sub {
print "Deleting custom certificate files\n";
unlink "${cert_prefix}.pem";
unlink "${cert_prefix}.key";
if ($param->{restart}) {
print "Restarting pveproxy\n";
PVE::Tools::run_command(['systemctl', 'reload-or-restart', 'pveproxy']);
}
};
PVE::CertHelpers::cert_lock(10, $code);
die "$@\n" if $@;
return undef;
}});
1;