From: Dietmar Maurer Date: Tue, 18 Mar 2014 11:06:53 +0000 (+0100) Subject: start VM firewall API X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=commitdiff_plain;h=e7b3571121372860f43ab905757c1b7e78bad19d;hp=8b27beb907eff6f132d6830739328781dcfb36cb start VM firewall API --- diff --git a/src/PVE/API2/Firewall/Makefile b/src/PVE/API2/Firewall/Makefile index 062f31f..78fe63e 100644 --- a/src/PVE/API2/Firewall/Makefile +++ b/src/PVE/API2/Firewall/Makefile @@ -1,5 +1,6 @@ LIB_SOURCES= \ Host.pm \ + VM.pm \ Groups.pm all: diff --git a/src/PVE/API2/Firewall/VM.pm b/src/PVE/API2/Firewall/VM.pm new file mode 100644 index 0000000..2ed73d5 --- /dev/null +++ b/src/PVE/API2/Firewall/VM.pm @@ -0,0 +1,129 @@ +package PVE::API2::Firewall::VM; + +use strict; +use warnings; +use PVE::JSONSchema qw(get_standard_option); +use PVE::Cluster; +use PVE::Firewall; + +use Data::Dumper; # fixme: remove + +use base qw(PVE::RESTHandler); + +__PACKAGE__->register_method({ + name => 'index', + path => '', + method => 'GET', + permissions => { user => 'all' }, + description => "Directory index.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + }, + }, + returns => { + type => 'array', + items => { + type => "object", + properties => {}, + }, + links => [ { rel => 'child', href => "{name}" } ], + }, + code => sub { + my ($param) = @_; + + my $result = [ + { name => 'rules' }, + { name => 'options' }, + ]; + + return $result; + }}); + +__PACKAGE__->register_method({ + name => 'get_rules', + path => 'rules', + method => 'GET', + description => "List VM firewall rules.", + proxyto => 'node', + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + }, + }, + returns => { + type => 'array', + items => { + type => "object", + properties => {}, + }, + }, + code => sub { + my ($param) = @_; + + my $vmid = $param->{vmid}; + + my $vmlist = PVE::Cluster::get_vmlist(); + + die "no such VM ('$vmid')\n" + if !($vmlist && $vmlist->{ids} && defined($vmlist->{ids}->{$vmid})); + + my $vmfw_conf = PVE::Firewall::load_vmfw_conf($vmid); + + my $rules = $vmfw_conf->{rules} || []; + + my $digest = $vmfw_conf->{digest}; + + my $res = []; + + my $ind = 0; + foreach my $rule (@$rules) { + push @$res, PVE::Firewall::cleanup_fw_rule($rule, $digest, $ind++); + } + + return $res; + }}); + +__PACKAGE__->register_method({ + name => 'get_options', + path => 'options', + method => 'GET', + description => "Get host firewall options.", + proxyto => 'node', + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + }, + }, + returns => { + type => "object", + properties => {}, + }, + code => sub { + my ($param) = @_; + + my $vmid = $param->{vmid}; + + my $vmlist = PVE::Cluster::get_vmlist(); + + die "no such VM ('$vmid')\n" + if !($vmlist && $vmlist->{ids} && defined($vmlist->{ids}->{$vmid})); + + my $vmfw_conf = PVE::Firewall::load_vmfw_conf($vmid); + + my $options = $vmfw_conf->{options} || {}; + + my $digest = $vmfw_conf->{digest}; + + $options->{digest} = $digest; + + return $options; + }}); + +1; diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm index 3c8d687..4406824 100644 --- a/src/PVE/Firewall.pm +++ b/src/PVE/Firewall.pm @@ -1400,7 +1400,11 @@ sub parse_vm_fw_rules { my $section; + my $digest = Digest::SHA->new('sha1'); + while (defined(my $line = <$fh>)) { + $digest->add($line); + next if $line =~ m/^#/; next if $line =~ m/^\s*$/; @@ -1438,6 +1442,8 @@ sub parse_vm_fw_rules { push @{$res->{$section}}, @$rules; } + $res->{digest} = $digest->b64digest; + return $res; } @@ -1587,16 +1593,27 @@ sub read_local_vm_config { return $vmdata; }; +sub load_vmfw_conf { + my ($vmid) = @_; + + my $vmfw_conf = {}; + + my $filename = "/etc/pve/firewall/$vmid.fw"; + if (my $fh = IO::File->new($filename, O_RDONLY)) { + $vmfw_conf = parse_vm_fw_rules($filename, $fh); + } + + return $vmfw_conf; +} + sub read_vm_firewall_configs { my ($vmdata) = @_; my $vmfw_configs = {}; foreach my $vmid (keys %{$vmdata->{qemu}}, keys %{$vmdata->{openvz}}) { - my $filename = "/etc/pve/firewall/$vmid.fw"; - my $fh = IO::File->new($filename, O_RDONLY); - next if !$fh; - - $vmfw_configs->{$vmid} = parse_vm_fw_rules($filename, $fh); + my $vmfw_conf = load_vmfw_conf($vmid); + next if !$vmfw_conf->{options}; # skip if file does not exists + $vmfw_configs->{$vmid} = $vmfw_conf; } return $vmfw_configs;