mirror of
				https://git.proxmox.com/git/pve-manager
				synced 2025-10-31 04:24:46 +00:00 
			
		
		
		
	 036475f89a
			
		
	
	
		036475f89a
		
	
	
	
	
		
			
			to allow retrieval of certificate information, and uploading or removing of custom certificate files. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
		
			
				
	
	
		
			208 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 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;
 |