[pve-devel] [RFC manager 5/5] add certificates API endpoints
Dominik Csapak
d.csapak at proxmox.com
Tue Apr 17 16:27:21 CEST 2018
comments inline
On 04/11/2018 10:08 AM, Fabian Grünbichler wrote:
> to allow retrieval of certificate information, and uploading or removing
> of custom certificate files.
>
> Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
> ---
> PVE/API2/Makefile | 1 +
> PVE/API2/Certificates.pm | 202 +++++++++++++++++++++++++++++++++++++++++++++++
> PVE/API2/Nodes.pm | 8 ++
> 3 files changed, 211 insertions(+)
> create mode 100644 PVE/API2/Certificates.pm
>
> diff --git a/PVE/API2/Makefile b/PVE/API2/Makefile
> index 44b9cf7c..9862e498 100644
> --- a/PVE/API2/Makefile
> +++ b/PVE/API2/Makefile
> @@ -14,6 +14,7 @@ PERLSOURCE = \
> Pool.pm \
> Tasks.pm \
> Network.pm \
> + Certificates.pm \
> ACME.pm \
> ACMEAccount.pm \
> NodeConfig.pm \
> diff --git a/PVE/API2/Certificates.pm b/PVE/API2/Certificates.pm
> new file mode 100644
> index 00000000..6b66ea67
> --- /dev/null
> +++ b/PVE/API2/Certificates.pm
> @@ -0,0 +1,202 @@
> +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' },
> + description => "Get information about node's certificates.",
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + },
> + },
> + returns => {
> + type => 'object',
> + properties => {
> + clusterca => {
> + type => 'object',
> + },
> + custom => {
> + type => 'object',
> + optional => 1,
> + }
> + },
> + },
> + code => sub {
> + my ($param) = @_;
> +
> + my $node_path = "/etc/pve/nodes/$param->{node}";
> +
> + my $selfsigned_info = eval { PVE::Certificate::get_certificate_info("${node_path}/pve-ssl.pem")};
> + $selfsigned_info = { error => "$@" } if $@;
> + my $custom_info = eval { PVE::Certificate::get_certificate_info("${node_path}/pveproxy-ssl.pem")};
> + $custom_info = { error => "$@" } if $@;
> + return {
> + clusterca => $selfsigned_info,
> + custom => $custom_info,
> + };
> + },
> +});
> +
> +__PACKAGE__->register_method ({
> + name => 'upload_custom_cert',
> + path => 'custom',
> + method => 'POST',
> + description => 'Upload or update custom certificate chain and key.',
> + protected => 1,
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + certificates => {
> + type => 'string',
> + description => 'PEM encoded certificate (chain).',
> + },
> + key => {
> + type => 'string',
> + description => 'PEM encoded private key.',
> + 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 => {
> + type => 'object',
> + },
> + code => sub {
> + my ($param) = @_;
> +
> + my $certs = extract_param($param, 'certificates');
> + $certs = eval { PVE::Certificate::check_pem($certs, multiple => 1); };
> + raise_param_exc({ certificates => "Failed PEM format check - $@" }) if $@;
> +
> + my $key = extract_param($param, 'key');
> + $key = eval { PVE::Certificate::check_pem($key, label => qr/.*?/); };
> + raise_param_exc({ key => "Failed PEM format check - $@" }) if $@;
> +
> + my $node = extra_param($param, 'node');
should be extract_param
> + my $cert_prefix = PVE::CertHelpers::cert_path_prefix($node);
> +
> + my $info;
> +
> + my $code = sub {
> + print "Setting custom certificate files\n";
> + $info = PVE::CertHelper::set_cert_files($certs, $key, $cert_prefix, $param->{force});
should be CertHelpers
> +
> + 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,
> + parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + restart => {
> + type => 'boolean',
> + description => 'Restart pveproxy.',
> + optional => 1,
> + default => 0,
> + },
> + },
> + },
> + returns => {
> + type => 'object',
> + },
> + code => sub {
> + my ($param) = @_;
> +
> + my $node = extra_param($param, 'node');
extract_param
> + 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 $@;
> + }});
> +
> +1;
> diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm
> index 42b932cf..25f0e180 100644
> --- a/PVE/API2/Nodes.pm
> +++ b/PVE/API2/Nodes.pm
> @@ -41,6 +41,7 @@ use PVE::API2::APT;
> use PVE::API2::Ceph;
> use PVE::API2::Firewall::Host;
> use PVE::API2::Replication;
> +use PVE::API2::Certificates;
> use PVE::API2::NodeConfig;
> use Digest::MD5;
> use Digest::SHA;
> @@ -119,6 +120,12 @@ __PACKAGE__->register_method ({
> path => 'replication',
> });
>
> +__PACKAGE__->register_method ({
> + subclass => "PVE::API2::Certificates",
> + path => 'certificates',
> +});
> +
> +
> __PACKAGE__->register_method ({
> subclass => "PVE::API2::NodeConfig",
> path => 'config',
> @@ -177,6 +184,7 @@ __PACKAGE__->register_method ({
> { name => 'stopall' },
> { name => 'netstat' },
> { name => 'firewall' },
> + { name => 'certificates' },
> { name => 'config' },
> ];
>
>
More information about the pve-devel
mailing list