sub pve_verify_configid {
my ($id, $noerr) = @_;
- if ($id !~ m/^[a-z][a-z0-9_]+$/i) {
+ if ($id !~ m/^[a-z][a-z0-9_-]+$/i) {
return undef if $noerr;
die "invalid configuration ID '$id'\n";
}
sub parse_storage_id {
my ($storeid, $noerr) = @_;
- if ($storeid !~ m/^[a-z][a-z0-9\-\_\.]*[a-z0-9]$/i) {
+ return parse_id($storeid, 'storage', $noerr);
+}
+
+PVE::JSONSchema::register_format('acme-plugin-id', \&parse_acme_plugin_id);
+sub parse_acme_plugin_id {
+ my ($pluginid, $noerr) = @_;
+
+ return parse_id($pluginid, 'ACME plugin', $noerr);
+}
+
+sub parse_id {
+ my ($id, $type, $noerr) = @_;
+
+ if ($id !~ m/^[a-z][a-z0-9\-\_\.]*[a-z0-9]$/i) {
return undef if $noerr;
- die "storage ID '$storeid' contains illegal characters\n";
+ die "$type ID '$id' contains illegal characters\n";
}
- return $storeid;
+ return $id;
}
-
register_format('pve-vmid', \&pve_verify_vmid);
sub pve_verify_vmid {
my ($vmid, $noerr) = @_;
return $node;
}
+sub parse_idmap {
+ my ($idmap, $idformat) = @_;
+
+ return undef if !$idmap;
+
+ my $map = {};
+
+ foreach my $entry (PVE::Tools::split_list($idmap)) {
+ if ($entry eq '1') {
+ $map->{identity} = 1;
+ } elsif ($entry =~ m/^([^:]+):([^:]+)$/) {
+ my ($source, $target) = ($1, $2);
+ eval {
+ check_format($idformat, $source, '');
+ check_format($idformat, $target, '');
+ };
+ die "entry '$entry' contains invalid ID - $@\n" if $@;
+
+ die "duplicate mapping for source '$source'\n"
+ if exists $map->{entries}->{$source};
+
+ $map->{entries}->{$source} = $target;
+ } else {
+ eval {
+ check_format($idformat, $entry);
+ };
+ die "entry '$entry' contains invalid ID - $@\n" if $@;
+
+ die "default target ID can only be provided once\n"
+ if exists $map->{default};
+
+ $map->{default} = $entry;
+ }
+ }
+
+ die "identity mapping cannot be combined with other mappings\n"
+ if $map->{identity} && ($map->{default} || exists $map->{entries});
+
+ return $map;
+}
+
+register_format('storagepair', \&verify_storagepair);
+sub verify_storagepair {
+ my ($storagepair, $noerr) = @_;
+
+ # note: this only checks a single list entry
+ # when using a storagepair-list map, you need to pass the full
+ # parameter to parse_idmap
+ eval { parse_idmap($storagepair, 'pve-storage-id') };
+ if ($@) {
+ return undef if $noerr;
+ die "$@\n";
+ }
+
+ return $storagepair;
+}
+
register_format('mac-addr', \&pve_verify_mac_addr);
sub pve_verify_mac_addr {
my ($mac_addr, $noerr) = @_;
return $ip;
}
+PVE::JSONSchema::register_format('ldap-simple-attr', \&verify_ldap_simple_attr);
+sub verify_ldap_simple_attr {
+ my ($attr, $noerr) = @_;
+
+ if ($attr =~ m/^[a-zA-Z0-9]+$/) {
+ return $attr;
+ }
+
+ die "value '$attr' does not look like a simple ldap attribute name\n" if !$noerr;
+
+ return undef;
+}
+
my $ipv4_mask_hash = {
'0.0.0.0' => 0,
'128.0.0.0' => 1,
format => $bwlimit_format,
});
+# used for pve-tag-list in e.g., guest configs
+register_format('pve-tag', \&pve_verify_tag);
+sub pve_verify_tag {
+ my ($value, $noerr) = @_;
+
+ return $value if $value =~ m/^[a-z0-9_][a-z0-9_\-\+\.]*$/i;
+
+ return undef if $noerr;
+
+ die "invalid characters in tag\n";
+}
+
sub pve_parse_startup_order {
my ($value) = @_;
description => "Method needs special privileges - only pvedaemon can execute it",
optional => 1,
},
+ allowtoken => {
+ type => 'boolean',
+ description => "Method is available for clients authenticated using an API token.",
+ optional => 1,
+ default => 1,
+ },
download => {
type => 'boolean',
description => "Method downloads the file content (filename is the return value of the method).",