File Coverage

blib/lib/Net/Proxmox/VE/Access.pm
Criterion Covered Total %
statement 15 187 8.0
branch 0 184 0.0
condition n/a
subroutine 5 30 16.6
pod 25 25 100.0
total 45 426 10.5


line stmt bran cond sub pod time code
1             #!/bin/false
2             # vim: softtabstop=4 tabstop=4 shiftwidth=4 ft=perl expandtab smarttab
3             # PODNAME: Net::Proxmox::VE::Access
4             # ABSTRACT: Functions for the 'access' portion of the API
5              
6 2     2   228357 use strict;
  2         4  
  2         105  
7 2     2   12 use warnings;
  2         4  
  2         174  
8              
9             package Net::Proxmox::VE::Access;
10             $Net::Proxmox::VE::Access::VERSION = '0.44';
11 2     2   14 use parent 'Exporter';
  2         3  
  2         17  
12              
13 2     2   702 use Net::Proxmox::VE::Exception;
  2         7  
  2         61  
14              
15 2     2   643 use JSON::MaybeXS qw(decode_json);
  2         11271  
  2         5017  
16              
17             our @EXPORT = qw(
18             access
19             access_domains
20             access_groups
21             access_roles
22             create_access_domains
23             create_access_groups
24             create_access_roles
25             create_access_users
26             delete_access_domains
27             delete_access_groups
28             delete_access_roles
29             delete_access_users
30             get_access_domains
31             get_access_groups
32             get_access_roles
33             get_access_users
34             update_access_domains
35             update_access_groups
36             update_access_roles
37             update_access_users
38             sync_access_domains
39             get_access_acl
40             update_access_acl
41             update_access_password
42             );
43              
44              
45             my $BASEPATH = '/access';
46              
47             sub access {
48              
49 0 0   0 1   my $self = shift or return;
50              
51 0           return $self->get($BASEPATH);
52              
53             }
54              
55              
56             sub access_domains {
57              
58 0 0   0 1   my $self = shift or return;
59              
60 0           return $self->get( $BASEPATH, 'domains' );
61              
62             }
63              
64              
65             sub create_access_domains {
66              
67 0 0   0 1   my $self = shift or return;
68 0           my @p = @_;
69              
70 0 0         Net::Proxmox::VE::Exception->throw(
71             'No arguments for create_access_domains()')
72             unless @p;
73 0           my %args;
74              
75 0 0         if ( @p == 1 ) {
76 0 0         Net::Proxmox::VE::Exception->throw(
77             'Single argument not a hash for create_access_domains()')
78             unless ref $p[0] eq 'HASH';
79 0           %args = %{ $p[0] };
  0            
80             }
81             else {
82 0 0         Net::Proxmox::VE::Exception->throw(
83             'Odd number of arguments for create_access_domains()')
84             if ( scalar @p % 2 != 0 );
85 0           %args = @p;
86             }
87              
88 0           return $self->post( $BASEPATH, 'domains', \%args );
89              
90             }
91              
92              
93             sub get_access_domains {
94              
95 0 0   0 1   my $self = shift or return;
96              
97 0 0         my $realm = shift
98             or
99             Net::Proxmox::VE::Exception->throw('No realm for get_access_domains()');
100 0 0         Net::Proxmox::VE::Exception->throw(
101             'realm must be a scalar for get_access_domains()')
102             if ref $realm;
103              
104 0           return $self->get( $BASEPATH, 'domains', $realm );
105              
106             }
107              
108              
109             sub update_access_domains {
110              
111 0 0   0 1   my $self = shift or return;
112              
113 0 0         my $realm = shift
114             or Net::Proxmox::VE::Exception->throw(
115             'No realm provided for update_access_domains()');
116 0 0         Net::Proxmox::VE::Exception->throw(
117             'realm must be a scalar for update_access_domains()')
118             if ref $realm;
119 0           my @p = @_;
120              
121 0 0         Net::Proxmox::VE::Exception->throw(
122             'No arguments for update_access_domains()')
123             unless @p;
124 0           my %args;
125              
126 0 0         if ( @p == 1 ) {
127 0 0         Net::Proxmox::VE::Exception->throw(
128             'Single argument not a hash for update_access_domains()')
129             unless ref $p[0] eq 'HASH';
130 0           %args = %{ $p[0] };
  0            
131             }
132             else {
133 0 0         Net::Proxmox::VE::Exception->throw(
134             'Odd number of arguments for update_access_domains()')
135             if ( scalar @p % 2 != 0 );
136 0           %args = @p;
137             }
138              
139 0           return $self->put( $BASEPATH, 'domains', $realm, \%args );
140              
141             }
142              
143              
144             sub delete_access_domains {
145              
146 0 0   0 1   my $self = shift or return;
147              
148 0 0         my $realm = shift
149             or Net::Proxmox::VE::Exception->throw(
150             'No realm provided for delete_access_domains()');
151 0 0         Net::Proxmox::VE::Exception->throw(
152             'realm must be a scalar for delete_access_domains()')
153             if ref $realm;
154              
155 0           return $self->delete( $BASEPATH, 'domains', $realm );
156              
157             }
158              
159             ###
160             #
161              
162              
163             sub sync_access_domains {
164              
165 0 0   0 1   my $self = shift or return;
166              
167 0 0         my $realm = shift
168             or Net::Proxmox::VE::Exception->throw(
169             'No realm provided for sync_access_groups()');
170 0 0         Net::Proxmox::VE::Exception->throw(
171             'realm must be a scalar for sync_access_groups()')
172             if ref $realm;
173              
174 0           my @p = @_;
175              
176 0 0         Net::Proxmox::VE::Exception->throw('No arguments for sync_access_domains()')
177             unless @p;
178 0           my %args;
179              
180 0 0         if ( @p == 1 ) {
181 0 0         Net::Proxmox::VE::Exception->throw(
182             'Single argument not a hash for sync_access_domains()')
183             unless ref $p[0] eq 'HASH';
184 0           %args = %{ $p[0] };
  0            
185             }
186             else {
187 0 0         Net::Proxmox::VE::Exception->throw(
188             'Odd number of arguments for sync_access_domains()')
189             if ( scalar @p % 2 != 0 );
190 0           %args = @p;
191             }
192              
193 0           return $self->post( $BASEPATH, 'domains', \%args );
194              
195             }
196              
197              
198             sub access_groups {
199              
200 0 0   0 1   my $self = shift or return;
201              
202 0           return $self->get( $BASEPATH, 'groups' );
203              
204             }
205              
206              
207             sub create_access_groups {
208              
209 0 0   0 1   my $self = shift or return;
210 0           my @p = @_;
211              
212 0 0         Net::Proxmox::VE::Exception->throw(
213             'No arguments for create_access_groups()')
214             unless @p;
215 0           my %args;
216              
217 0 0         if ( @p == 1 ) {
218 0 0         Net::Proxmox::VE::Exception->throw(
219             'Single argument not a hash for create_access_groups()')
220             unless ref $p[0] eq 'HASH';
221 0           %args = %{ $p[0] };
  0            
222             }
223             else {
224 0 0         Net::Proxmox::VE::Exception->throw(
225             'Odd number of arguments for create_access_groups()')
226             if ( scalar @p % 2 != 0 );
227 0           %args = @p;
228             }
229              
230 0           return $self->post( $BASEPATH, 'groups', \%args );
231              
232             }
233              
234              
235             sub get_access_groups {
236              
237 0 0   0 1   my $self = shift or return;
238              
239 0 0         my $groupid = shift
240             or
241             Net::Proxmox::VE::Exception->throw('No groupid for get_access_groups()');
242 0 0         Net::Proxmox::VE::Exception->throw(
243             'groupid must be a scalar for get_access_groups()')
244             if ref $groupid;
245              
246 0           return $self->get( $BASEPATH, 'groups', $groupid );
247              
248             }
249              
250              
251             sub update_access_groups {
252              
253 0 0   0 1   my $self = shift or return;
254              
255 0 0         my $realm = shift
256             or Net::Proxmox::VE::Exception->throw(
257             'No realm provided for update_access_groups()');
258 0 0         Net::Proxmox::VE::Exception->throw(
259             'realm must be a scalar for update_access_groups()')
260             if ref $realm;
261              
262 0           my @p = @_;
263              
264 0 0         Net::Proxmox::VE::Exception->throw(
265             'No arguments for update_access_groups()')
266             unless @p;
267 0           my %args;
268              
269 0 0         if ( @p == 1 ) {
270 0 0         Net::Proxmox::VE::Exception->throw(
271             'Single argument not a hash for update_access_groups()')
272             unless ref $p[0] eq 'HASH';
273 0           %args = %{ $p[0] };
  0            
274             }
275             else {
276 0 0         Net::Proxmox::VE::Exception->throw(
277             'Odd number of arguments for update_access_groups()')
278             if ( scalar @p % 2 != 0 );
279 0           %args = @p;
280             }
281              
282 0           return $self->put( $BASEPATH, 'groups', $realm, \%args );
283              
284             }
285              
286              
287             sub delete_access_groups {
288              
289 0 0   0 1   my $self = shift or return;
290 0 0         my $groupid = shift
291             or Net::Proxmox::VE::Exception->throw(
292             'No argument given for delete_access_groups()');
293              
294 0           return $self->delete( $BASEPATH, 'groups', $groupid );
295              
296             }
297              
298              
299             sub access_roles {
300              
301 0 0   0 1   my $self = shift or return;
302              
303 0           return $self->get( $BASEPATH, 'roles' );
304              
305             }
306              
307              
308             sub create_access_roles {
309              
310 0 0   0 1   my $self = shift or return;
311 0           my @p = @_;
312              
313 0 0         Net::Proxmox::VE::Exception->throw('No arguments for create_access_roles()')
314             unless @p;
315 0           my %args;
316              
317 0 0         if ( @p == 1 ) {
318 0 0         Net::Proxmox::VE::Exception->throw(
319             'Single argument not a hash for create_access_roles()')
320             unless ref $p[0] eq 'HASH';
321 0           %args = %{ $p[0] };
  0            
322             }
323             else {
324 0 0         Net::Proxmox::VE::Exception->throw(
325             'Odd number of arguments for create_access_roles()')
326             if ( scalar @p % 2 != 0 );
327 0           %args = @p;
328             }
329              
330 0           return $self->post( $BASEPATH, 'roles', \%args );
331              
332             }
333              
334              
335             sub get_access_roles {
336              
337 0 0   0 1   my $self = shift or return;
338              
339 0 0         my $roleid = shift
340             or Net::Proxmox::VE::Exception->throw('No roleid for get_access_roles()');
341 0 0         Net::Proxmox::VE::Exception->throw(
342             'roleid must be a scalar for get_access_roles()')
343             if ref $roleid;
344              
345 0           return $self->get( $BASEPATH, 'roles', $roleid );
346              
347             }
348              
349              
350             sub update_access_roles {
351              
352 0 0   0 1   my $self = shift or return;
353 0 0         my $realm = shift
354             or Net::Proxmox::VE::Exception->throw(
355             'No realm provided for update_access_roles()');
356 0 0         Net::Proxmox::VE::Exception->throw(
357             'realm must be a scalar for update_access_roles()')
358             if ref $realm;
359 0           my @p = @_;
360              
361 0 0         Net::Proxmox::VE::Exception->throw('No arguments for update_access_roles()')
362             unless @p;
363 0           my %args;
364              
365 0 0         if ( @p == 1 ) {
366 0 0         Net::Proxmox::VE::Exception->throw(
367             'Single argument not a hash for update_access_roles()')
368             unless ref $p[0] eq 'HASH';
369 0           %args = %{ $p[0] };
  0            
370             }
371             else {
372 0 0         Net::Proxmox::VE::Exception->throw(
373             'Odd number of arguments for update_access_roles()')
374             if ( scalar @p % 2 != 0 );
375 0           %args = @p;
376             }
377              
378 0           return $self->put( $BASEPATH, 'roles', $realm, \%args );
379              
380             }
381              
382              
383             sub delete_access_roles {
384              
385 0 0   0 1   my $self = shift or return;
386 0 0         my $roleid = shift
387             or Net::Proxmox::VE::Exception->throw(
388             'No argument given for delete_access_roles()');
389              
390 0           return $self->delete( $BASEPATH, 'roles', $roleid );
391              
392             }
393              
394              
395             sub access_users {
396              
397 0 0   0 1   my $self = shift or return;
398              
399 0           return $self->get( $BASEPATH, 'users' );
400              
401             }
402              
403              
404             sub create_access_users {
405              
406 0 0   0 1   my $self = shift or return;
407 0           my @p = @_;
408              
409 0 0         Net::Proxmox::VE::Exception->throw('No arguments for create_access_users()')
410             unless @p;
411 0           my %args;
412              
413 0 0         if ( @p == 1 ) {
414 0 0         Net::Proxmox::VE::Exception->throw(
415             'Single argument not a hash for create_access_users()')
416             unless ref $p[0] eq 'HASH';
417 0           %args = %{ $p[0] };
  0            
418             }
419             else {
420 0 0         Net::Proxmox::VE::Exception->throw(
421             'Odd number of arguments for create_access_users()')
422             if ( scalar @p % 2 != 0 );
423 0           %args = @p;
424             }
425              
426 0           return $self->post( $BASEPATH, 'users', \%args );
427              
428             }
429              
430              
431             sub get_access_users {
432              
433 0 0   0 1   my $self = shift or return;
434              
435 0 0         my $userid = shift
436             or Net::Proxmox::VE::Exception->throw('No userid for get_access_users()');
437 0 0         Net::Proxmox::VE::Exception->throw(
438             'userid must be a scalar for get_access_users()')
439             if ref $userid;
440              
441 0           return $self->get( $BASEPATH, 'users', $userid );
442              
443             }
444              
445              
446             sub update_access_users {
447              
448 0 0   0 1   my $self = shift or return;
449 0 0         my $realm = shift
450             or Net::Proxmox::VE::Exception->throw(
451             'No realm provided for update_access_users()');
452 0 0         Net::Proxmox::VE::Exception->throw(
453             'realm must be a scalar for update_access_users()')
454             if ref $realm;
455 0           my @p = @_;
456              
457 0 0         Net::Proxmox::VE::Exception->throw('No arguments for update_access_users()')
458             unless @p;
459 0           my %args;
460              
461 0 0         if ( @p == 1 ) {
462 0 0         Net::Proxmox::VE::Exception->throw(
463             'Single argument not a hash for update_access_users()')
464             unless ref $p[0] eq 'HASH';
465 0           %args = %{ $p[0] };
  0            
466             }
467             else {
468 0 0         Net::Proxmox::VE::Exception->throw(
469             'Odd number of arguments for update_access_users()')
470             if ( scalar @p % 2 != 0 );
471 0           %args = @p;
472             }
473              
474 0           return $self->put( $BASEPATH, 'users', $realm, \%args );
475              
476             }
477              
478              
479             sub delete_access_users {
480              
481 0 0   0 1   my $self = shift or return;
482 0 0         my $userid = shift
483             or Net::Proxmox::VE::Exception->throw(
484             'No argument given for delete_access_users()');
485              
486 0           return $self->delete( $BASEPATH, 'users', $userid );
487              
488             }
489              
490              
491             sub get_access_acl {
492              
493 0 0   0 1   my $self = shift or return;
494              
495 0           return $self->get( $BASEPATH, 'acl' );
496              
497             }
498              
499              
500             sub update_access_acl {
501              
502 0 0   0 1   my $self = shift or return;
503 0           my @p = @_;
504              
505 0 0         Net::Proxmox::VE::Exception->throw('No arguments for update_acl()')
506             unless @p;
507 0           my %args;
508              
509 0 0         if ( @p == 1 ) {
510 0 0         Net::Proxmox::VE::Exception->throw(
511             'Single argument not a hash for update_acl()')
512             unless ref $p[0] eq 'HASH';
513 0           %args = %{ $p[0] };
  0            
514             }
515             else {
516 0 0         Net::Proxmox::VE::Exception->throw(
517             'Odd number of arguments for update_acl()')
518             if ( scalar @p % 2 != 0 );
519 0           %args = @p;
520             }
521              
522 0           return $self->put( $BASEPATH, 'acl', \%args );
523              
524             }
525              
526              
527             sub update_access_password {
528              
529 0 0   0 1   my $self = shift or return;
530 0           my @p = @_;
531              
532 0 0         Net::Proxmox::VE::Exception->throw('No arguments for update_password()')
533             unless @p;
534 0           my %args;
535              
536 0 0         if ( @p == 1 ) {
537 0 0         Net::Proxmox::VE::Exception->throw(
538             'Single argument not a hash for update_password()')
539             unless ref $p[0] eq 'HASH';
540 0           %args = %{ $p[0] };
  0            
541             }
542             else {
543 0 0         Net::Proxmox::VE::Exception->throw(
544             'Odd number of arguments for update_password()')
545             if ( scalar @p % 2 != 0 );
546 0           %args = @p;
547             }
548              
549 0           return $self->put( $BASEPATH, 'password', \%args );
550              
551             }
552              
553              
554             1;
555              
556             __END__
557              
558             =pod
559              
560             =encoding UTF-8
561              
562             =head1 NAME
563              
564             Net::Proxmox::VE::Access - Functions for the 'access' portion of the API
565              
566             =head1 VERSION
567              
568             version 0.44
569              
570             =head1 SYNOPSIS
571              
572             # assuming $obj is a Net::Proxmox::VE object
573              
574             my @dir_index = $obj->access();
575              
576             my @domain_index = $obj->access_domains();
577             my $domain = $obj->access_domains($realm);
578              
579             =head1 METHODS
580              
581             =head2 access
582              
583             Without arguments, returns the 'Directory index'.
584              
585             Note: Accessible by all authenticated users.
586              
587             =head2 access_domains
588              
589             Gets a list of access domains (aka the Authentication domain index)
590              
591             @pools = $obj->access_domains();
592              
593             Note: Anyone can access that, because we need that list for the login box (before the user is authenticated).
594              
595             No arguments are available.
596              
597             A hash will be returned which will include the following:
598              
599             =over 4
600              
601             =item realm
602              
603             String.
604              
605             =item string
606              
607             String.
608              
609             =item comment
610              
611             A comment. The GUI use this text when you select a domain (Realm) on the login window.
612              
613             Optional.
614              
615             =item tfa
616              
617             Enum. Available options: yubico, oath
618              
619             Optional.
620              
621             =back
622              
623             =head2 create_access_domains
624              
625             Adds an authentication server. i.e. creates a new access domain
626              
627             $ok = $obj->create_access_domains( %args );
628             $ok = $obj->create_access_domains( \%args );
629              
630             I<%args> may items contain from the following list
631              
632             =over 4
633              
634             =item realm
635              
636             String. The id of the authentication domain you wish to add, in pve-realm format. This is required.
637              
638             =item type
639              
640             Enum. This is the server type and is one of: ad, ldap, openid, pam, or pve
641              
642             This is required.
643              
644             =item base_dn
645              
646             String. LDAP base domain name. Optional.
647              
648             =item comment
649              
650             String. This is a comment associated with the new domain, this is optional.
651              
652             =item default
653              
654             Boolean. Use this domain as the default. Optional.
655              
656             =item domain
657              
658             String. AD domain name. Optional.
659              
660             =item port
661              
662             Integer. Server port, user '0' if you want to use the default setting. Optional.
663              
664             =item secure
665              
666             Boolean. Use secure LDAPS protocol. Optional.
667              
668             =item user_attr
669              
670             String. LDAP user attribute name. Optional.
671              
672             =back
673              
674             =head2 get_access_domains
675              
676             Gets a single access domain
677              
678             $ok = $obj->get_access_domains( $realm )
679              
680             Where $realm is a string in pve-realm format
681              
682             =head2 update_access_domains
683              
684             Updates (sets) a access domain's data
685              
686             $ok = $obj->update_access_domains( $realm, %args );
687             $ok = $obj->update_access_domains( $realm, \%args );
688              
689             Where $realm is a string in pve-realm format
690              
691             I<%args> may items contain from the following list
692              
693             =over 4
694              
695             =item base_dn
696              
697             String. LDAP base domain name. Optional.
698              
699             =item comment
700              
701             String. This is a comment associated with the domain, this is optional.
702              
703             =item default
704              
705             Boolean. Use this domain as the default. Optional.
706              
707             =item domain
708              
709             String. AD domain name. Optional.
710              
711             =item port
712              
713             Integer. Server port, user '0' if you want to use the default setting. Optional.
714              
715             =item secure
716              
717             Boolean. Use secure LDAPS protocol. Optional.
718              
719             =item user_attr
720              
721             String. LDAP user attribute name. Optional.
722              
723             =back
724              
725             =head2 delete_access_domains
726              
727             Deletes a single access domain
728              
729             $ok = $obj->delete_access_domains( $realm )
730              
731             Where $realm is a string in pve-realm format
732              
733             =head2 sync_access_domains
734              
735             Syncs users and/or groups from the configured LDAP to user.cfg.
736              
737             $ok = $obj->sync_access_domains( $realm, %args );
738             $ok = $obj->sync_access_domains( $realm, \%args );
739              
740             NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.
741              
742             I<%args> may items contain from the following list
743              
744             =over 4
745              
746             =item realm
747              
748             String. The id of the authentication domain you wish to add, in pve-realm format. This is required.
749              
750             =item dry-run
751              
752             Boolean. If set, does not write anything. Default 0
753              
754             =item enable-new
755              
756             Boolean. Enable newly synced users immediately. Default 1
757              
758             =item remove-vanished
759              
760             String. A semicolon-seperated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).
761              
762             Format: ([acl];[properties];[entry]) | none
763              
764             =item scope
765              
766             Enum. Select what to sync.
767              
768             Possible values: users, groups, both
769              
770             =back
771              
772             =head2 access_groups
773              
774             Gets a list of access groups (aka the Group index)
775              
776             @pools = $obj->access_groups();
777              
778             Note: The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/<<group>>.
779              
780             =head2 create_access_groups
781              
782             Creates a new access group
783              
784             $ok = $obj->create_access_groups( %args );
785             $ok = $obj->create_access_groups( \%args );
786              
787             I<%args> may items contain from the following list
788              
789             =over 4
790              
791             =item groupid
792              
793             String. The id of the access group you wish to add, in pve-groupid format. This is required.
794              
795             =item comment
796              
797             String. This is a comment associated with the new group, this is optional.
798              
799             =back
800              
801             =head2 get_access_groups
802              
803             Gets a single access group
804              
805             $ok = $obj->get_access_groups( $groupid )
806              
807             Where I<$groupid> is a string in pve-groupid format
808              
809             =head2 update_access_groups
810              
811             Updates (sets) a access group's data
812              
813             $ok = $obj->update_access_groups( $groupid, %args );
814             $ok = $obj->update_access_groups( $groupid, \%args );
815              
816             Where I<$groupid> is a string in pve-groupid format
817              
818             I<%args> may items contain from the following list
819              
820             =over 4
821              
822             =item comment
823              
824             String. This is a comment associated with the group, this is optional.
825              
826             =back
827              
828             =head2 delete_access_groups
829              
830             Deletes a single access group
831              
832             $ok = $obj->delete_access_groups( $groupid )
833              
834             Where I<$groupid> is a string in pve-groupid format
835              
836             =head2 access_roles
837              
838             Gets a list of access roles (aka the Role index)
839              
840             @pools = $obj->access_roles();
841              
842             Note: Accessible by all authententicated users.
843              
844             =head2 create_access_roles
845              
846             Creates a new access role
847              
848             $ok = $obj->create_access_roles( %args );
849             $ok = $obj->create_access_roles( \%args );
850              
851             I<%args> may items contain from the following list
852              
853             =over 4
854              
855             =item roleid
856              
857             String. The id of the access role you wish to add, in pve-roleid format. This is required.
858              
859             =item privs
860              
861             String. A string in pve-string-list format. Optional.
862              
863             =back
864              
865             =head2 get_access_roles
866              
867             Gets a single access role
868              
869             $ok = $obj->get_access_roles( $roleid )
870              
871             Where I<$roleid> is a string in pve-roleid format
872              
873             =head2 update_access_roles
874              
875             Updates (sets) a access role's data
876              
877             $ok = $obj->update_access_roles( $roleid, %args );
878             $ok = $obj->update_access_roles( $roleid, \%args );
879              
880             Where I<$roleid> is a string in pve-roleid format
881              
882             I<%args> may items contain from the following list
883              
884             =over 4
885              
886             =item privs
887              
888             String. A string in pve-priv-list format, this is required.
889              
890             =item append
891              
892             Booelean. Append privileges to existing. Optional.
893              
894             =back
895              
896             =head2 delete_access_roles
897              
898             Deletes a single access role
899              
900             $ok = $obj->delete_access_roles( $roleid )
901              
902             Where I<$roleid> is a string in pve-roleid format
903              
904             =head2 access_users
905              
906             Gets a list of users (aka the User index)
907              
908             @pools = $obj->access_users();
909              
910             Note: You need 'Realm.AllocateUser' on '/access/realm/<<realm>>' on the realm of user <<userid>>, and 'User.Modify' permissions to '/access/groups/<<group>>' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups.
911              
912             =head2 create_access_users
913              
914             Creates a new user
915              
916             $ok = $obj->create_access_users( %args );
917             $ok = $obj->create_access_users( \%args );
918              
919             I<%args> may items contain from the following list
920              
921             =over 4
922              
923             =item userid
924              
925             String. The id of the user you wish to add, in pve-userid format. This is required.
926              
927             =item comment
928              
929             String. This is a comment associated with the new user, this is optional.
930              
931             =item email
932              
933             String. The users email address in email-opt format. Optional.
934              
935             =item enable
936              
937             Boolean. If the user is enabled where the default is to be enabled. Disable with a 0 value. Optional.
938              
939             =item expire
940              
941             Integer. Account expiration date in seconds since epoch. 0 means never expire. Optional.
942              
943             =item firstname
944              
945             String. Optional.
946              
947             =item groups
948              
949             String. A string in pve-groupid-list format. Optional.
950              
951             =item lastname
952              
953             String. Optional.
954              
955             =item password
956              
957             String. The users initial passowrd. Optional.
958              
959             =back
960              
961             =head2 get_access_users
962              
963             Gets a single user
964              
965             $ok = $obj->get_access_users( $userid )
966              
967             Where I<$userid> is a string in pve-userid format
968              
969             =head2 update_access_users
970              
971             Updates (sets) a user's configuration
972              
973             $ok = $obj->update_access_users( $userid, %args );
974             $ok = $obj->update_access_users( $userid, \%args );
975              
976             Where I<$userid> is a string in pve-userid format
977              
978             I<%args> may items contain from the following list
979              
980             =over 4
981              
982             =item append
983              
984             Boolean. Optional.
985              
986             =item comment
987              
988             String. This is a comment associated with the user, this is optional.
989              
990             =item email
991              
992             String. The users email address in email-opt format. Optional.
993              
994             =item enable
995              
996             Boolean. If the user is enabled where the default is to be enabled. Disable with a 0 value. Optional.
997              
998             =item expire
999              
1000             Integer. Account expiration date in seconds since epoch. 0 means never expire. Optional.
1001              
1002             =item firstname
1003              
1004             String. Optional.
1005              
1006             =item groups
1007              
1008             String. A string in pve-groupid-list format. Optional.
1009              
1010             =item lastname
1011              
1012             String. Optional.
1013              
1014             =back
1015              
1016             =head2 delete_access_users
1017              
1018             Deletes a single user
1019              
1020             $ok = $obj->delete_access_users( $userid )
1021              
1022             Where I<$userid> is a string in pve-userid format
1023              
1024             =head2 get_access_acl
1025              
1026             The returned list is restricted to objects where you have rights to modify permissions
1027              
1028             $pool = $obj->get_access_acl();
1029              
1030             Note: The returned list is restricted to objects where you have rights to modify permissions.
1031              
1032             =head2 update_access_acl
1033              
1034             Updates (sets) an acl's data
1035              
1036             $ok = $obj->update_access_acl( %args );
1037             $ok = $obj->update_access_acl( \%args );
1038              
1039             I<%args> may items contain from the following list
1040              
1041             =over 4
1042              
1043             =item path
1044              
1045             String. Access control path. Required.
1046              
1047             =item roles
1048              
1049             String. List of roles. Required.
1050              
1051             =item delete
1052              
1053             Boolean. Removes the access rather than adding it. Optional.
1054              
1055             =item groups
1056              
1057             String. List of groups. Optional.
1058              
1059             =item propagate
1060              
1061             Boolean. Allow to propagate (inherit) permissions. Optional.
1062              
1063             =item users
1064              
1065             String. List of users. Optional.
1066              
1067             =back
1068              
1069             =head2 update_access_password
1070              
1071             Updates a users password
1072              
1073             $ok = $obj->update_password( %args );
1074             $ok = $obj->update_password( \%args );
1075              
1076             Each user is allowed to change his own password. See proxmox api document for which permissions are needed to change the passwords of other people.
1077              
1078             I<%args> may items contain from the following list
1079              
1080             =over 4
1081              
1082             =item password
1083              
1084             String. The new password. Required.
1085              
1086             =item userid
1087              
1088             String. User ID. Required.
1089              
1090             =back
1091              
1092             Note: Each user is allowed to change his own password. A user can change the password of another user if he has 'Realm.AllocateUser' (on the realm of user <<userid>>) and 'User.Modify' permission on /access/groups/<<group>> on a group where user <<userid>> is member of.
1093              
1094             =head1 SEE ALSO
1095              
1096             L<Net::Proxmox::VE>
1097              
1098             =head1 AUTHOR
1099              
1100             Dean Hamstead <dean@fragfest.com.au>
1101              
1102             =head1 COPYRIGHT AND LICENSE
1103              
1104             This software is Copyright (c) 2026 by Dean Hamstead.
1105              
1106             This is free software, licensed under:
1107              
1108             The MIT (X11) License
1109              
1110             =cut