mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-04-30 19:09:51 +00:00
add certificates API endpoints
to allow retrieval of certificate information, and uploading or removing of custom certificate files. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
parent
9945a5018e
commit
036475f89a
207
PVE/API2/Certificates.pm
Normal file
207
PVE/API2/Certificates.pm
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
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',
|
||||||
|
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',
|
||||||
|
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;
|
@ -14,6 +14,7 @@ PERLSOURCE = \
|
|||||||
Pool.pm \
|
Pool.pm \
|
||||||
Tasks.pm \
|
Tasks.pm \
|
||||||
Network.pm \
|
Network.pm \
|
||||||
|
Certificates.pm \
|
||||||
ACME.pm \
|
ACME.pm \
|
||||||
ACMEAccount.pm \
|
ACMEAccount.pm \
|
||||||
NodeConfig.pm \
|
NodeConfig.pm \
|
||||||
|
@ -41,6 +41,7 @@ use PVE::API2::APT;
|
|||||||
use PVE::API2::Ceph;
|
use PVE::API2::Ceph;
|
||||||
use PVE::API2::Firewall::Host;
|
use PVE::API2::Firewall::Host;
|
||||||
use PVE::API2::Replication;
|
use PVE::API2::Replication;
|
||||||
|
use PVE::API2::Certificates;
|
||||||
use PVE::API2::NodeConfig;
|
use PVE::API2::NodeConfig;
|
||||||
use Digest::MD5;
|
use Digest::MD5;
|
||||||
use Digest::SHA;
|
use Digest::SHA;
|
||||||
@ -119,6 +120,12 @@ __PACKAGE__->register_method ({
|
|||||||
path => 'replication',
|
path => 'replication',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
__PACKAGE__->register_method ({
|
||||||
|
subclass => "PVE::API2::Certificates",
|
||||||
|
path => 'certificates',
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
__PACKAGE__->register_method ({
|
__PACKAGE__->register_method ({
|
||||||
subclass => "PVE::API2::NodeConfig",
|
subclass => "PVE::API2::NodeConfig",
|
||||||
path => 'config',
|
path => 'config',
|
||||||
@ -177,6 +184,7 @@ __PACKAGE__->register_method ({
|
|||||||
{ name => 'stopall' },
|
{ name => 'stopall' },
|
||||||
{ name => 'netstat' },
|
{ name => 'netstat' },
|
||||||
{ name => 'firewall' },
|
{ name => 'firewall' },
|
||||||
|
{ name => 'certificates' },
|
||||||
{ name => 'config' },
|
{ name => 'config' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user