]>
git.proxmox.com Git - pve-access-control.git/blob - src/PVE/API2/AccessControl/RealmSync.pm
f5334b8bdb68e51c8e55a7e072fbae06c3f2f994
1 package PVE
::API2
::AccessControl
::RealmSync
;
7 use PVE
::Cluster
qw(cfs_lock_file cfs_read_file cfs_write_file);
8 use PVE
::Exception
qw(raise_param_exc);
9 use PVE
::JSONSchema
qw(get_standard_option);
10 use PVE
::Job
::Registry
();
11 use PVE
::SectionConfig
();
12 use PVE
::Tools
qw(extract_param);
14 use PVE
::Jobs
::RealmSync
();
16 use base
qw(PVE::RESTHandler);
18 my $get_cluster_last_run = sub {
21 my $state = eval { PVE
::Jobs
::RealmSync
::get_state
($jobid) };
22 die "error on getting state for '$jobid': $@\n" if $@;
24 if (my $upid = $state->{upid
}) {
25 if (my $decoded = PVE
::Tools
::upid_decode
($upid)) {
26 return $decoded->{starttime
};
29 return $state->{time};
35 __PACKAGE__-
>register_method ({
36 name
=> 'syncjob_index',
39 description
=> "List configured realm-sync-jobs.",
41 check
=> ['perm', '/', ['Sys.Audit']],
44 additionalProperties
=> 0,
53 description
=> "The ID of the entry.",
57 description
=> "If the job is enabled or not.",
61 description
=> "A comment for the job.",
66 description
=> "The configured sync schedule.",
69 realm
=> get_standard_option
('realm'),
70 scope
=> get_standard_option
('sync-scope'),
71 'remove-vanished' => get_standard_option
('sync-remove-vanished'),
73 description
=> "Last execution time of the job in seconds since the beginning of the UNIX epoch",
78 description
=> "Next planned execution time of the job in seconds since the beginning of the UNIX epoch.",
84 links
=> [ { rel
=> 'child', href
=> "{id}" } ],
89 my $rpcenv = PVE
::RPCEnvironment
::get
();
90 my $user = $rpcenv->get_user();
92 my $jobs_data = cfs_read_file
('jobs.cfg');
93 my $order = $jobs_data->{order
};
94 my $jobs = $jobs_data->{ids
};
97 for my $jobid (sort { $order->{$a} <=> $order->{$b} } keys %$jobs) {
98 my $job = $jobs->{$jobid};
99 next if $job->{type
} ne 'realm-sync';
102 if (my $schedule = $job->{schedule
}) {
103 $job->{'last-run'} = eval { $get_cluster_last_run->($jobid) };
104 my $last_run = $job->{'last-run'} // time(); # current time as fallback
106 my $calendar_event = Proxmox
::RS
::CalendarEvent-
>new($schedule);
107 my $next_run = $calendar_event->compute_next_event($last_run);
108 $job->{'next-run'} = $next_run if defined($next_run);
117 __PACKAGE__-
>register_method({
121 description
=> "Read realm-sync job definition.",
123 check
=> ['perm', '/', ['Sys.Audit']],
126 additionalProperties
=> 0,
130 format
=> 'pve-configid',
140 my $jobs = cfs_read_file
('jobs.cfg');
141 my $id = $param->{id
};
142 my $job = $jobs->{ids
}->{$id};
143 return $job if $job && $job->{type
} eq 'realm-sync';
145 raise_param_exc
({ id
=> "No such job '$id'" });
149 __PACKAGE__-
>register_method({
150 name
=> 'create_job',
154 description
=> "Create new realm-sync job.",
156 description
=> "'Realm.AllocateUser' on '/access/realm/<realm>' and "
157 ."'User.Modify' permissions to '/access/groups/'.",
159 ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
160 ['perm', '/access/groups', ['User.Modify']],
163 parameters
=> PVE
::Jobs
::RealmSync-
>createSchema(),
164 returns
=> { type
=> 'null' },
168 my $id = extract_param
($param, 'id');
170 cfs_lock_file
('jobs.cfg', undef, sub {
171 my $data = cfs_read_file
('jobs.cfg');
173 die "Job '$id' already exists\n"
174 if $data->{ids
}->{$id};
176 my $plugin = PVE
::Job
::Registry-
>lookup('realm-sync');
177 my $opts = $plugin->check_config($id, $param, 1, 1);
179 my $realm = $opts->{realm
};
180 my $cfg = cfs_read_file
('domains.cfg');
182 raise_param_exc
({ realm
=> "No such realm '$realm'" })
183 if !defined($cfg->{ids
}->{$realm});
185 my $realm_type = $cfg->{ids
}->{$realm}->{type
};
186 raise_param_exc
({ realm
=> "Only LDAP/AD realms can be synced." })
187 if $realm_type ne 'ldap' && $realm_type ne 'ad';
189 $data->{ids
}->{$id} = $opts;
191 cfs_write_file
('jobs.cfg', $data);
198 __PACKAGE__-
>register_method({
199 name
=> 'update_job',
203 description
=> "Update realm-sync job definition.",
205 description
=> "'Realm.AllocateUser' on '/access/realm/<realm>' and 'User.Modify'"
206 ." permissions to '/access/groups/'.",
208 ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
209 ['perm', '/access/groups', ['User.Modify']],
212 parameters
=> PVE
::Jobs
::RealmSync-
>updateSchema(),
213 returns
=> { type
=> 'null' },
217 my $id = extract_param
($param, 'id');
218 my $delete = extract_param
($param, 'delete');
219 $delete = [PVE
::Tools
::split_list
($delete)] if $delete;
221 cfs_lock_file
('jobs.cfg', undef, sub {
222 my $jobs = cfs_read_file
('jobs.cfg');
224 die "no options specified\n" if !scalar(keys %$param);
226 my $plugin = PVE
::Job
::Registry-
>lookup('realm-sync');
227 my $opts = $plugin->check_config($id, $param, 0, 1);
229 my $job = $jobs->{ids
}->{$id};
230 die "no such realm-sync job\n" if !$job || $job->{type
} ne 'realm-sync';
232 my $options = $plugin->options();
233 PVE
::SectionConfig
::delete_from_config
($job, $options, $opts, $delete);
235 $job->{$_} = $param->{$_} for keys $param->%*;
237 cfs_write_file
('jobs.cfg', $jobs);
245 __PACKAGE__-
>register_method({
246 name
=> 'delete_job',
249 description
=> "Delete realm-sync job definition.",
251 check
=> ['perm', '/', ['Sys.Modify']],
255 additionalProperties
=> 0,
259 format
=> 'pve-configid',
263 returns
=> { type
=> 'null' },
267 my $id = $param->{id
};
269 cfs_lock_file
('jobs.cfg', undef, sub {
270 my $jobs = cfs_read_file
('jobs.cfg');
272 if (!defined($jobs->{ids
}->{$id}) || $jobs->{ids
}->{$id}->{type
} ne 'realm-sync') {
273 raise_param_exc
({ id
=> "No such job '$id'" });
275 delete $jobs->{ids
}->{$id};
277 cfs_write_file
('jobs.cfg', $jobs);
278 PVE
::Jobs
::RealmSync
::save_state
($id, undef);