realm: add default-sync-options to config

This allows us to have a convenient way to set the desired default
sync options, and thus not forcing users to pass always all options
when they want to trigger a sync.

We still die when an option is neither specified in the domains
(realm) config nor as API/CLI parameter.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Thomas Lamprecht 2020-03-21 16:01:56 +01:00
parent 415179b03a
commit d29d2d4a11
3 changed files with 74 additions and 27 deletions

View File

@ -276,7 +276,7 @@ my $update_users = sub {
my $olduser = $oldusers->{$userid} // {};
if (defined(my $enabled = $olduser->{enable})) {
$user->{enable} = $enabled;
} elsif ($opts->{enable}) {
} elsif ($opts->{'enable-new'}) {
$user->{enable} = 1;
}
@ -340,6 +340,31 @@ my $update_groups = sub {
}
};
my $parse_sync_opts = sub {
my ($param, $realmconfig) = @_;
my $sync_opts_fmt = PVE::JSONSchema::get_format('realm-sync-options');
my $res = {};
if (defined(my $cfg_opts = $realmconfig->{'sync-defaults-options'})) {
$res = PVE::JSONSchema::parse_property_string($sync_opts_fmt, $cfg_opts);
}
for my $opt (sort keys %$sync_opts_fmt) {
my $fmt = $sync_opts_fmt->{$opt};
if (exists $param->{$opt}) {
$res->{$opt} = $param->{$opt};
} elsif (!exists $res->{$opt}) {
raise_param_exc({
"$opt" => 'Not passed as parameter and not defined in realm default sync options.'
}) if !$fmt->{optional};
$res->{$opt} = $fmt->{default} if exists $fmt->{default};
}
}
return $res;
};
__PACKAGE__->register_method ({
name => 'sync',
path => '{realm}/sync',
@ -358,28 +383,9 @@ __PACKAGE__->register_method ({
protected => 1,
parameters => {
additionalProperties => 0,
properties => {
realm => get_standard_option('realm'),
scope => {
description => "Select what to sync.",
type => 'string',
enum => [qw(users groups both)],
},
full => {
description => "If set, uses the LDAP Directory as source of truth, ".
"deleting all information not contained there. ".
"Otherwise only syncs information set explicitly.",
type => 'boolean',
},
enable => {
description => "Enable newly synced users.",
type => 'boolean',
},
purge => {
description => "Remove ACLs for users/groups that were removed from the config.",
type => 'boolean',
},
}
properties => get_standard_option('realm-sync-options', {
realm => get_standard_option('realm'),
})
},
returns => {
description => 'Worker Task-UPID',
@ -402,8 +408,9 @@ __PACKAGE__->register_method ({
die "Cannot sync realm type '$type'! Only LDAP/AD realms can be synced.\n";
}
my $opts = $parse_sync_opts->($param, $realmconfig); # can throw up
my $scope = $param->{scope};
my $scope = $opts->{scope};
my $whatstring = $scope eq 'both' ? "users and groups" : $scope;
my $plugin = PVE::Auth::Plugin->lookup($type);
@ -422,11 +429,11 @@ __PACKAGE__->register_method ({
print "got data from server, updating $whatstring\n";
if ($scope eq 'users' || $scope eq 'both') {
$update_users->($usercfg, $realm, $synced_users, $param);
$update_users->($usercfg, $realm, $synced_users, $opts);
}
if ($scope eq 'groups' || $scope eq 'both') {
$update_groups->($usercfg, $realm, $synced_groups, $param);
$update_groups->($usercfg, $realm, $synced_groups, $opts);
}
cfs_write_file("user.cfg", $usercfg);

View File

@ -3,9 +3,11 @@ package PVE::Auth::LDAP;
use strict;
use warnings;
use PVE::Tools;
use PVE::Auth::Plugin;
use PVE::JSONSchema;
use PVE::LDAP;
use PVE::Tools;
use base qw(PVE::Auth::Plugin);
sub type {
@ -109,6 +111,12 @@ sub properties {
format => 'ldap-simple-attr-list',
optional => 1,
},
'sync-defaults-options' => {
description => "The default options for behavior of synchronizations.",
type => 'string',
format => 'realm-sync-options',
optional => 1,
},
};
}
@ -136,6 +144,7 @@ sub options {
group_name_attr => { optional => 1 },
group_filter => { optional => 1 },
group_classes => { optional => 1 },
'sync-defaults-options' => { optional => 1 },
};
}

View File

@ -47,6 +47,37 @@ PVE::JSONSchema::register_standard_option('realm', {
maxLength => 32,
});
my $realm_sync_options_desc = {
scope => {
description => "Select what to sync.",
type => 'string',
enum => [qw(users groups both)],
optional => '1',
},
full => {
description => "If set, uses the LDAP Directory as source of truth,"
." deleting users or groups not returned from the sync. Otherwise"
." only syncs information which is not already present, and does not"
." deletes or modifies anything else.",
type => 'boolean',
optional => '1',
},
'enable-new' => {
description => "Enable newly synced users immediately.",
type => 'boolean',
default => '1',
optional => '1',
},
purge => {
description => "Remove ACLs for users or groups which were removed from"
." the config during a sync.",
type => 'boolean',
optional => '1',
},
};
PVE::JSONSchema::register_standard_option('realm-sync-options', $realm_sync_options_desc);
PVE::JSONSchema::register_format('realm-sync-options', $realm_sync_options_desc);
PVE::JSONSchema::register_format('pve-userid', \&verify_username);
sub verify_username {
my ($username, $noerr) = @_;