'255.255.255.224' => 27,
'255.255.255.240' => 28,
'255.255.255.248' => 29,
- '255.255.255.252' => 30
+ '255.255.255.252' => 30,
+ '255.255.255.254' => 31,
+ '255.255.255.255' => 32,
};
register_format('ipv4mask', \&pve_verify_ipv4mask);
return undef;
}
return 1;
+ } elsif ($type eq 'string' && $vt eq 'Regexp') {
+ # qr// regexes can be used as strings and make sense for format=regex
+ return 1;
} else {
if ($vt) {
add_error($errors, $path, "type check ('$type') failed - got $vt");
check_prop($value, $requires, $path, $errors);
} elsif (!defined($value->{$requires})) {
add_error($errors, $path ? "$path.$requires" : $requires,
- "missing property - '$newpath' requiers this property");
+ "missing property - '$newpath' requires this property");
}
}
optional => 1,
description => "This provides a description of the purpose the instance property. The value can be a string or it can be an object with properties corresponding to various different instance languages (with an optional default property indicating the default description).",
},
+ verbose_description => {
+ type => "string",
+ optional => 1,
+ description => "This provides a more verbose description.",
+ },
format_description => {
type => "string",
optional => 1,
if defined($phash->{alias});
die "default key '$key' with keyAlias attribute is not allowed\n"
if $phash->{keyAlias};
-
$default_key = $key;
}
my $key_alias = $phash->{keyAlias};
+ die "found keyAlias without 'alias definition for '$key'\n"
+ if $key_alias && !$phash->{alias};
+
if ($phash->{alias} && $key_alias) {
die "inconsistent keyAlias '$key_alias' definition"
if defined($keyAliasProps->{$key_alias}) &&
sub generate_typetext {
my ($format) = @_;
- my $default_key = &$find_schema_default_key($format);
+ my ($default_key, $keyAliasProps) = &$find_schema_default_key($format);
my $res = '';
my $add_sep = 0;
}
};
- if (defined($default_key)) {
- my $phash = $format->{$default_key};
- &$format_key_value($default_key, $phash);
- }
+ my $done = {};
- foreach my $key (sort keys %$format) {
- next if defined($default_key) && ($key eq $default_key);
+ my $cond_add_key = sub {
+ my ($key) = @_;
+
+ return if $done->{$key}; # avoid duplicates
+
+ $done->{$key} = 1;
my $phash = $format->{$key};
- next if $phash->{alias};
- next if $phash->{group};
+ return if !$phash; # should not happen
+
+ return if $phash->{alias};
&$format_key_value($key, $phash);
- if (my $keyAlias = $phash->{keyAlias}) {
- &$add_option_string("<$keyAlias>=<$key>", 1);
- }
+ };
+
+ &$cond_add_key($default_key) if defined($default_key);
+
+ # add required keys first
+ foreach my $key (sort keys %$format) {
+ my $phash = $format->{$key};
+ &$cond_add_key($key) if $phash && !$phash->{optional};
+ }
+
+ # add the rest
+ foreach my $key (sort keys %$format) {
+ &$cond_add_key($key);
+ }
+
+ foreach my $keyAlias (sort keys %$keyAliasProps) {
+ &$add_option_string("<$keyAlias>=<$keyAliasProps->{$keyAlias }>", 1);
}
return $res;
}
};
- my $done = {};
+ my $done = { map { $_ => 1 } @$skip };
my $cond_add_key = sub {
- my ($key) = @_;
+ my ($key, $isdefault) = @_;
return if $done->{$key}; # avoid duplicates
die "internal error" if defined($phash->{alias});
my $value_str = &$format_value($key, $value, $phash->{format});
- &$add_option_string("$key=${value_str}");
+ if ($isdefault) {
+ &$add_option_string($value_str);
+ } else {
+ &$add_option_string("$key=${value_str}");
+ }
};
# add default key first
- &$cond_add_key($default_key) if defined($default_key);
+ &$cond_add_key($default_key, 1) if defined($default_key);
+
+ # add required keys first
+ foreach my $key (sort keys %$data) {
+ my $phash = $format->{$key};
+ &$cond_add_key($key) if $phash && !$phash->{optional};
+ }
+ # add the rest
foreach my $key (sort keys %$data) {
&$cond_add_key($key);
}
sub schema_get_type_text {
my ($phash) = @_;
+ my $type = $phash->{type} || 'string';
+
if ($phash->{typetext}) {
return $phash->{typetext};
} elsif ($phash->{format_description}) {
return "(" . join(' | ', sort @{$phash->{enum}}) . ")";
} elsif ($phash->{pattern}) {
return $phash->{pattern};
- } elsif ($phash->{type} eq 'integer' || $phash->{type} eq 'number') {
+ } elsif ($type eq 'integer' || $type eq 'number') {
+ # NOTE: always access values as number (avoid converion to string)
if (defined($phash->{minimum}) && defined($phash->{maximum})) {
- return "$phash->{type} ($phash->{minimum} - $phash->{maximum})";
+ return "$type (" . ($phash->{minimum} + 0) . " - " .
+ ($phash->{maximum} + 0) . ")";
} elsif (defined($phash->{minimum})) {
- return "$phash->{type} ($phash->{minimum} - N)";
+ return "$type (" . ($phash->{minimum} + 0) . " - N)";
} elsif (defined($phash->{maximum})) {
- return "$phash->{type} (-N - $phash->{maximum})";
+ return "$type (-N - " . ($phash->{maximum} + 0) . ")";
}
- } elsif ($phash->{type} eq 'string') {
+ } elsif ($type eq 'string') {
if (my $format = $phash->{format}) {
$format = get_format($format) if ref($format) ne 'HASH';
if (ref($format) eq 'HASH') {
}
}
- my $type = $phash->{type} || 'string';
-
return $type;
}