5
0
mirror of git://git.proxmox.com/git/pve-common.git synced 2025-01-03 09:17:36 +03:00

section config: implement array support

enables section configs in the style of:

----
type: id
    property value
    property value2
    property value3
----

can be combined with property strings

the provided create and update schema just pass through the array type
to the api, so the api call must always contain the complete array

also adds a test case for such array fields

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2023-06-06 15:08:46 +02:00 committed by Wolfgang Bumiller
parent 9a3af02069
commit 69d9edcc75
2 changed files with 63 additions and 5 deletions

View File

@ -254,7 +254,15 @@ sub check_value {
if (!$skipSchemaCheck) {
my $errors = {};
PVE::JSONSchema::check_prop($value, $schema, '', $errors);
my $checkschema = $schema;
if ($ct eq 'array') {
die "no item schema for array" if !defined($schema->{items});
$checkschema = $schema->{items};
}
PVE::JSONSchema::check_prop($value, $checkschema, '', $errors);
if (scalar(keys %$errors)) {
die "$errors->{$key}\n" if $errors->{$key};
die "$errors->{_root}\n" if $errors->{_root};
@ -311,6 +319,15 @@ sub parse_config {
}
};
my $is_array = sub {
my ($type, $key) = @_;
my $schema = $pdata->{propertyList}->{$key};
die "unknown property type\n" if !$schema;
return $schema->{type} eq 'array';
};
my $errors = [];
while (@lines) {
my $line = $nextline->();
@ -352,11 +369,19 @@ sub parse_config {
my ($k, $v) = ($1, $3);
eval {
if ($is_array->($type, $k)) {
if (!$unknown) {
$v = $plugin->check_value($type, $k, $v, $sectionId);
}
$config->{$k} = [] if !defined($config->{$k});
push $config->{$k}->@*, $v;
} else {
die "duplicate attribute\n" if defined($config->{$k});
if (!$unknown) {
$v = $plugin->check_value($type, $k, $v, $sectionId);
}
$config->{$k} = $v;
}
};
if (my $err = $@) {
warn "$errprefix (section '$sectionId') - unable to parse value of '$k': $err";
@ -448,6 +473,13 @@ my $format_config_line = sub {
if ($ct eq 'boolean') {
return "\t$key " . ($value ? 1 : 0) . "\n"
if defined($value);
} elsif ($ct eq 'array') {
die "property '$key' is not an array" if ref($value) ne 'ARRAY';
my $result = '';
for my $line ($value->@*) {
$result .= "\t$key $line\n" if $value ne '';
}
return $result;
} else {
return "\t$key $value\n" if "$value" ne '';
}

View File

@ -105,6 +105,25 @@ sub properties {
minimum => 3,
maximum => 9,
},
arrayfield => {
description => "Array Field with property string",
type => 'array',
items => {
type => 'string',
description => 'a property string',
format => {
subfield1 => {
type => 'string',
description => 'first subfield'
},
subfield2 => {
type => 'integer',
minimum => 0,
optional => 1,
},
},
},
},
};
}
@ -113,6 +132,7 @@ sub options {
common => { optional => 1 },
field2 => {},
another => {},
arrayfield => { optional => 1 },
};
}
@ -190,6 +210,10 @@ my $with_unknown_data = {
type => 'two',
field2 => 5,
another => 'even more text',
arrayfield => [
'subfield1=test,subfield2=2',
'subfield1=test2',
],
},
invalid => {
type => 'bad',
@ -214,6 +238,8 @@ bad: invalid
two: t3
field2 5
another even more text
arrayfield subfield1=test,subfield2=2
arrayfield subfield1=test2
EOF
Conf->expect_fail('unknown-forbidden', $with_unknown_data, $with_unknown_text);