]>
git.proxmox.com Git - pve-firewall.git/blob - src/PVE/API2/Firewall/Groups.pm
1 package PVE
:: API2
:: Firewall
:: Groups
;
5 use PVE
:: JSONSchema
qw(get_standard_option) ;
6 use PVE
:: Exception
qw(raise raise_param_exc) ;
9 use PVE
:: API2
:: Firewall
:: Rules
;
12 use base
qw(PVE::RESTHandler) ;
14 my $get_security_group_list = sub {
15 my ( $cluster_conf ) = @_ ;
18 foreach my $group ( sort keys %{ $cluster_conf ->{ groups
}}) {
22 if ( my $comment = $cluster_conf ->{ group_comments
}->{ $group }) {
23 $data ->{ comment
} = $comment ;
28 my ( $list, $digest ) = PVE
:: Firewall
:: copy_list_with_digest
( $res );
30 return wantarray ?
( $list, $digest ) : $list ;
33 my $rename_fw_rules = sub {
34 my ( $old, $new, $rules ) = @_ ;
36 for my $rule (@{ $rules }) {
37 next if ( $rule ->{ type
} ne "group" || $rule ->{ action
} ne $old );
38 $rule ->{ action
} = $new ;
42 __PACKAGE__-
> register_method ({
43 name
=> 'list_security_groups' ,
46 description
=> "List security groups." ,
47 permissions
=> { user
=> 'all' },
49 additionalProperties
=> 0 ,
57 group
=> get_standard_option
( 'pve-security-group-name' ),
58 digest
=> get_standard_option
( 'pve-config-digest' , { optional
=> 0 } ),
65 links
=> [ { rel
=> 'child' , href
=> "{group}" } ],
70 my $cluster_conf = PVE
:: Firewall
:: load_clusterfw_conf
();
72 return & $get_security_group_list ( $cluster_conf );
75 __PACKAGE__-
> register_method ({
76 name
=> 'create_security_group' ,
79 description
=> "Create new security group." ,
82 check
=> [ 'perm' , '/' , [ 'Sys.Modify' ]],
85 additionalProperties
=> 0 ,
87 group
=> get_standard_option
( 'pve-security-group-name' ),
92 rename => get_standard_option
( 'pve-security-group-name' , {
93 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." ,
96 digest
=> get_standard_option
( 'pve-config-digest' ),
99 returns
=> { type
=> 'null' },
103 my $group = $param ->{ group
};
104 my $rename = $param ->{ rename };
105 my $comment = $param ->{ comment
};
107 PVE
:: Firewall
:: lock_clusterfw_conf
( 10 , sub {
108 my $cluster_conf = PVE
:: Firewall
:: load_clusterfw_conf
();
111 my ( undef , $digest ) = & $get_security_group_list ( $cluster_conf );
112 PVE
:: Tools
:: assert_if_modified
( $digest, $param ->{ digest
});
114 raise_param_exc
({ group
=> "Security group ' $rename ' does not exist" })
115 if ! $cluster_conf ->{ groups
}->{ $rename };
117 # prevent overwriting an existing group
118 raise_param_exc
({ group
=> "Security group ' $group ' does already exist" })
119 if $cluster_conf ->{ groups
}->{ $group } &&
122 if ( $rename eq $group ) {
123 $cluster_conf ->{ group_comments
}->{ $rename } = $comment if defined ( $comment );
124 PVE
:: Firewall
:: save_clusterfw_conf
( $cluster_conf );
128 # Create an exact copy of the old security group
129 $cluster_conf ->{ groups
}->{ $group } = $cluster_conf ->{ groups
}->{ $rename };
130 $cluster_conf ->{ group_comments
}->{ $group } = $cluster_conf ->{ group_comments
}->{ $rename };
132 # Update comment if provided
133 $cluster_conf ->{ group_comments
}->{ $group } = $comment if defined ( $comment );
135 # Write the copy to the cluster config, so that if something fails inbetween, the new firewall
136 # rules won't be broken when the new name is referenced
137 PVE
:: Firewall
:: save_clusterfw_conf
( $cluster_conf );
139 # Update all the host configs to the new copy
140 my $hosts = PVE
:: Cluster
:: get_nodelist
();
141 foreach my $host ( @$hosts ) {
142 PVE
:: Firewall
:: lock_hostfw_conf
( $host, 10 , sub {
143 my $host_conf_path = "/etc/pve/nodes/ $host/host .fw" ;
144 my $host_conf = PVE
:: Firewall
:: load_hostfw_conf
( $cluster_conf, $host_conf_path );
146 if ( defined ( $host_conf )) {
147 & $rename_fw_rules ( $rename,
149 $host_conf ->{ rules
});
150 PVE
:: Firewall
:: save_hostfw_conf
( $host_conf, $host_conf_path );
155 # Update all the VM configs
156 my $vms = PVE
:: Cluster
:: get_vmlist
();
157 foreach my $vm ( keys %{ $vms ->{ ids
}}) {
158 PVE
:: Firewall
:: lock_vmfw_conf
( $vm, 10 , sub {
159 my $vm_type = $vms ->{ ids
}->{ $vm }->{ type
} eq "lxc" ?
"ct" : "vm" ;
160 my $vm_conf = PVE
:: Firewall
:: load_vmfw_conf
( $cluster_conf, $vm_type, $vm, "/etc/pve/firewall" );
162 if ( defined ( $vm_conf )) {
163 & $rename_fw_rules ( $rename,
166 PVE
:: Firewall
:: save_vmfw_conf
( $vm, $vm_conf );
171 # And also update the cluster itself
172 & $rename_fw_rules ( $rename,
174 $cluster_conf ->{ rules
});
176 # Now that everything has been updated, the old rule can be deleted
177 delete $cluster_conf ->{ groups
}->{ $rename };
178 delete $cluster_conf ->{ group_comments
}->{ $rename };
180 foreach my $name ( keys %{ $cluster_conf ->{ groups
}}) {
181 raise_param_exc
({ group
=> "Security group ' $name ' already exists" })
185 $cluster_conf ->{ groups
}->{ $group } = [];
186 $cluster_conf ->{ group_comments
}->{ $group } = $comment if defined ( $comment );
189 PVE
:: Firewall
:: save_clusterfw_conf
( $cluster_conf );
195 __PACKAGE__-
> register_method ({
196 subclass
=> "PVE::API2::Firewall::GroupRules" ,