]> git.proxmox.com Git - pve-access-control.git/commitdiff
fix module namespace of realm sync API
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 7 Jun 2023 07:37:46 +0000 (09:37 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 7 Jun 2023 07:37:47 +0000 (09:37 +0200)
it isn't mounted in PVE::API2::AccessControl and it doesn't lives
anywhere in /access, so using that is just confusing.

Both, API and backend could simply move to manager, but as we already
got an api package here and it does somewhat fits into the topic lets
keep it here for now.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
src/PVE/API2/AccessControl/Makefile [deleted file]
src/PVE/API2/AccessControl/RealmSync.pm [deleted file]
src/PVE/API2/Jobs/Makefile [new file with mode: 0644]
src/PVE/API2/Jobs/RealmSync.pm [new file with mode: 0644]
src/PVE/API2/Makefile

diff --git a/src/PVE/API2/AccessControl/Makefile b/src/PVE/API2/AccessControl/Makefile
deleted file mode 100644 (file)
index 8f9d749..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-API2_SOURCES=  \
-       RealmSync.pm    \
-
-.PHONY: install
-install:
-       for i in ${API2_SOURCES}; do install -D -m 0644 $$i ${DESTDIR}${PERLDIR}/PVE/API2/AccessControl/$$i; done
diff --git a/src/PVE/API2/AccessControl/RealmSync.pm b/src/PVE/API2/AccessControl/RealmSync.pm
deleted file mode 100644 (file)
index e5af8b3..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-package PVE::API2::AccessControl::RealmSync;
-
-use strict;
-use warnings;
-
-
-use PVE::Cluster qw(cfs_lock_file cfs_read_file cfs_write_file);
-use PVE::Exception qw(raise_param_exc);
-use PVE::JSONSchema qw(get_standard_option);
-use PVE::Job::Registry ();
-use PVE::SectionConfig ();
-use PVE::Tools qw(extract_param);
-
-use PVE::Jobs::RealmSync ();
-
-use base qw(PVE::RESTHandler);
-
-my $get_cluster_last_run = sub {
-    my ($jobid) = @_;
-
-    my $state = eval { PVE::Jobs::RealmSync::get_state($jobid) };
-    die "error on getting state for '$jobid': $@\n" if $@;
-
-    if (my $upid = $state->{upid}) {
-       if (my $decoded = PVE::Tools::upid_decode($upid)) {
-           return $decoded->{starttime};
-       }
-    } else {
-       return $state->{time};
-    }
-
-    return undef;
-};
-
-__PACKAGE__->register_method ({
-    name => 'syncjob_index',
-    path => '',
-    method => 'GET',
-    description => "List configured realm-sync-jobs.",
-    permissions => {
-       check => ['perm', '/', ['Sys.Audit']],
-    },
-    parameters => {
-       additionalProperties => 0,
-       properties => {},
-    },
-    returns => {
-       type => 'array',
-       items => {
-           type => "object",
-           properties => {
-               id => {
-                   description => "The ID of the entry.",
-                   type => 'string'
-               },
-               enabled => {
-                   description => "If the job is enabled or not.",
-                   type => 'boolean',
-               },
-               comment => {
-                   description => "A comment for the job.",
-                   type => 'string',
-                   optional => 1,
-               },
-               schedule => {
-                   description => "The configured sync schedule.",
-                   type => 'string',
-               },
-               realm => get_standard_option('realm'),
-               scope => get_standard_option('sync-scope'),
-               'remove-vanished' => get_standard_option('sync-remove-vanished'),
-               'last-run' => {
-                   description => "Last execution time of the job in seconds since the beginning of the UNIX epoch",
-                   type => 'integer',
-                   optional => 1,
-               },
-               'next-run' => {
-                   description => "Next planned execution time of the job in seconds since the beginning of the UNIX epoch.",
-                   type => 'integer',
-                   optional => 1,
-               },
-           },
-       },
-       links => [ { rel => 'child', href => "{id}" } ],
-    },
-    code => sub {
-       my ($param) = @_;
-
-       my $rpcenv = PVE::RPCEnvironment::get();
-       my $user = $rpcenv->get_user();
-
-       my $jobs_data = cfs_read_file('jobs.cfg');
-       my $order = $jobs_data->{order};
-       my $jobs = $jobs_data->{ids};
-
-       my $res = [];
-       for my $jobid (sort { $order->{$a} <=> $order->{$b} } keys %$jobs) {
-           my $job = $jobs->{$jobid};
-           next if $job->{type} ne 'realm-sync';
-
-           $job->{id} = $jobid;
-           if (my $schedule = $job->{schedule}) {
-               $job->{'last-run'} = eval { $get_cluster_last_run->($jobid) };
-               my $last_run = $job->{'last-run'} // time(); # current time as fallback
-
-               my $calendar_event = Proxmox::RS::CalendarEvent->new($schedule);
-               my $next_run = $calendar_event->compute_next_event($last_run);
-               $job->{'next-run'} = $next_run if defined($next_run);
-           }
-
-           push @$res, $job;
-       }
-
-       return $res;
-    }});
-
-__PACKAGE__->register_method({
-    name => 'read_job',
-    path => '{id}',
-    method => 'GET',
-    description => "Read realm-sync job definition.",
-    permissions => {
-       check => ['perm', '/', ['Sys.Audit']],
-    },
-    parameters => {
-       additionalProperties => 0,
-       properties => {
-           id => {
-               type => 'string',
-               format => 'pve-configid',
-           },
-       },
-    },
-    returns => {
-       type => 'object',
-    },
-    code => sub {
-       my ($param) = @_;
-
-       my $jobs = cfs_read_file('jobs.cfg');
-       my $id = $param->{id};
-       my $job = $jobs->{ids}->{$id};
-       return $job if $job && $job->{type} eq 'realm-sync';
-
-       raise_param_exc({ id => "No such job '$id'" });
-
-    }});
-
-__PACKAGE__->register_method({
-    name => 'create_job',
-    path => '{id}',
-    method => 'POST',
-    protected => 1,
-    description => "Create new realm-sync job.",
-    permissions => {
-       description => "'Realm.AllocateUser' on '/access/realm/<realm>' and "
-           ."'User.Modify' permissions to '/access/groups/'.",
-       check => [ 'and',
-           ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
-           ['perm', '/access/groups', ['User.Modify']],
-       ],
-    },
-    parameters => PVE::Jobs::RealmSync->createSchema(),
-    returns => { type => 'null' },
-    code => sub {
-       my ($param) = @_;
-
-       my $id = extract_param($param, 'id');
-
-       cfs_lock_file('jobs.cfg', undef, sub {
-           my $data = cfs_read_file('jobs.cfg');
-
-           die "Job '$id' already exists\n"
-               if $data->{ids}->{$id};
-
-           my $plugin = PVE::Job::Registry->lookup('realm-sync');
-           my $opts = $plugin->check_config($id, $param, 1, 1);
-
-           my $realm = $opts->{realm};
-           my $cfg = cfs_read_file('domains.cfg');
-
-           raise_param_exc({ realm => "No such realm '$realm'" })
-               if !defined($cfg->{ids}->{$realm});
-
-           my $realm_type = $cfg->{ids}->{$realm}->{type};
-           raise_param_exc({ realm => "Only LDAP/AD realms can be synced." })
-               if $realm_type ne 'ldap' && $realm_type ne 'ad';
-
-           $data->{ids}->{$id} = $opts;
-
-           cfs_write_file('jobs.cfg', $data);
-       });
-       die "$@" if ($@);
-
-       return undef;
-    }});
-
-__PACKAGE__->register_method({
-    name => 'update_job',
-    path => '{id}',
-    method => 'PUT',
-    protected => 1,
-    description => "Update realm-sync job definition.",
-    permissions => {
-       description => "'Realm.AllocateUser' on '/access/realm/<realm>' and 'User.Modify'"
-           ." permissions to '/access/groups/'.",
-       check => [ 'and',
-           ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
-           ['perm', '/access/groups', ['User.Modify']],
-       ],
-    },
-    parameters => PVE::Jobs::RealmSync->updateSchema(),
-    returns => { type => 'null' },
-    code => sub {
-       my ($param) = @_;
-
-       my $id = extract_param($param, 'id');
-       my $delete = extract_param($param, 'delete');
-       $delete = [PVE::Tools::split_list($delete)] if $delete;
-
-       die "no job options specified\n" if !scalar(keys %$param);
-
-       cfs_lock_file('jobs.cfg', undef, sub {
-           my $jobs = cfs_read_file('jobs.cfg');
-
-           my $plugin = PVE::Job::Registry->lookup('realm-sync');
-           my $opts = $plugin->check_config($id, $param, 0, 1);
-
-           my $job = $jobs->{ids}->{$id};
-           die "no such realm-sync job\n" if !$job || $job->{type} ne 'realm-sync';
-
-           my $options = $plugin->options();
-           PVE::SectionConfig::delete_from_config($job, $options, $opts, $delete);
-
-           $job->{$_} = $param->{$_} for keys $param->%*;
-
-           cfs_write_file('jobs.cfg', $jobs);
-
-           return;
-       });
-       die "$@" if ($@);
-    }});
-
-
-__PACKAGE__->register_method({
-    name => 'delete_job',
-    path => '{id}',
-    method => 'DELETE',
-    description => "Delete realm-sync job definition.",
-    permissions => {
-       check => ['perm', '/', ['Sys.Modify']],
-    },
-    protected => 1,
-    parameters => {
-       additionalProperties => 0,
-       properties => {
-           id => {
-               type => 'string',
-               format => 'pve-configid',
-           },
-       },
-    },
-    returns => { type => 'null' },
-    code => sub {
-       my ($param) = @_;
-
-       my $id = $param->{id};
-
-       cfs_lock_file('jobs.cfg', undef, sub {
-           my $jobs = cfs_read_file('jobs.cfg');
-
-           if (!defined($jobs->{ids}->{$id}) || $jobs->{ids}->{$id}->{type} ne 'realm-sync') {
-               raise_param_exc({ id => "No such job '$id'" });
-           }
-           delete $jobs->{ids}->{$id};
-
-           cfs_write_file('jobs.cfg', $jobs);
-           PVE::Jobs::RealmSync::save_state($id, undef);
-       });
-       die "$@" if $@;
-
-       return undef;
-    }});
-
-1;
diff --git a/src/PVE/API2/Jobs/Makefile b/src/PVE/API2/Jobs/Makefile
new file mode 100644 (file)
index 0000000..fd79607
--- /dev/null
@@ -0,0 +1,6 @@
+SOURCES = \
+       RealmSync.pm \
+
+.PHONY: install
+install:
+       for i in $(SOURCES); do install -D -m 0644 $$i $(DESTDIR)$(PERLDIR)/PVE/API2/Jobs/$$i; done
diff --git a/src/PVE/API2/Jobs/RealmSync.pm b/src/PVE/API2/Jobs/RealmSync.pm
new file mode 100644 (file)
index 0000000..111ffc3
--- /dev/null
@@ -0,0 +1,284 @@
+package PVE::API2::Jobs::RealmSync;
+
+use strict;
+use warnings;
+
+use PVE::Cluster qw(cfs_lock_file cfs_read_file cfs_write_file);
+use PVE::Exception qw(raise_param_exc);
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::Job::Registry ();
+use PVE::SectionConfig ();
+use PVE::Tools qw(extract_param);
+
+use PVE::Jobs::RealmSync ();
+
+use base qw(PVE::RESTHandler);
+
+my $get_cluster_last_run = sub {
+    my ($jobid) = @_;
+
+    my $state = eval { PVE::Jobs::RealmSync::get_state($jobid) };
+    die "error on getting state for '$jobid': $@\n" if $@;
+
+    if (my $upid = $state->{upid}) {
+       if (my $decoded = PVE::Tools::upid_decode($upid)) {
+           return $decoded->{starttime};
+       }
+    } else {
+       return $state->{time};
+    }
+
+    return undef;
+};
+
+__PACKAGE__->register_method ({
+    name => 'syncjob_index',
+    path => '',
+    method => 'GET',
+    description => "List configured realm-sync-jobs.",
+    permissions => {
+       check => ['perm', '/', ['Sys.Audit']],
+    },
+    parameters => {
+       additionalProperties => 0,
+       properties => {},
+    },
+    returns => {
+       type => 'array',
+       items => {
+           type => "object",
+           properties => {
+               id => {
+                   description => "The ID of the entry.",
+                   type => 'string'
+               },
+               enabled => {
+                   description => "If the job is enabled or not.",
+                   type => 'boolean',
+               },
+               comment => {
+                   description => "A comment for the job.",
+                   type => 'string',
+                   optional => 1,
+               },
+               schedule => {
+                   description => "The configured sync schedule.",
+                   type => 'string',
+               },
+               realm => get_standard_option('realm'),
+               scope => get_standard_option('sync-scope'),
+               'remove-vanished' => get_standard_option('sync-remove-vanished'),
+               'last-run' => {
+                   description => "Last execution time of the job in seconds since the beginning of the UNIX epoch",
+                   type => 'integer',
+                   optional => 1,
+               },
+               'next-run' => {
+                   description => "Next planned execution time of the job in seconds since the beginning of the UNIX epoch.",
+                   type => 'integer',
+                   optional => 1,
+               },
+           },
+       },
+       links => [ { rel => 'child', href => "{id}" } ],
+    },
+    code => sub {
+       my ($param) = @_;
+
+       my $rpcenv = PVE::RPCEnvironment::get();
+       my $user = $rpcenv->get_user();
+
+       my $jobs_data = cfs_read_file('jobs.cfg');
+       my $order = $jobs_data->{order};
+       my $jobs = $jobs_data->{ids};
+
+       my $res = [];
+       for my $jobid (sort { $order->{$a} <=> $order->{$b} } keys %$jobs) {
+           my $job = $jobs->{$jobid};
+           next if $job->{type} ne 'realm-sync';
+
+           $job->{id} = $jobid;
+           if (my $schedule = $job->{schedule}) {
+               $job->{'last-run'} = eval { $get_cluster_last_run->($jobid) };
+               my $last_run = $job->{'last-run'} // time(); # current time as fallback
+
+               my $calendar_event = Proxmox::RS::CalendarEvent->new($schedule);
+               my $next_run = $calendar_event->compute_next_event($last_run);
+               $job->{'next-run'} = $next_run if defined($next_run);
+           }
+
+           push @$res, $job;
+       }
+
+       return $res;
+    }});
+
+__PACKAGE__->register_method({
+    name => 'read_job',
+    path => '{id}',
+    method => 'GET',
+    description => "Read realm-sync job definition.",
+    permissions => {
+       check => ['perm', '/', ['Sys.Audit']],
+    },
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           id => {
+               type => 'string',
+               format => 'pve-configid',
+           },
+       },
+    },
+    returns => {
+       type => 'object',
+    },
+    code => sub {
+       my ($param) = @_;
+
+       my $jobs = cfs_read_file('jobs.cfg');
+       my $id = $param->{id};
+       my $job = $jobs->{ids}->{$id};
+       return $job if $job && $job->{type} eq 'realm-sync';
+
+       raise_param_exc({ id => "No such job '$id'" });
+
+    }});
+
+__PACKAGE__->register_method({
+    name => 'create_job',
+    path => '{id}',
+    method => 'POST',
+    protected => 1,
+    description => "Create new realm-sync job.",
+    permissions => {
+       description => "'Realm.AllocateUser' on '/access/realm/<realm>' and "
+           ."'User.Modify' permissions to '/access/groups/'.",
+       check => [ 'and',
+           ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
+           ['perm', '/access/groups', ['User.Modify']],
+       ],
+    },
+    parameters => PVE::Jobs::RealmSync->createSchema(),
+    returns => { type => 'null' },
+    code => sub {
+       my ($param) = @_;
+
+       my $id = extract_param($param, 'id');
+
+       cfs_lock_file('jobs.cfg', undef, sub {
+           my $data = cfs_read_file('jobs.cfg');
+
+           die "Job '$id' already exists\n"
+               if $data->{ids}->{$id};
+
+           my $plugin = PVE::Job::Registry->lookup('realm-sync');
+           my $opts = $plugin->check_config($id, $param, 1, 1);
+
+           my $realm = $opts->{realm};
+           my $cfg = cfs_read_file('domains.cfg');
+
+           raise_param_exc({ realm => "No such realm '$realm'" })
+               if !defined($cfg->{ids}->{$realm});
+
+           my $realm_type = $cfg->{ids}->{$realm}->{type};
+           raise_param_exc({ realm => "Only LDAP/AD realms can be synced." })
+               if $realm_type ne 'ldap' && $realm_type ne 'ad';
+
+           $data->{ids}->{$id} = $opts;
+
+           cfs_write_file('jobs.cfg', $data);
+       });
+       die "$@" if ($@);
+
+       return undef;
+    }});
+
+__PACKAGE__->register_method({
+    name => 'update_job',
+    path => '{id}',
+    method => 'PUT',
+    protected => 1,
+    description => "Update realm-sync job definition.",
+    permissions => {
+       description => "'Realm.AllocateUser' on '/access/realm/<realm>' and 'User.Modify'"
+           ." permissions to '/access/groups/'.",
+       check => [ 'and',
+           ['perm', '/access/realm/{realm}', ['Realm.AllocateUser']],
+           ['perm', '/access/groups', ['User.Modify']],
+       ],
+    },
+    parameters => PVE::Jobs::RealmSync->updateSchema(),
+    returns => { type => 'null' },
+    code => sub {
+       my ($param) = @_;
+
+       my $id = extract_param($param, 'id');
+       my $delete = extract_param($param, 'delete');
+       $delete = [PVE::Tools::split_list($delete)] if $delete;
+
+       die "no job options specified\n" if !scalar(keys %$param);
+
+       cfs_lock_file('jobs.cfg', undef, sub {
+           my $jobs = cfs_read_file('jobs.cfg');
+
+           my $plugin = PVE::Job::Registry->lookup('realm-sync');
+           my $opts = $plugin->check_config($id, $param, 0, 1);
+
+           my $job = $jobs->{ids}->{$id};
+           die "no such realm-sync job\n" if !$job || $job->{type} ne 'realm-sync';
+
+           my $options = $plugin->options();
+           PVE::SectionConfig::delete_from_config($job, $options, $opts, $delete);
+
+           $job->{$_} = $param->{$_} for keys $param->%*;
+
+           cfs_write_file('jobs.cfg', $jobs);
+
+           return;
+       });
+       die "$@" if ($@);
+    }});
+
+
+__PACKAGE__->register_method({
+    name => 'delete_job',
+    path => '{id}',
+    method => 'DELETE',
+    description => "Delete realm-sync job definition.",
+    permissions => {
+       check => ['perm', '/', ['Sys.Modify']],
+    },
+    protected => 1,
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           id => {
+               type => 'string',
+               format => 'pve-configid',
+           },
+       },
+    },
+    returns => { type => 'null' },
+    code => sub {
+       my ($param) = @_;
+
+       my $id = $param->{id};
+
+       cfs_lock_file('jobs.cfg', undef, sub {
+           my $jobs = cfs_read_file('jobs.cfg');
+
+           if (!defined($jobs->{ids}->{$id}) || $jobs->{ids}->{$id}->{type} ne 'realm-sync') {
+               raise_param_exc({ id => "No such job '$id'" });
+           }
+           delete $jobs->{ids}->{$id};
+
+           cfs_write_file('jobs.cfg', $jobs);
+           PVE::Jobs::RealmSync::save_state($id, undef);
+       });
+       die "$@" if $@;
+
+       return undef;
+    }});
+
+1;
index e430d5ef1a506f4b52ddcec5009cda456700703f..c3690198f146cbad2633e6a6c845a1bd5f35b748 100644 (file)
@@ -10,7 +10,7 @@ API2_SOURCES=                         \
        TFA.pm                  \
        OpenId.pm
 
-SUBDIRS=AccessControl
+SUBDIRS = Jobs
 
 .PHONY: install
 install: