]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/JSONSchema.pm
JSONSchema: format_description + generate_typetext
[pve-common.git] / src / PVE / JSONSchema.pm
index 2837cf56378a766d5f5dbe93f8431eabfd1291a9..8725949443d08ff50ad1e973dd8ee8ac4f77c5ef 100644 (file)
@@ -83,6 +83,13 @@ PVE::JSONSchema::register_standard_option('pve-config-digest', {
     maxLength => 40, # sha1 hex digest lenght is 40
 });
 
+PVE::JSONSchema::register_standard_option('extra-args', {
+    description => "Extra arguments as array",
+    type => 'array',
+    items => { type => 'string' },
+    optional => 1
+});
+
 my $format_list = {};
 
 sub register_format {
@@ -238,8 +245,8 @@ register_format('email', \&pve_verify_email);
 sub pve_verify_email {
     my ($email, $noerr) = @_;
 
-    # we use same regex as extjs Ext.form.VTypes.email
-    if ($email !~ /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/) {
+    # we use same regex as in Utils.js
+    if ($email !~ /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,63}$/) {
           return undef if $noerr;
           die "value does not look like a valid email address\n";
     }
@@ -790,6 +797,11 @@ my $default_schema_noref = {
            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).",
        },
+       format_description => {
+           type => "string",
+           optional => 1,
+           description => "This provides a shorter (usually just one word) description for a property used to generate descriptions for comma separated list property strings.",
+       },
         title => {
            type => "string",
            optional => 1,
@@ -810,6 +822,11 @@ my $default_schema_noref = {
            optional => 1,
            description => "This indicates the default for the instance property."
        },
+        completion => {
+           type => 'coderef',
+           description => "Bash completion function. This function should return a list of possible values.",
+           optional => 1,
+        },
         disallow => {
            type => "object",
            optional => 1,
@@ -955,6 +972,11 @@ my $method_schema = {
            description => "JSON Schema for parameters.",
            optional => 1,
        },
+        formatter => {
+           type => 'object',
+           description => "Used to store page formatter information (set by PVE::RESTHandler->register_page_formatter).",
+           optional => 1,
+        },
        returns => {
            type => 'object',
            description => "JSON Schema for return value.",
@@ -1070,20 +1092,30 @@ sub get_options {
        }
     }
 
+    Getopt::Long::Configure('prefix_pattern=(--|-)');
+
     my $opts = {};
     raise("unable to parse option\n", code => HTTP_BAD_REQUEST)
        if !Getopt::Long::GetOptionsFromArray($args, $opts, @getopt);
 
-    if (my $acount = scalar(@$args)) {
+    if (@$args) {
        if ($list_param) {
            $opts->{$list_param} = $args;
            $args = [];
        } elsif (ref($arg_param)) {
-           raise("wrong number of arguments\n", code => HTTP_BAD_REQUEST)
-               if scalar(@$arg_param) != $acount; 
-           foreach my $p (@$arg_param) {
-               $opts->{$p} = shift @$args;
+           foreach my $arg_name (@$arg_param) {
+               if ($opts->{'extra-args'}) {
+                   raise("internal error: extra-args must be the last argument\n", code => HTTP_BAD_REQUEST);
+               }
+               if ($arg_name eq 'extra-args') {
+                   $opts->{'extra-args'} = $args;
+                   $args = [];
+                   next;
+               }
+               raise("not enough arguments\n", code => HTTP_BAD_REQUEST) if !@$args;
+               $opts->{$arg_name} = shift @$args;
            }
+           raise("too many arguments\n", code => HTTP_BAD_REQUEST) if @$args;
        } else {
            raise("too many arguments\n", code => HTTP_BAD_REQUEST)
                if scalar(@$args) != 0;
@@ -1117,7 +1149,7 @@ sub get_options {
                if ($pd->{format} =~ m/-list/) {
                    # allow --vmid 100 --vmid 101 and --vmid 100,101
                    # allow --dow mon --dow fri and --dow mon,fri
-                   $opts->{$p} = join(",", @{$opts->{$p}});
+                   $opts->{$p} = join(",", @{$opts->{$p}}) if ref($opts->{$p}) eq 'ARRAY';
                } elsif ($pd->{format} =~ m/-alist/) {
                    # we encode array as \0 separated strings
                    # Note: CGI.pm also use this encoding
@@ -1200,4 +1232,32 @@ sub dump_config {
     return $data;
 }
 
+sub generate_typetext {
+    my ($schema) = @_;
+    my $typetext = '';
+    my (@optional, @required);
+    foreach my $key (sort keys %$schema) {
+       next if !$schema->{$key}->{format_description};
+       if ($schema->{$key}->{optional}) {
+           push @optional, $key;
+       } else {
+           push @required, $key;
+       }
+    }
+    my ($pre, $post) = ('', '');
+    foreach my $key (@required) {
+       my $desc = $schema->{$key}->{format_description};
+       $typetext .= "$pre$key=<$desc>$post";
+       $pre = ', ';
+    }
+    $pre = ' [,' if $pre;
+    foreach my $key (@optional) {
+       my $desc = $schema->{$key}->{format_description};
+       $typetext .= "$pre$key=<$desc>$post";
+       $pre = ' [,';
+       $post = ']';
+    }
+    return $typetext;
+}
+
 1;