]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/JSONSchema.pm
JSONSchema: add get_netmask_bits and missing netmask
[pve-common.git] / src / PVE / JSONSchema.pm
index 41a66528681e1c40812531798826462bb90c3c48..d458ec13f87d57eed2b6d1fab691479dac5cf0a5 100644 (file)
@@ -83,7 +83,7 @@ register_standard_option('pve-config-digest', {
     description => 'Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.',
     type => 'string',
     optional => 1,
-    maxLength => 40, # sha1 hex digest lenght is 40
+    maxLength => 40, # sha1 hex digest length is 40
 });
 
 register_standard_option('skiplock', {
@@ -105,6 +105,20 @@ register_standard_option('fingerprint-sha256', {
     pattern => '([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}',
 });
 
+register_standard_option('pve-output-format', {
+    type => 'string',
+    description => 'Output format.',
+    enum => [ 'text', 'json', 'json-pretty', 'yaml' ],
+    optional => 1,
+    default => 'text',
+});
+
+register_standard_option('pve-snapshot-name', {
+    description => "The name of the snapshot.",
+    type => 'string', format => 'pve-configid',
+    maxLength => 40,
+});
+
 my $format_list = {};
 
 sub register_format {
@@ -121,6 +135,22 @@ sub get_format {
     return $format_list->{$format};
 }
 
+my $renderer_hash = {};
+
+sub register_renderer {
+    my ($name, $code) = @_;
+
+    die "renderer '$name' already registered\n"
+       if $renderer_hash->{$name};
+
+    $renderer_hash->{$name} = $code;
+}
+
+sub get_renderer {
+    my ($name) = @_;
+    return $renderer_hash->{$name};
+}
+
 # register some common type for pve
 
 register_format('string', sub {}); # allow format => 'string-list'
@@ -180,6 +210,28 @@ sub pve_verify_node_name {
     return $node;
 }
 
+register_format('mac-addr', \&pve_verify_mac_addr);
+sub pve_verify_mac_addr {
+    my ($mac_addr, $noerr) = @_;
+
+    # don't allow I/G bit to be set, most of the time it breaks things, see:
+    # https://pve.proxmox.com/pipermail/pve-devel/2019-March/035998.html
+    if ($mac_addr !~ m/^[a-f0-9][02468ace](?::[a-f0-9]{2}){5}$/i) {
+       return undef if $noerr;
+       die "value does not look like a valid unicast MAC address\n";
+    }
+    return $mac_addr;
+
+}
+register_standard_option('mac-addr', {
+    type => 'string',
+    description => 'Unicast MAC address.',
+    verbose_description => 'A common MAC address with the I/G (Individual/Group) bit not set.',
+    format_description => "XX:XX:XX:XX:XX:XX",
+    optional => 1,
+    format => 'mac-addr',
+});
+
 register_format('ipv4', \&pve_verify_ipv4);
 sub pve_verify_ipv4 {
     my ($ipv4, $noerr) = @_;
@@ -214,6 +266,7 @@ sub pve_verify_ip {
 }
 
 my $ipv4_mask_hash = {
+    '0.0.0.0' => 0,
     '128.0.0.0' => 1,
     '192.0.0.0' => 2,
     '224.0.0.0' => 3,
@@ -248,6 +301,11 @@ my $ipv4_mask_hash = {
     '255.255.255.255' => 32,
 };
 
+sub get_netmask_bits {
+    my ($mask) = @_;
+    return $ipv4_mask_hash->{$mask};
+}
+
 register_format('ipv4mask', \&pve_verify_ipv4mask);
 sub pve_verify_ipv4mask {
     my ($mask, $noerr) = @_;
@@ -321,8 +379,7 @@ register_format('email', \&pve_verify_email);
 sub pve_verify_email {
     my ($email, $noerr) = @_;
 
-    # we use same regex as in Utils.js
-    if ($email !~ /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,63}$/) {
+    if ($email !~ /^[\w\+\-\~]+(\.[\w\+\-\~]+)*@[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*$/) {
           return undef if $noerr;
           die "value does not look like a valid email address\n";
     }
@@ -379,7 +436,7 @@ sub pve_verify_disk_size {
 }
 
 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).",
+    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 reasonable 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 => 'address',
 }); 
 
@@ -415,23 +472,23 @@ my %bwlimit_opt = (
 my $bwlimit_format = {
        default => {
            %bwlimit_opt,
-           description => 'default bandwidth limit in MiB/s',
+           description => 'default bandwidth limit in KiB/s',
        },
        restore => {
            %bwlimit_opt,
-           description => 'bandwidth limit in MiB/s for restoring guests from backups',
+           description => 'bandwidth limit in KiB/s for restoring guests from backups',
        },
        migration => {
            %bwlimit_opt,
-           description => 'bandwidth limit in MiB/s for migrating guests',
+           description => 'bandwidth limit in KiB/s for migrating guests (including moving local disks)',
        },
        clone => {
            %bwlimit_opt,
-           description => 'bandwidth limit in MiB/s for cloning disks',
+           description => 'bandwidth limit in KiB/s for cloning disks',
        },
        move => {
            %bwlimit_opt,
-           description => 'bandwidth limit in MiB/s for moving disks',
+           description => 'bandwidth limit in KiB/s for moving disks',
        },
 };
 register_format('bwlimit', $bwlimit_format);
@@ -1065,6 +1122,11 @@ my $default_schema_noref = {
            optional => 1,
            description => "This provides the title of the property",
        },
+       renderer => {
+           type => "string",
+           optional => 1,
+           description => "This is used to provide rendering hints to format cli command output.",
+       },
        requires => {
            type => [ "string", "object" ],
            optional => 1,
@@ -1213,7 +1275,7 @@ my $method_schema = {
        },
        proxyto_callback => {
            type =>  'coderef',
-           description => "A function which is called to resolve the proxyto attribute. The default implementaion returns the value of the 'proxyto' parameter.",
+           description => "A function which is called to resolve the proxyto attribute. The default implementation returns the value of the 'proxyto' parameter.",
            optional => 1,
        },
         permissions => {
@@ -1253,7 +1315,7 @@ my $method_schema = {
        },
         fragmentDelimiter => {
             type => 'string',
-           description => "A ways to override the default fragment delimiter '/'. This onyl works on a whole sub-class. You can set this to the empty string to match the whole rest of the URI.",            
+           description => "A way to override the default fragment delimiter '/'. This only works on a whole sub-class. You can set this to the empty string to match the whole rest of the URI.",
            optional => 1,
         },
        parameters => {
@@ -1268,7 +1330,7 @@ my $method_schema = {
        },
         code => {
            type => 'coderef',
-           description => "method implementaion (code reference)",
+           description => "method implementation (code reference)",
            optional => 1,
         },
        subclass => {