]>
git.proxmox.com Git - pve-access-control.git/blob - src/PVE/API2/Jobs/RealmSync.pm
1 package PVE
::API2
::Jobs
::RealmSync
;
6 use PVE
::Cluster
qw(cfs_lock_file cfs_read_file cfs_write_file);
7 use PVE
::Exception
qw(raise_param_exc);
8 use PVE
::JSONSchema
qw(get_standard_option);
9 use PVE
::Job
::Registry
();
10 use PVE
::SectionConfig
();
11 use PVE
::Tools
qw(extract_param);
13 use PVE
::Jobs
::RealmSync
();
15 use base
qw(PVE::RESTHandler);
17 my $get_cluster_last_run = sub {
20 my $state = eval { PVE
::Jobs
::RealmSync
::get_state
($jobid) };
21 die "error on getting state for '$jobid': $@\n" if $@;
23 if (my $upid = $state->{upid
}) {
24 if (my $decoded = PVE
::Tools
::upid_decode
($upid)) {
25 return $decoded->{starttime
};
28 return $state->{time};
34 __PACKAGE__-
>register_method ({
35 name
=> 'syncjob_index',
38 description
=> "List configured realm-sync-jobs.",
40 check
=> ['perm', '/', ['Sys.Audit']],
43 additionalProperties
=> 0,
52 description
=> "The ID of the entry.",
56 description
=> "If the job is enabled or not.",
60 description
=> "A comment for the job.",
65 description
=> "The configured sync schedule.",
68 realm
=> get_standard_option
('realm'),
69 scope
=> get_standard_option
('sync-scope'),
70 'remove-vanished' => get_standard_option
('sync-remove-vanished'),
72 description
=> "Last execution time of the job in seconds since the beginning of the UNIX epoch",
77 description
=> "Next planned execution time of the job in seconds since the beginning of the UNIX epoch.",
83 links
=> [ { rel
=> 'child', href
=> "{id}" } ],
88 my $rpcenv = PVE
::RPCEnvironment
::get
();
89 my $user = $rpcenv->get_user();
91 my $jobs_data = cfs_read_file
('jobs.cfg');
92 my $order = $jobs_data->{order
};
93 my $jobs = $jobs_data->{ids
};
96 for my $jobid (sort { $order->{$a} <=> $order->{$b} } keys %$jobs) {
97 my $job = $jobs->{$jobid};
98 next if $job->{type
} ne 'realm-sync';
101 if (my $schedule = $job->{schedule
}) {
102 $job->{'last-run'} = eval { $get_cluster_last_run->($jobid) };
103 my $last_run = $job->{'last-run'} // time(); # current time as fallback
105 my $calendar_event = Proxmox
::RS
::CalendarEvent-
>new($schedule);
106 my $next_run = $calendar_event->compute_next_event($last_run);
107 $job->{'next-run'} = $next_run if defined($next_run);
116 __PACKAGE__-
>register_method({
120 description
=> "Read realm-sync job definition.",
122 check
=> ['perm', '/', ['Sys.Audit']],
125 additionalProperties
=> 0,
129 format
=> 'pve-configid',
139 my $jobs = cfs_read_file
('jobs.cfg');
140 my $id = $param->{id
};
141 my $job = $jobs->{ids
}->{$id};
142 return $job if $job && $job->{type
} eq 'realm-sync';
144 raise_param_exc
({ id
=> "No such job '$id'" });
148 __PACKAGE__-
>register_method({
149 name
=> 'create_job',
153 description
=> "Create new realm-sync job.",
155 description
=> "'Realm.AllocateUser' on '/access/realm/<realm>' and "
156 ."'User.Modify' permissions to '/access/groups/'.",
158 ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
159 ['perm', '/access/groups', ['User.Modify']],
162 parameters
=> PVE
::Jobs
::RealmSync-
>createSchema(),
163 returns
=> { type
=> 'null' },
167 my $id = extract_param
($param, 'id');
169 cfs_lock_file
('jobs.cfg', undef, sub {
170 my $data = cfs_read_file
('jobs.cfg');
172 die "Job '$id' already exists\n"
173 if $data->{ids
}->{$id};
175 my $plugin = PVE
::Job
::Registry-
>lookup('realm-sync');
176 my $opts = $plugin->check_config($id, $param, 1, 1);
178 my $realm = $opts->{realm
};
179 my $cfg = cfs_read_file
('domains.cfg');
181 raise_param_exc
({ realm
=> "No such realm '$realm'" })
182 if !defined($cfg->{ids
}->{$realm});
184 my $realm_type = $cfg->{ids
}->{$realm}->{type
};
185 raise_param_exc
({ realm
=> "Only LDAP/AD realms can be synced." })
186 if $realm_type ne 'ldap' && $realm_type ne 'ad';
188 $data->{ids
}->{$id} = $opts;
190 cfs_write_file
('jobs.cfg', $data);
197 __PACKAGE__-
>register_method({
198 name
=> 'update_job',
202 description
=> "Update realm-sync job definition.",
204 description
=> "'Realm.AllocateUser' on '/access/realm/<realm>' and 'User.Modify'"
205 ." permissions to '/access/groups/'.",
207 ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
208 ['perm', '/access/groups', ['User.Modify']],
211 parameters
=> PVE
::Jobs
::RealmSync-
>updateSchema(),
212 returns
=> { type
=> 'null' },
216 my $id = extract_param
($param, 'id');
217 my $delete = extract_param
($param, 'delete');
218 $delete = [PVE
::Tools
::split_list
($delete)] if $delete;
220 die "no job options specified\n" if !scalar(keys %$param);
222 cfs_lock_file
('jobs.cfg', undef, sub {
223 my $jobs = cfs_read_file
('jobs.cfg');
225 my $plugin = PVE
::Job
::Registry-
>lookup('realm-sync');
226 my $opts = $plugin->check_config($id, $param, 0, 1);
228 my $job = $jobs->{ids
}->{$id};
229 die "no such realm-sync job\n" if !$job || $job->{type
} ne 'realm-sync';
231 my $options = $plugin->options();
232 PVE
::SectionConfig
::delete_from_config
($job, $options, $opts, $delete);
234 $job->{$_} = $param->{$_} for keys $param->%*;
236 cfs_write_file
('jobs.cfg', $jobs);
244 __PACKAGE__-
>register_method({
245 name
=> 'delete_job',
248 description
=> "Delete realm-sync job definition.",
250 check
=> ['perm', '/', ['Sys.Modify']],
254 additionalProperties
=> 0,
258 format
=> 'pve-configid',
262 returns
=> { type
=> 'null' },
266 my $id = $param->{id
};
268 cfs_lock_file
('jobs.cfg', undef, sub {
269 my $jobs = cfs_read_file
('jobs.cfg');
271 if (!defined($jobs->{ids
}->{$id}) || $jobs->{ids
}->{$id}->{type
} ne 'realm-sync') {
272 raise_param_exc
({ id
=> "No such job '$id'" });
274 delete $jobs->{ids
}->{$id};
276 cfs_write_file
('jobs.cfg', $jobs);
277 PVE
::Jobs
::RealmSync
::save_state
($id, undef);