]>
Commit | Line | Data |
---|---|---|
036475f8 FG |
1 | package PVE::API2::Certificates; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use PVE::API2::ACME; | |
7 | use PVE::Certificate; | |
8 | use PVE::CertHelpers;; | |
9 | use PVE::Exception qw(raise_param_exc); | |
10 | use PVE::JSONSchema qw(get_standard_option); | |
11 | use PVE::Tools qw(extract_param file_get_contents file_set_contents); | |
12 | ||
13 | use base qw(PVE::RESTHandler); | |
14 | ||
15 | ||
16 | __PACKAGE__->register_method ({ | |
17 | subclass => "PVE::API2::ACME", | |
18 | path => 'acme', | |
19 | }); | |
20 | ||
21 | __PACKAGE__->register_method ({ | |
22 | name => 'index', | |
23 | path => '', | |
24 | method => 'GET', | |
25 | permissions => { user => 'all' }, | |
26 | description => "Node index.", | |
27 | parameters => { | |
28 | additionalProperties => 0, | |
29 | properties => { | |
30 | node => get_standard_option('pve-node'), | |
31 | }, | |
32 | }, | |
33 | returns => { | |
34 | type => 'array', | |
35 | items => { | |
36 | type => "object", | |
37 | properties => {}, | |
38 | }, | |
39 | links => [ { rel => 'child', href => "{name}" } ], | |
40 | }, | |
41 | code => sub { | |
42 | my ($param) = @_; | |
43 | ||
44 | return [ | |
45 | { name => 'acme' }, | |
46 | { name => 'custom' }, | |
47 | { name => 'info' }, | |
48 | ]; | |
49 | }, | |
50 | }); | |
51 | ||
52 | __PACKAGE__->register_method ({ | |
53 | name => 'info', | |
54 | path => 'info', | |
55 | method => 'GET', | |
56 | permissions => { user => 'all' }, | |
57 | proxyto => 'node', | |
58 | description => "Get information about node's certificates.", | |
59 | parameters => { | |
60 | additionalProperties => 0, | |
61 | properties => { | |
62 | node => get_standard_option('pve-node'), | |
63 | }, | |
64 | }, | |
65 | returns => { | |
66 | type => 'array', | |
67 | items => get_standard_option('pve-certificate-info'), | |
68 | }, | |
69 | code => sub { | |
70 | my ($param) = @_; | |
71 | ||
72 | my $node_path = "/etc/pve/nodes/$param->{node}"; | |
73 | ||
74 | my $res = []; | |
75 | my $cert_paths = [ | |
76 | '/etc/pve/pve-root-ca.pem', | |
77 | "$node_path/pve-ssl.pem", | |
78 | "$node_path/pveproxy-ssl.pem", | |
79 | ]; | |
80 | for my $path (@$cert_paths) { | |
81 | eval { | |
82 | my $info = PVE::Certificate::get_certificate_info($path); | |
83 | push @$res, $info if $info; | |
84 | }; | |
85 | } | |
86 | return $res; | |
87 | }, | |
88 | }); | |
89 | ||
90 | __PACKAGE__->register_method ({ | |
91 | name => 'upload_custom_cert', | |
92 | path => 'custom', | |
93 | method => 'POST', | |
63ad2164 FG |
94 | permissions => { |
95 | check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]], | |
96 | }, | |
036475f8 FG |
97 | description => 'Upload or update custom certificate chain and key.', |
98 | protected => 1, | |
99 | proxyto => 'node', | |
100 | parameters => { | |
101 | additionalProperties => 0, | |
102 | properties => { | |
103 | node => get_standard_option('pve-node'), | |
104 | certificates => { | |
105 | type => 'string', | |
106 | format => 'pem-certificate-chain', | |
107 | description => 'PEM encoded certificate (chain).', | |
108 | }, | |
109 | key => { | |
110 | type => 'string', | |
111 | description => 'PEM encoded private key.', | |
112 | format => 'pem-string', | |
113 | optional => 1, | |
114 | }, | |
115 | force => { | |
116 | type => 'boolean', | |
117 | description => 'Overwrite existing custom or ACME certificate files.', | |
118 | optional => 1, | |
119 | default => 0, | |
120 | }, | |
121 | restart => { | |
122 | type => 'boolean', | |
123 | description => 'Restart pveproxy.', | |
124 | optional => 1, | |
125 | default => 0, | |
126 | }, | |
127 | }, | |
128 | }, | |
129 | returns => get_standard_option('pve-certificate-info'), | |
130 | code => sub { | |
131 | my ($param) = @_; | |
132 | ||
133 | my $node = extract_param($param, 'node'); | |
134 | my $cert_prefix = PVE::CertHelpers::cert_path_prefix($node); | |
135 | ||
136 | my $certs = extract_param($param, 'certificates'); | |
137 | $certs = PVE::Certificate::strip_leading_text($certs); | |
138 | ||
139 | my $key = extract_param($param, 'key'); | |
140 | if ($key) { | |
141 | $key = PVE::Certificate::strip_leading_text($key); | |
142 | } else { | |
143 | raise_param_exc({'key' => "Attempted to upload custom certificate without (existing) key."}) | |
144 | if ! -e "${cert_prefix}.key"; | |
145 | } | |
146 | ||
147 | my $info; | |
148 | ||
149 | my $code = sub { | |
150 | print "Setting custom certificate files\n"; | |
151 | $info = PVE::CertHelpers::set_cert_files($certs, $key, $cert_prefix, $param->{force}); | |
152 | ||
153 | if ($param->{restart}) { | |
154 | print "Restarting pveproxy\n"; | |
155 | PVE::Tools::run_command(['systemctl', 'reload-or-restart', 'pveproxy']); | |
156 | } | |
157 | }; | |
158 | ||
159 | PVE::CertHelpers::cert_lock(10, $code); | |
160 | die "$@\n" if $@; | |
161 | ||
162 | return $info; | |
163 | }}); | |
164 | ||
165 | __PACKAGE__->register_method ({ | |
166 | name => 'remove_custom_cert', | |
167 | path => 'custom', | |
168 | method => 'DELETE', | |
63ad2164 FG |
169 | permissions => { |
170 | check => ['perm', '/nodes/{node}', [ 'Sys.Modify' ]], | |
171 | }, | |
036475f8 FG |
172 | description => 'DELETE custom certificate chain and key.', |
173 | protected => 1, | |
174 | proxyto => 'node', | |
175 | parameters => { | |
176 | additionalProperties => 0, | |
177 | properties => { | |
178 | node => get_standard_option('pve-node'), | |
179 | restart => { | |
180 | type => 'boolean', | |
181 | description => 'Restart pveproxy.', | |
182 | optional => 1, | |
183 | default => 0, | |
184 | }, | |
185 | }, | |
186 | }, | |
187 | returns => { | |
188 | type => 'null', | |
189 | }, | |
190 | code => sub { | |
191 | my ($param) = @_; | |
192 | ||
193 | my $node = extract_param($param, 'node'); | |
194 | my $cert_prefix = PVE::CertHelpers::cert_path_prefix($node); | |
195 | ||
196 | my $code = sub { | |
197 | print "Deleting custom certificate files\n"; | |
198 | unlink "${cert_prefix}.pem"; | |
199 | unlink "${cert_prefix}.key"; | |
200 | ||
201 | if ($param->{restart}) { | |
202 | print "Restarting pveproxy\n"; | |
203 | PVE::Tools::run_command(['systemctl', 'reload-or-restart', 'pveproxy']); | |
204 | } | |
205 | }; | |
206 | ||
207 | PVE::CertHelpers::cert_lock(10, $code); | |
208 | die "$@\n" if $@; | |
209 | ||
210 | return undef; | |
211 | }}); | |
212 | ||
213 | 1; |