]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/JSONSchema.pm
createSchema: include type property
[pve-common.git] / src / PVE / JSONSchema.pm
index e1485ff161f13343c5ca0768e4a575374c6a1da0..dbe2e3516493350e3ca6509e68529d9916a1b6ab 100644 (file)
@@ -42,7 +42,7 @@ sub get_standard_option {
     my $res = $base || {};
 
     foreach my $opt (keys %$std) {
-       next if $res->{$opt};
+       next if defined($res->{$opt});
        $res->{$opt} = $std->{$opt};
     }
 
@@ -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";
     }
@@ -271,9 +278,23 @@ sub pve_verify_iface {
     return $id;
 }
 
+# general addresses by name or IP
+register_format('address', \&pve_verify_address);
+sub pve_verify_address {
+    my ($addr, $noerr) = @_;
+
+    if (!(pve_verify_ip($addr, 1) ||
+         pve_verify_dns_name($addr, 1)))
+    {
+          return undef if $noerr;
+          die "value does not look like a valid address: $addr\n";
+    }
+    return $addr;
+}
+
 register_standard_option('spice-proxy', {
     description => "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As resonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).",
-    type => 'string', format => 'dns-name',
+    type => 'string', format => 'address',
 }); 
 
 register_standard_option('remote-viewer-config', {
@@ -796,6 +817,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,
@@ -941,6 +967,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.",
@@ -1056,20 +1087,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;
@@ -1103,7 +1144,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
@@ -1136,13 +1177,12 @@ sub parse_config {
 
     my $cfg = {};
 
-    while ($raw && $raw =~ s/^(.*?)(\n|$)//) {
+    while ($raw =~ /^\s*(.+?)\s*$/gm) {
        my $line = $1;
-       next if $line =~ m/^\#/; # skip comment lines
-       next if $line =~ m/^\s*$/; # skip empty lines
 
-       if ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
+       next if $line =~ /^#/;
+
+       if ($line =~ m/^(\S+?):\s*(.*)$/) {
            my $key = $1;
            my $value = $2;
            if ($schema->{properties}->{$key} &&