]> git.proxmox.com Git - pve-manager.git/blame - PVE/API2/Backup.pm
backup: factor out param permission check
[pve-manager.git] / PVE / API2 / Backup.pm
CommitLineData
ac27b58d
DM
1package PVE::API2::Backup;
2
3use strict;
4use warnings;
52878b0a 5use Digest::SHA;
ac27b58d
DM
6
7use PVE::SafeSyslog;
8use PVE::Tools qw(extract_param);
2424074e 9use PVE::Cluster qw(cfs_lock_file cfs_read_file cfs_write_file);
ac27b58d
DM
10use PVE::RESTHandler;
11use PVE::RPCEnvironment;
12use PVE::JSONSchema;
13use PVE::Storage;
14use PVE::Exception qw(raise_param_exc);
15use PVE::VZDump;
2424074e 16use PVE::VZDump::Common;
ac27b58d
DM
17
18use base qw(PVE::RESTHandler);
19
ac27b58d
DM
20PVE::JSONSchema::register_format('pve-day-of-week', \&verify_day_of_week);
21sub verify_day_of_week {
22 my ($value, $noerr) = @_;
23
24 return $value if $value =~ m/^(mon|tue|wed|thu|fri|sat|sun)$/;
25
26 return undef if $noerr;
27
28 die "invalid day '$value'\n";
29}
30
43b2494b
SR
31my $vzdump_job_id_prop = {
32 type => 'string',
33 description => "The job ID.",
34 maxLength => 50
35};
ac27b58d 36
2617768f
TL
37my $assert_param_permission = sub {
38 my ($param, $user) = @_;
39 return if $user eq 'root@pam'; # always OK
40
41 for my $key (qw(tmpdir dumpdir script)) {
42 raise_param_exc({ $key => "Only root may set this option."}) if exists $param->{$key};
43 }
44};
45
ac27b58d 46__PACKAGE__->register_method({
60e049c2
TM
47 name => 'index',
48 path => '',
ac27b58d
DM
49 method => 'GET',
50 description => "List vzdump backup schedule.",
937515d6
DM
51 permissions => {
52 check => ['perm', '/', ['Sys.Audit']],
53 },
ac27b58d
DM
54 parameters => {
55 additionalProperties => 0,
56 properties => {},
57 },
58 returns => {
59 type => 'array',
60 items => {
61 type => "object",
62 properties => {
43b2494b 63 id => $vzdump_job_id_prop
ac27b58d
DM
64 },
65 },
66 links => [ { rel => 'child', href => "{id}" } ],
67 },
68 code => sub {
69 my ($param) = @_;
70
71 my $rpcenv = PVE::RPCEnvironment::get();
72 my $user = $rpcenv->get_user();
73
b0905e3a 74 my $data = cfs_read_file('vzdump.cron');
ac27b58d
DM
75
76 my $res = $data->{jobs} || [];
77
78 return $res;
79 }});
80
81__PACKAGE__->register_method({
60e049c2
TM
82 name => 'create_job',
83 path => '',
ac27b58d
DM
84 method => 'POST',
85 protected => 1,
86 description => "Create new vzdump backup job.",
937515d6
DM
87 permissions => {
88 check => ['perm', '/', ['Sys.Modify']],
f0bbc084 89 description => "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root\@pam' user.",
937515d6 90 },
ac27b58d
DM
91 parameters => {
92 additionalProperties => 0,
2424074e 93 properties => PVE::VZDump::Common::json_config_properties({
7625ea19
DM
94 starttime => {
95 type => 'string',
96 description => "Job Start time.",
97 pattern => '\d{1,2}:\d{1,2}',
98 typetext => 'HH:MM',
ac27b58d
DM
99 },
100 dow => {
101 type => 'string', format => 'pve-day-of-week-list',
102 optional => 1,
103 description => "Day of week selection.",
104 default => 'mon,tue,wed,thu,fri,sat,sun',
105 },
4341db1d
TL
106 enabled => {
107 type => 'boolean',
108 optional => 1,
109 description => "Enable or disable the job.",
110 default => '1',
111 },
ac27b58d
DM
112 }),
113 },
114 returns => { type => 'null' },
115 code => sub {
116 my ($param) = @_;
117
118 my $rpcenv = PVE::RPCEnvironment::get();
119 my $user = $rpcenv->get_user();
120
2617768f 121 $assert_param_permission->($param, $user);
f0bbc084 122
c92c54d5
TL
123 if (my $pool = $param->{pool}) {
124 $rpcenv->check_pool_exist($pool);
125 $rpcenv->check($user, "/pool/$pool", ['VM.Backup']);
126 }
127
128
200cef80
CE
129 my $create_job = sub {
130 my $data = cfs_read_file('vzdump.cron');
ac27b58d 131
200cef80
CE
132 $param->{dow} = 'mon,tue,wed,thu,fri,sat,sun' if !defined($param->{dow});
133 $param->{enabled} = 1 if !defined($param->{enabled});
134 PVE::VZDump::verify_vzdump_parameters($param, 1);
ac27b58d 135
200cef80 136 push @{$data->{jobs}}, $param;
ac27b58d 137
200cef80
CE
138 cfs_write_file('vzdump.cron', $data);
139 };
140 cfs_lock_file('vzdump.cron', undef, $create_job);
141 die "$@" if ($@);
ac27b58d
DM
142
143 return undef;
144 }});
145
146__PACKAGE__->register_method({
60e049c2
TM
147 name => 'read_job',
148 path => '{id}',
ac27b58d
DM
149 method => 'GET',
150 description => "Read vzdump backup job definition.",
937515d6
DM
151 permissions => {
152 check => ['perm', '/', ['Sys.Audit']],
153 },
ac27b58d
DM
154 parameters => {
155 additionalProperties => 0,
156 properties => {
43b2494b 157 id => $vzdump_job_id_prop
ac27b58d
DM
158 },
159 },
160 returns => {
161 type => 'object',
162 },
163 code => sub {
164 my ($param) = @_;
165
166 my $rpcenv = PVE::RPCEnvironment::get();
167 my $user = $rpcenv->get_user();
168
b0905e3a 169 my $data = cfs_read_file('vzdump.cron');
ac27b58d
DM
170
171 my $jobs = $data->{jobs} || [];
172
173 foreach my $job (@$jobs) {
174 return $job if $job->{id} eq $param->{id};
175 }
176
177 raise_param_exc({ id => "No such job '$param->{id}'" });
178
179 }});
180
181__PACKAGE__->register_method({
60e049c2
TM
182 name => 'delete_job',
183 path => '{id}',
ac27b58d
DM
184 method => 'DELETE',
185 description => "Delete vzdump backup job definition.",
937515d6
DM
186 permissions => {
187 check => ['perm', '/', ['Sys.Modify']],
188 },
ac27b58d
DM
189 protected => 1,
190 parameters => {
191 additionalProperties => 0,
192 properties => {
43b2494b 193 id => $vzdump_job_id_prop
ac27b58d
DM
194 },
195 },
196 returns => { type => 'null' },
197 code => sub {
198 my ($param) = @_;
199
200 my $rpcenv = PVE::RPCEnvironment::get();
201 my $user = $rpcenv->get_user();
202
200cef80
CE
203 my $delete_job = sub {
204 my $data = cfs_read_file('vzdump.cron');
ac27b58d 205
200cef80
CE
206 my $jobs = $data->{jobs} || [];
207 my $newjobs = [];
ac27b58d 208
200cef80
CE
209 my $found;
210 foreach my $job (@$jobs) {
211 if ($job->{id} eq $param->{id}) {
212 $found = 1;
213 } else {
214 push @$newjobs, $job;
215 }
ac27b58d 216 }
ac27b58d 217
200cef80 218 raise_param_exc({ id => "No such job '$param->{id}'" }) if !$found;
ac27b58d 219
200cef80 220 $data->{jobs} = $newjobs;
ac27b58d 221
200cef80
CE
222 cfs_write_file('vzdump.cron', $data);
223 };
224 cfs_lock_file('vzdump.cron', undef, $delete_job);
225 die "$@" if ($@);
ac27b58d
DM
226
227 return undef;
228 }});
229
230__PACKAGE__->register_method({
60e049c2
TM
231 name => 'update_job',
232 path => '{id}',
ac27b58d
DM
233 method => 'PUT',
234 protected => 1,
235 description => "Update vzdump backup job definition.",
937515d6
DM
236 permissions => {
237 check => ['perm', '/', ['Sys.Modify']],
238 },
ac27b58d
DM
239 parameters => {
240 additionalProperties => 0,
2424074e 241 properties => PVE::VZDump::Common::json_config_properties({
43b2494b 242 id => $vzdump_job_id_prop,
7625ea19
DM
243 starttime => {
244 type => 'string',
245 description => "Job Start time.",
246 pattern => '\d{1,2}:\d{1,2}',
247 typetext => 'HH:MM',
ac27b58d
DM
248 },
249 dow => {
250 type => 'string', format => 'pve-day-of-week-list',
251 optional => 1,
252 description => "Day of week selection.",
253 },
53c6bb6c
DM
254 delete => {
255 type => 'string', format => 'pve-configid-list',
256 description => "A list of settings you want to delete.",
257 optional => 1,
258 },
4341db1d
TL
259 enabled => {
260 type => 'boolean',
261 optional => 1,
262 description => "Enable or disable the job.",
263 default => '1',
264 },
ac27b58d
DM
265 }),
266 },
267 returns => { type => 'null' },
268 code => sub {
269 my ($param) = @_;
270
271 my $rpcenv = PVE::RPCEnvironment::get();
272 my $user = $rpcenv->get_user();
273
2617768f 274 $assert_param_permission->($param, $user);
d5b9f2e1 275
16f5b283
TL
276 if (my $pool = $param->{pool}) {
277 $rpcenv->check_pool_exist($pool);
278 $rpcenv->check($user, "/pool/$pool", ['VM.Backup']);
279 }
280
200cef80
CE
281 my $update_job = sub {
282 my $data = cfs_read_file('vzdump.cron');
ac27b58d 283
200cef80 284 my $jobs = $data->{jobs} || [];
ac27b58d 285
200cef80 286 die "no options specified\n" if !scalar(keys %$param);
53c6bb6c 287
200cef80 288 PVE::VZDump::verify_vzdump_parameters($param);
ac27b58d 289
200cef80 290 my @delete = PVE::Tools::split_list(extract_param($param, 'delete'));
53c6bb6c 291
200cef80
CE
292 foreach my $job (@$jobs) {
293 if ($job->{id} eq $param->{id}) {
ac27b58d 294
200cef80
CE
295 foreach my $k (@delete) {
296 if (!PVE::VZDump::option_exists($k)) {
297 raise_param_exc({ delete => "unknown option '$k'" });
298 }
53c6bb6c 299
200cef80
CE
300 delete $job->{$k};
301 }
53c6bb6c 302
200cef80
CE
303 foreach my $k (keys %$param) {
304 $job->{$k} = $param->{$k};
305 }
ac27b58d 306
f3376261 307 $job->{all} = 1 if (defined($job->{exclude}) && !defined($job->{pool}));
ac27b58d 308
200cef80
CE
309 if (defined($param->{vmid})) {
310 delete $job->{all};
311 delete $job->{exclude};
f3376261 312 delete $job->{pool};
200cef80
CE
313 } elsif ($param->{all}) {
314 delete $job->{vmid};
f3376261
TM
315 delete $job->{pool};
316 } elsif ($job->{pool}) {
317 delete $job->{vmid};
318 delete $job->{all};
b05c9908 319 delete $job->{exclude};
200cef80 320 }
ac27b58d 321
200cef80 322 PVE::VZDump::verify_vzdump_parameters($job, 1);
ac27b58d 323
200cef80 324 cfs_write_file('vzdump.cron', $data);
ac27b58d 325
200cef80
CE
326 return undef;
327 }
ac27b58d 328 }
200cef80
CE
329 raise_param_exc({ id => "No such job '$param->{id}'" });
330 };
331 cfs_lock_file('vzdump.cron', undef, $update_job);
332 die "$@" if ($@);
ac27b58d
DM
333 }});
334
3351;