security group API: protect against concurrent updates
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 10 Apr 2014 08:38:48 +0000 (10:38 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 10 Apr 2014 08:39:17 +0000 (10:39 +0200)
src/PVE/API2/Firewall/Groups.pm
src/PVE/Firewall.pm

index 0317af8..8b65f21 100644 (file)
@@ -26,6 +26,7 @@ __PACKAGE__->register_method({
            type => "object",
            properties => { 
                name => get_standard_option('pve-security-group-name'),
+               digest => get_standard_option('pve-config-digest', { optional => 0} ),
                comment => { 
                    type => 'string',
                    optional => 1,
@@ -39,10 +40,13 @@ __PACKAGE__->register_method({
 
        my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
 
+       my $digest = $cluster_conf->{digest};
+
        my $res = [];
        foreach my $group (keys %{$cluster_conf->{groups}}) {
            my $data = { 
                name => $group,
+               digest => $digest,
                count => scalar(@{$cluster_conf->{groups}->{$group}}) 
            };
            if (my $comment = $cluster_conf->{group_comments}->{$group}) {
@@ -72,6 +76,7 @@ __PACKAGE__->register_method({
                description => "Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.",
                optional => 1,
            }),
+           digest => get_standard_option('pve-config-digest'),
        },
     },
     returns => { type => 'null' },
@@ -80,6 +85,10 @@ __PACKAGE__->register_method({
 
        my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
 
+       my $digest = $cluster_conf->{digest};
+
+       PVE::Tools::assert_if_modified($digest, $param->{digest});
+
        foreach my $name (keys %{$cluster_conf->{groups}}) {
            raise_param_exc({ name => "Security group '$name' already exists" }) 
                if !$param->{rename} && $name eq $param->{name};
@@ -114,6 +123,7 @@ __PACKAGE__->register_method({
        additionalProperties => 0,
        properties => { 
            name => get_standard_option('pve-security-group-name'),
+           digest => get_standard_option('pve-config-digest'),
        }
     },
     returns => { type => 'null' },
@@ -122,6 +132,8 @@ __PACKAGE__->register_method({
            
        my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
 
+       PVE::Tools::assert_if_modified($cluster_conf->{digest}, $param->{digest});
+
        return undef if !$cluster_conf->{groups}->{$param->{name}};
 
        die "Security group '$param->{name}' is not empty\n" 
index aa3555a..99afc57 100644 (file)
@@ -56,14 +56,6 @@ PVE::JSONSchema::register_standard_option('ipset-name', {
     maxLength => 20,                     
 });
 
-PVE::JSONSchema::register_standard_option('pve-config-digest', {
-    description => "This digest/signature can be used to prevent updates when the original configuration was changed by somebody else.",
-    type => 'string',
-    optional => 1,
-    maxLength => 27,
-    minLength => 27,                                     
-});
-
 my $security_group_pattern = '[A-Za-z][A-Za-z0-9\-\_]+';
 
 PVE::JSONSchema::register_standard_option('pve-security-group-name', {